diff --git a/crates/slice-dst/src/provided_types.rs b/crates/slice-dst/src/provided_types.rs index 87b87b5..d6d5f89 100644 --- a/crates/slice-dst/src/provided_types.rs +++ b/crates/slice-dst/src/provided_types.rs @@ -1,3 +1,5 @@ +use core::cmp::Ordering; + use super::*; #[repr(C)] @@ -174,6 +176,26 @@ unsafe impl Erasable for SliceWithHeader { const ACK_1_1_0: bool = true; } +impl PartialOrd for SliceWithHeader +where + Header: PartialOrd, + Item: PartialOrd, +{ + fn partial_cmp(&self, other: &Self) -> Option { + (&self.header, &self.slice).partial_cmp(&(&other.header, &other.slice)) + } +} + +impl Ord for SliceWithHeader +where + Header: Ord, + Item: Ord, +{ + fn cmp(&self, other: &Self) -> Ordering { + (&self.header, &self.slice).cmp(&(&other.header, &other.slice)) + } +} + #[repr(C)] #[derive(Debug, Eq, PartialEq, Hash)] /// A custom str-based DST. @@ -246,3 +268,21 @@ unsafe impl
Erasable for StrWithHeader
{ const ACK_1_1_0: bool = true; } + +impl
PartialOrd for StrWithHeader
+where + Header: PartialOrd, +{ + fn partial_cmp(&self, other: &Self) -> Option { + (&self.header, &self.str).partial_cmp(&(&other.header, &other.str)) + } +} + +impl
Ord for StrWithHeader
+where + Header: Ord, +{ + fn cmp(&self, other: &Self) -> Ordering { + (&self.header, &self.str).cmp(&(&other.header, &other.str)) + } +} diff --git a/crates/slice-dst/tests/smoke.rs b/crates/slice-dst/tests/smoke.rs index 71b79b3..df18912 100644 --- a/crates/slice-dst/tests/smoke.rs +++ b/crates/slice-dst/tests/smoke.rs @@ -39,6 +39,131 @@ fn actual_zst() { } } +#[test] +fn str_eq_cmp() { + [ + [("*", "AB"), ("*", "ab")], + [("*", "AB"), ("*", "a")], + [("*", "A"), ("*", "ab")], + [("A", "*"), ("a", "*")], + [("a", "*"), ("A", "*")], + [("AB", "*"), ("a", "*")], + [("A", "*"), ("ab", "*")], + ] + .iter() + .for_each(|[lt @ (lh, ls), rt @ (rh, rs)]| { + let l: Box> = StrWithHeader::new(*lh, ls); + let r: Box> = StrWithHeader::new(*rh, rs); + + assert_eq!(l, l); + assert_eq!(r, r); + + assert_ne!(l, r); + assert_ne!(r, l); + + assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}"); + assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}"); + + assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}"); + assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}"); + + assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}"); + assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}"); + + assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}"); + assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}"); + + assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}"); + assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}"); + }) +} + +#[test] +fn slice_eq_cmp() { + [ + [(0, &[0, 0][..]), (1, &[0, 0][..])], + [(1, &[0, 0][..]), (0, &[0, 0][..])], + [(0, &[0][..]), (0, &[0, 0][..])], + [(0, &[0, 0][..]), (0, &[0][..])], + [(0, &[1, 2][..]), (0, &[10, 20][..])], + ] + .iter() + .for_each(|[lt @ (lh, ls), rt @ (rh, rs)]| { + let l: Box> = SliceWithHeader::from_slice(*lh, ls); + let r: Box> = SliceWithHeader::from_slice(*rh, rs); + + assert_eq!(l, l); + assert_eq!(r, r); + + assert_ne!(l, r); + assert_ne!(r, l); + + assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}"); + assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}"); + + assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}"); + assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}"); + + assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}"); + assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}"); + + assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}"); + assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}"); + + assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}"); + assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}"); + }) +} + +#[test] +fn slice_partial_eq_cmp() { + [ + [(0.0, &[0.0, 0.0][..]), (1.0, &[0.0, 0.0][..])], + [(1.0, &[0.0, 0.0][..]), (0.0, &[0.0, 0.0][..])], + [(0.0, &[0.0][..]), (0.0, &[0.0, 0.0][..])], + [(0.0, &[0.0, 0.0][..]), (0.0, &[0.0][..])], + [(0.0, &[1.0, 2.0][..]), (0.0, &[10.0, 20.0][..])], + ] + .iter() + .for_each(|[lt @ (lh, ls), rt @ (rh, rs)]| { + let l: Box> = SliceWithHeader::from_slice(*lh, ls); + let r: Box> = SliceWithHeader::from_slice(*rh, rs); + + assert_eq!(l, l); + assert_eq!(r, r); + + assert_ne!(l, r); + assert_ne!(r, l); + + assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}"); + assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}"); + + assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}"); + assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}"); + + assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}"); + assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}"); + + assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}"); + assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}"); + + assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}"); + assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}"); + }) +} + +const fn is_partial_ord() {} +const fn is_ord() {} + +// compile-time check that PartialOrd/Ord is correctly derived +const _: () = is_partial_ord::>(); +const _: () = is_partial_ord::>(); +const _: () = is_partial_ord::>(); +const _: () = is_ord::>(); + +const _: () = is_partial_ord::>(); +const _: () = is_ord::>(); + type Data = usize; #[repr(transparent)] #[derive(Debug, Clone)]