konst/cmp/cmp_wrapper.rs
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
use crate::cmp::{ConstCmp, IsAConstCmp, IsNotStdKind, IsStdKind};
/// A wrapper type for std types, which defines `const_eq` and `const_cmp` methods for them.
///
/// This is what [`coerce_to_cmp`](crate::coerce_to_cmp)
/// and the comparison macros convert standard library types into.
///
/// # Example
///
/// ```rust
/// use konst::{
/// cmp::CmpWrapper,
/// coerce_to_cmp,
/// };
///
/// use std::cmp::Ordering;
///
/// {
/// // The `CmpWrapper<u32>` type annotation is just for the reader
/// let foo: CmpWrapper<u32> = coerce_to_cmp!(10u32);
/// assert!( foo.const_eq(&10));
/// assert!(!foo.const_eq(&20));
///
/// assert_eq!(foo.const_cmp(&5), Ordering::Greater);
/// assert_eq!(foo.const_cmp(&10), Ordering::Equal);
/// assert_eq!(foo.const_cmp(&15), Ordering::Less);
/// }
/// {
/// let bar = CmpWrapper(Ordering::Equal);
/// assert!( bar.const_eq(&Ordering::Equal));
/// assert!(!bar.const_eq(&Ordering::Less));
///
/// assert_eq!(bar.const_cmp(&Ordering::Less), Ordering::Greater);
/// assert_eq!(bar.const_cmp(&Ordering::Equal), Ordering::Equal);
/// assert_eq!(bar.const_cmp(&Ordering::Greater), Ordering::Less);
/// }
///
/// ```
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct CmpWrapper<T>(pub T);
impl<'a, T> CmpWrapper<&'a [T]> {
/// For constructing from a reference to an array.
///
/// With slices you can do `CmpWrapper(slice)` as well.
#[inline(always)]
pub const fn slice(x: &'a [T]) -> Self {
Self { 0: x }
}
}
impl<P> ConstCmp for CmpWrapper<P> {
type Kind = IsNotStdKind;
}
macro_rules! std_kind_impls {
($($ty:ty),* $(,)* ) => (
$(
impl ConstCmp for $ty {
type Kind = IsStdKind;
}
impl<T> IsAConstCmp<IsStdKind, $ty, T> {
/// Copies the value from `reference`, and wraps it in a `CmpWrapper`
#[inline(always)]
pub const fn coerce(self, reference: &$ty) -> CmpWrapper<$ty> {
CmpWrapper(*reference)
}
}
impl CmpWrapper<$ty> {
/// Compares `self` and `other` for equality.
#[inline(always)]
pub const fn const_eq(self, other: &$ty) -> bool {
self.0 == *other
}
}
)*
)
}
std_kind_impls! {
i8, u8,
i16, u16,
i32, u32,
i64, u64,
i128, u128,
isize, usize,
bool, char,
}