macro_rules! impl_cmp { ( $($rem:tt)* ) => { ... }; ( $($rem:tt)* ) => { ... }; }
Expand description
For implementing const comparison semi-manually.
§Impls
This macro implements ConstCmp
for all the impl
d types,
and outputs the methods/associated constants in each of the listed impls.
§Example
§Generic type
This demonstrates how you can implement equality and ordering comparison for a generic struct.
use konst::{const_cmp, const_eq, impl_cmp, try_equal};
use std::{
cmp::Ordering,
marker::PhantomData,
};
pub struct Tupled<T>(u32, T);
impl_cmp!{
impl[T] Tupled<PhantomData<T>>
where[ T: 'static ];
impl[] Tupled<bool>;
impl Tupled<Option<bool>>;
pub const fn const_eq(&self, other: &Self) -> bool {
const_eq!(self.0, other.0) &&
const_eq!(self.1, other.1)
}
pub const fn const_cmp(&self, other: &Self) -> Ordering {
try_equal!(const_cmp!(self.0, other.0));
try_equal!(const_cmp!(self.1, other.1))
}
}
const _: () = {
let foo = Tupled(3, PhantomData::<u32>);
let bar = Tupled(5, PhantomData::<u32>);
assert!(matches!(const_cmp!(foo, foo), Ordering::Equal));
assert!( const_eq!(foo, foo));
assert!(matches!(const_cmp!(foo, bar), Ordering::Less));
assert!(!const_eq!(foo, bar));
assert!(matches!(const_cmp!(bar, foo), Ordering::Greater));
assert!(!const_eq!(bar, foo));
assert!(matches!(const_cmp!(bar, bar), Ordering::Equal));
assert!( const_eq!(bar, bar));
};
§Enum
This demonstrates how you can implement equality and ordering comparison for an enum.
use konst::{const_cmp, const_eq, impl_cmp, try_equal};
use std::cmp::Ordering;
pub enum Enum {
Tupled(u32, u32),
Unit,
}
impl_cmp!{
impl Enum;
pub const fn const_eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Tupled(l0,l1), Self::Tupled(r0, r1)) => *l0 == *r0 && *l1 == *r1,
(Self::Unit, Self::Unit) => true,
_ => false,
}
}
pub const fn const_cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Self::Tupled(l0,l1), Self::Tupled(r0, r1)) => {
try_equal!(const_cmp!(*l0, *r0));
try_equal!(const_cmp!(*l1, *r1))
}
(Self::Tupled{..}, Self::Unit) => Ordering::Less,
(Self::Unit, Self::Unit) => Ordering::Equal,
(Self::Unit, Self::Tupled{..}) => Ordering::Greater,
}
}
}
const _: () = {
let foo = Enum::Tupled(3, 5);
let bar = Enum::Unit;
assert!(matches!(const_cmp!(foo, foo), Ordering::Equal));
assert!( const_eq!(foo, foo));
assert!(matches!(const_cmp!(foo, bar), Ordering::Less));
assert!(!const_eq!(foo, bar));
assert!(matches!(const_cmp!(bar, foo), Ordering::Greater));
assert!(!const_eq!(bar, foo));
assert!(matches!(const_cmp!(bar, bar), Ordering::Equal));
assert!( const_eq!(bar, bar));
};