1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
use core::ops::{Range, RangeInclusive};

use crate::polymorphism::{CmpWrapper, ConstCmpMarker, IsAConstCmpMarker, IsStdKind};

macro_rules! shared_range_impls {
    ($type:ty, $eq_fn_name:ident) => {
        impl ConstCmpMarker for $type {
            type Kind = IsStdKind;
            type This = Self;
        }
        impl CmpWrapper<$type> {
            #[inline(always)]
            pub const fn const_eq(&self, other: &$type) -> bool {
                $eq_fn_name(&self.0, other)
            }
        }
    };
}

macro_rules! declare_range_cmp_fns {
    (
        ($type:ty, ($eq_fn_name:ident))

        docs( $docs_eq:expr, $docs_cmp:expr,)
    ) => {
        shared_range_impls! {$type, $eq_fn_name}

        impl<T> IsAConstCmpMarker<IsStdKind, $type, T> {
            #[inline(always)]
            pub const fn coerce(self, range: &$type) -> CmpWrapper<$type> {
                CmpWrapper(Range {
                    start: range.start,
                    end: range.end,
                })
            }
        }

        __delegate_const_eq! {
            skip_coerce;
            for['a,]

            #[doc = $docs_eq]
            pub const fn $eq_fn_name(ref left: &'a $type, right: &'a $type) -> bool {
                left.start == right.start && left.end == right.end
            }
        }
    };
}

__declare_fns_with_docs! {
    (Range<u8>,    (eq_range_u8))
    (Range<u16>,   (eq_range_u16))
    (Range<u32>,   (eq_range_u32))
    (Range<u64>,   (eq_range_u64))
    (Range<u128>,  (eq_range_u128))
    (Range<usize>, (eq_range_usize))

    (Range<char>, (eq_range_char))

    docs(default)

    macro = declare_range_cmp_fns!(),
}

macro_rules! declare_rangeinclusive_cmp_fns {
    (
        ($type:ty, ($eq_fn_name:ident))

        docs( $docs_eq:expr, $docs_cmp:expr,)
    ) => {
        shared_range_impls! {$type, $eq_fn_name}

        impl<T> IsAConstCmpMarker<IsStdKind, $type, T> {
            #[inline(always)]
            pub const fn coerce(self, range: &$type) -> CmpWrapper<$type> {
                CmpWrapper(RangeInclusive::new(*range.start(), *range.end()))
            }
        }

        #[doc = $docs_eq]
        pub const fn $eq_fn_name(left: &$type, right: &$type) -> bool {
            *left.start() == *right.start() && *left.end() == *right.end()
        }
    };
}

__declare_fns_with_docs! {
    (RangeInclusive<u8>,    (eq_rangeinc_u8,))
    (RangeInclusive<u16>,   (eq_rangeinc_u16))
    (RangeInclusive<u32>,   (eq_rangeinc_u32))
    (RangeInclusive<u64>,   (eq_rangeinc_u64))
    (RangeInclusive<u128>,  (eq_rangeinc_u128))
    (RangeInclusive<usize>, (eq_rangeinc_usize))

    (RangeInclusive<char>, (eq_rangeinc_char))

    docs(default)

    macro = declare_rangeinclusive_cmp_fns!(),
}