From e81dc7599d213f9bd19663b67c8dc2652e7ac590 Mon Sep 17 00:00:00 2001 From: daddinuz Date: Sun, 21 May 2023 14:20:00 +0200 Subject: [PATCH 1/3] derive PartialOrd + Ord for SliceWithHeader and StrWithHeader --- crates/slice-dst/src/provided_types.rs | 4 +- crates/slice-dst/tests/smoke.rs | 62 ++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/crates/slice-dst/src/provided_types.rs b/crates/slice-dst/src/provided_types.rs index 87b87b5..f54ede7 100644 --- a/crates/slice-dst/src/provided_types.rs +++ b/crates/slice-dst/src/provided_types.rs @@ -1,7 +1,7 @@ use super::*; #[repr(C)] -#[derive(Debug, Eq, PartialEq, Hash)] +#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] /// A custom slice-based DST. /// /// The length is stored as a `usize` at offset 0. @@ -175,7 +175,7 @@ unsafe impl Erasable for SliceWithHeader { } #[repr(C)] -#[derive(Debug, Eq, PartialEq, Hash)] +#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] /// A custom str-based DST. /// /// The length is stored as a `usize` at offset 0. diff --git a/crates/slice-dst/tests/smoke.rs b/crates/slice-dst/tests/smoke.rs index 71b79b3..e395981 100644 --- a/crates/slice-dst/tests/smoke.rs +++ b/crates/slice-dst/tests/smoke.rs @@ -39,6 +39,68 @@ fn actual_zst() { } } +#[test] +fn str_eq_cmp() { + let l: Box> = StrWithHeader::new('*', "AB"); + let r: Box> = StrWithHeader::new('*', "ab"); + + assert_eq!(l, l); + assert_eq!(r, r); + + assert_ne!(l, r); + assert_ne!(r, l); + + assert!(l <= l); + assert!(l >= l); + assert!(!(l < l)); + assert!(!(l > l)); + + assert!(r <= r); + assert!(r >= r); + assert!(!(r < r)); + assert!(!(r > r)); + + assert!(l < r); + assert!(r > l); +} + +#[test] +fn slice_eq_cmp() { + let l: Box> = SliceWithHeader::from_slice(1, &[2, 3]); + let r: Box> = SliceWithHeader::from_slice(10, &[20, 30]); + + assert_eq!(l, l); + assert_eq!(r, r); + + assert_ne!(l, r); + assert_ne!(r, l); + + assert!(l <= l); + assert!(l >= l); + assert!(!(l < l)); + assert!(!(l > l)); + + assert!(r <= r); + assert!(r >= r); + assert!(!(r < r)); + assert!(!(r > r)); + + assert!(l < r); + assert!(r > l); +} + +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)] From 0ae7a8f344c08761a8ea52d1ba712d824718b8a6 Mon Sep 17 00:00:00 2001 From: daddinuz Date: Sun, 21 May 2023 16:39:28 +0200 Subject: [PATCH 2/3] Bugfix semantic of PartialOrd/Ord for SliceWithHeader/StrWithHeader The semantic of PartialOrd/Ord traits for types SliceWithHeader/StrWithHeader is now the same of the tuple `(&Header, &[Item])` --- crates/slice-dst/src/provided_types.rs | 44 +++++++++- crates/slice-dst/tests/smoke.rs | 110 +++++++++++++++---------- 2 files changed, 110 insertions(+), 44 deletions(-) diff --git a/crates/slice-dst/src/provided_types.rs b/crates/slice-dst/src/provided_types.rs index f54ede7..d6d5f89 100644 --- a/crates/slice-dst/src/provided_types.rs +++ b/crates/slice-dst/src/provided_types.rs @@ -1,7 +1,9 @@ +use core::cmp::Ordering; + use super::*; #[repr(C)] -#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] /// A custom slice-based DST. /// /// The length is stored as a `usize` at offset 0. @@ -174,8 +176,28 @@ 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, PartialOrd, Ord, Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] /// A custom str-based DST. /// /// The length is stored as a `usize` at offset 0. @@ -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 e395981..a81ed74 100644 --- a/crates/slice-dst/tests/smoke.rs +++ b/crates/slice-dst/tests/smoke.rs @@ -41,52 +41,78 @@ fn actual_zst() { #[test] fn str_eq_cmp() { - let l: Box> = StrWithHeader::new('*', "AB"); - let r: Box> = StrWithHeader::new('*', "ab"); - - assert_eq!(l, l); - assert_eq!(r, r); - - assert_ne!(l, r); - assert_ne!(r, l); - - assert!(l <= l); - assert!(l >= l); - assert!(!(l < l)); - assert!(!(l > l)); - - assert!(r <= r); - assert!(r >= r); - assert!(!(r < r)); - assert!(!(r > r)); - - assert!(l < r); - assert!(r > l); + [ + [("*", "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); + assert_eq!(l >= l, lt >= lt); + + assert_eq!(l < l, lt < lt); + assert_eq!(l > l, lt > lt); + + assert_eq!(r <= r, rt <= rt); + assert_eq!(r >= r, rt >= rt); + + assert_eq!(r < r, rt < rt); + assert_eq!(r > r, rt > rt); + + assert_eq!(l < r, lt < rt); + assert_eq!(r > l, rt > lt); + }) } #[test] fn slice_eq_cmp() { - let l: Box> = SliceWithHeader::from_slice(1, &[2, 3]); - let r: Box> = SliceWithHeader::from_slice(10, &[20, 30]); - - assert_eq!(l, l); - assert_eq!(r, r); - - assert_ne!(l, r); - assert_ne!(r, l); - - assert!(l <= l); - assert!(l >= l); - assert!(!(l < l)); - assert!(!(l > l)); - - assert!(r <= r); - assert!(r >= r); - assert!(!(r < r)); - assert!(!(r > r)); - - assert!(l < r); - assert!(r > l); + [ + [(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); + assert_eq!(l >= l, lt >= lt); + + assert_eq!(l < l, lt < lt); + assert_eq!(l > l, lt > lt); + + assert_eq!(r <= r, rt <= rt); + assert_eq!(r >= r, rt >= rt); + + assert_eq!(r < r, rt < rt); + assert_eq!(r > r, rt > rt); + + assert_eq!(l < r, lt < rt); + assert_eq!(r > l, rt > lt); + }) } const fn is_partial_ord() {} From 3a90081775c564b63ba7e9832e636e91c4aac3f6 Mon Sep 17 00:00:00 2001 From: daddinuz Date: Sun, 21 May 2023 19:29:34 +0200 Subject: [PATCH 3/3] more tests --- crates/slice-dst/tests/smoke.rs | 77 ++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/crates/slice-dst/tests/smoke.rs b/crates/slice-dst/tests/smoke.rs index a81ed74..df18912 100644 --- a/crates/slice-dst/tests/smoke.rs +++ b/crates/slice-dst/tests/smoke.rs @@ -61,20 +61,20 @@ fn str_eq_cmp() { assert_ne!(l, r); assert_ne!(r, l); - assert_eq!(l <= l, lt <= lt); - assert_eq!(l >= l, lt >= lt); + assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}"); + assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}"); - assert_eq!(l < l, lt < lt); - assert_eq!(l > l, lt > lt); + assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}"); + assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}"); - assert_eq!(r <= r, rt <= rt); - assert_eq!(r >= r, rt >= rt); + assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}"); + assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}"); - assert_eq!(r < r, rt < rt); - assert_eq!(r > r, rt > rt); + assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}"); + assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}"); - assert_eq!(l < r, lt < rt); - assert_eq!(r > l, rt > lt); + assert_eq!(l < r, lt < rt, "{lt:?} < {rt:?}"); + assert_eq!(r > l, rt > lt, "{rt:?} > {lt:?}"); }) } @@ -98,20 +98,57 @@ fn slice_eq_cmp() { assert_ne!(l, r); assert_ne!(r, l); - assert_eq!(l <= l, lt <= lt); - assert_eq!(l >= l, lt >= lt); + assert_eq!(l <= l, lt <= lt, "{lt:?} <= {lt:?}"); + assert_eq!(l >= l, lt >= lt, "{lt:?} >= {lt:?}"); - assert_eq!(l < l, lt < lt); - assert_eq!(l > l, lt > lt); + assert_eq!(l < l, lt < lt, "{lt:?} < {lt:?}"); + assert_eq!(l > l, lt > lt, "{lt:?} > {lt:?}"); - assert_eq!(r <= r, rt <= rt); - assert_eq!(r >= r, rt >= rt); + assert_eq!(r <= r, rt <= rt, "{rt:?} <= {rt:?}"); + assert_eq!(r >= r, rt >= rt, "{rt:?} >= {rt:?}"); - assert_eq!(r < r, rt < rt); - assert_eq!(r > r, rt > rt); + assert_eq!(r < r, rt < rt, "{rt:?} < {rt:?}"); + assert_eq!(r > r, rt > rt, "{rt:?} > {rt:?}"); - assert_eq!(l < r, lt < rt); - assert_eq!(r > l, rt > lt); + 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:?}"); }) }