From 2f192f1c6c96ad440e1d85180f9da762b16bd976 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Sun, 17 Nov 2024 19:45:56 +0800 Subject: [PATCH] more sort, format readme --- README.md | 495 +++++++++++++++++++++++---------------- tuples/src/sort.rs | 287 +++++++++++++++++------ tuples/src/tuple_iter.rs | 12 +- 3 files changed, 513 insertions(+), 281 deletions(-) diff --git a/README.md b/README.md index 67052ea..1260fcf 100644 --- a/README.md +++ b/README.md @@ -38,241 +38,338 @@ Provides many useful tools related to tuples ## Examples - map - ```rust - let a = (1, 2, 3); - let b = a.map(|v| v * 3); - assert_eq!(b, (3, 6, 9)); - ``` + + ```rust + let a = (1, 2, 3); + let b = a.map(|v| v * 3); + assert_eq!(b, (3, 6, 9)); + ``` + - mapN - ```rust - let a = (1, 2, 3, 4, 5); - let b = a.map3(|v| v * 5); - assert_eq!(b, (1, 2, 3, 20, 5)); - ``` + + ```rust + let a = (1, 2, 3, 4, 5); + let b = a.map3(|v| v * 5); + assert_eq!(b, (1, 2, 3, 20, 5)); + ``` + - map_all - ```rust - let a = (1, 2, 3); - let b = a.map_all(|v| v * 10, |v| v * 100, |v| v * 1000); - assert_eq!(b, (10, 200, 3000)); - ``` + + ```rust + let a = (1, 2, 3); + let b = a.map_all(|v| v * 10, |v| v * 100, |v| v * 1000); + assert_eq!(b, (10, 200, 3000)); + ``` + - as_ref - ```rust - let t = (5, 6, 7); - let (a, b, c) = t.as_ref(); - assert_eq!(*a, 5); - assert_eq!(*b, 6); - assert_eq!(*c, 7); - ``` + + ```rust + let t = (5, 6, 7); + let (a, b, c) = t.as_ref(); + assert_eq!(*a, 5); + assert_eq!(*b, 6); + assert_eq!(*c, 7); + ``` + - cloned - ```rust - let a = (&1, &2, &3); - let b = a.cloned(); - assert_eq!(b, (1, 2, 3)) - ``` + + ```rust + let a = (&1, &2, &3); + let b = a.cloned(); + assert_eq!(b, (1, 2, 3)) + ``` + - flatten - ```rust - let a = ((1, 2, 3), (4, 5, 6), (7, 8, 9)); - let b = a.flatten(); - assert_eq!(b, (1, 2, 3, 4, 5, 6, 7, 8, 9)); - ``` + + ```rust + let a = ((1, 2, 3), (4, 5, 6), (7, 8, 9)); + let b = a.flatten(); + assert_eq!(b, (1, 2, 3, 4, 5, 6, 7, 8, 9)); + ``` + - meta - ```rust - let a = (1, 2, 3, 4, 5); - assert_eq!(a.arity(), 5); - let b = (); - assert_eq!(b.arity(), 0); - ``` + ```rust + let a = (1, 2, 3, 4, 5); + assert_eq!(a.arity(), 5); + + let b = (); + assert_eq!(b.arity(), 0); + ``` + - get - ```rust - let a = (1, 2, 3, 4, 5); - assert_eq!(*a.get(2), 3); - let mut a = (1, 2, 3, 4, 5); - *a.get_mut(3) = 6; - ``` + ```rust + let a = (1, 2, 3, 4, 5); + assert_eq!(*a.get(2), 3); + + let mut a = (1, 2, 3, 4, 5); + *a.get_mut(3) = 6; + ``` + - iter - ```rust - let a = (1, 2, 3) - .into_iter() - .map(|v| v * 3) - .collect_tuple::(); - let b: (i32, i32, i32) = (3, 6, 9); - assert_eq!(a, b); - ``` - ```rust - let a = (1, 2, 3) - .into_iter() - .map(|v| v * 3) - .try_collect_tuple::(); - let b: Option<(i32, i32, i32)> = Some((3, 6, 9)); - assert_eq!(a, b); - ``` - ```rust - let a = (1, 2, 3) - .into_iter() - .map(|v| v * 3) - .collect_tuple_try::(); - let b: (Option, Option, Option) = (Some(3), Some(6), Some(9)); - assert_eq!(a, b); - ``` + + ```rust + let a = (1, 2, 3) + .into_iter() + .map(|v| v * 3) + .collect_tuple::(); + let b: (i32, i32, i32) = (3, 6, 9); + assert_eq!(a, b); + ``` + + ```rust + let a = (1, 2, 3) + .into_iter() + .map(|v| v * 3) + .try_collect_tuple::(); + let b: Option<(i32, i32, i32)> = Some((3, 6, 9)); + assert_eq!(a, b); + ``` + + ```rust + let a = (1, 2, 3) + .into_iter() + .map(|v| v * 3) + .collect_tuple_try::(); + let b: (Option, Option, Option) = (Some(3), Some(6), Some(9)); + assert_eq!(a, b); + ``` + - transpose + + ```rust + let a = Some((1, 2, 3)).transpose(); + assert_eq!(a, (Some(1), Some(2), Some(3))); + + let b = (Some(1), Some(2), Some(3)).transpose(); + assert_eq!(b, Some((1, 2, 3))); + ``` + + ```rust + let a: (Result, Result, Result) = (Ok(1), Ok(2), Ok(3)); + let b: Result<(u8, u8, u8), ()> = a.transpose(); + assert_eq!(b, Ok((1, 2, 3))); + ``` + + ```rust + let a: (Result, Result, Result) = (Ok(1), Err(-1), Ok(3)); + let b: Result<(u8, u8, u8), i64> = a.transpose(); + assert_eq!(b, Err(-1)); + ``` + + ```rust + let a: (Result, Result, Result) = (Ok(1), Err(-1), Ok(3)); + let b = a.transpose1::(); + assert_eq!(b, Err(-1)); + ``` + +- combin + + ```rust + let a = (1, 2).push_right(3); + assert_eq!(a, (1, 2, 3)); + + let b = (2, 1).push_left(3); + assert_eq!(b, (3, 2, 1)); + + let c = (1, 2, 3).concat((4, 5, 6)); + assert_eq!(c, (1, 2, 3, 4, 5, 6)) + ``` + +- split + + - split_parts + ```rust - let a = Some((1, 2, 3)).transpose(); - assert_eq!(a, (Some(1), Some(2), Some(3))); + let t = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + + let a = t.split_2_parts(); + assert_eq!(a, ((0, 1, 2, 3, 4), (5, 6, 7, 8, 9))); + + let b = t.split_3_parts(); + assert_eq!(b, ((0, 1, 2, 3), (4, 5, 6), (7, 8, 9))); + + let c = t.split_4_parts(); + assert_eq!(c, ((0, 1, 2), (3, 4, 5), (6, 7), (8, 9))); - let b = (Some(1), Some(2), Some(3)).transpose(); - assert_eq!(b, Some((1, 2, 3))); + let d = t.split_5_parts(); + assert_eq!(d, ((0, 1), (2, 3), (4, 5), (6, 7), (8, 9))); ``` + + - split_at + ```rust - let a: (Result, Result, Result) = (Ok(1), Ok(2), Ok(3)); - let b: Result<(u8, u8, u8), ()> = a.transpose(); - assert_eq!(b, Ok((1, 2, 3))); + let t = (1, 2, 3, 4, 5, 6); + + let a = t.split_at_1(); + assert_eq!(a, (1, (2, 3, 4, 5, 6))); + + let b = t.split_at_3(); + assert_eq!(b, ((1, 2, 3), (4, 5, 6))); + + let c = t.split_at_5(); + assert_eq!(c, ((1, 2, 3, 4, 5), 6)); ``` + + - split_by + ```rust - let a: (Result, Result, Result) = (Ok(1), Err(-1), Ok(3)); - let b: Result<(u8, u8, u8), i64> = a.transpose(); - assert_eq!(b, Err(-1)); + let t = (1, 2, 3, 4, 5, 6); + let t2 = (1, 2, 3, 4, 5); + + let a = t.split_by_2(); + assert_eq!(a, ((1, 2), (3, 4), (5, 6))); + + let b = t2.split_by_2(); + assert_eq!(b, ((1, 2), (3, 4), 5)); + + let c = t.split_by_3(); + assert_eq!(c, ((1, 2, 3), (4, 5, 6))); + + let d = t2.split_by_3(); + assert_eq!(d, ((1, 2, 3), (4, 5))); + + let e = t.split_by_6(); + assert_eq!(e, ((1, 2, 3, 4, 5, 6))); ``` + + - split_to_tuple_at + ```rust - let a: (Result, Result, Result) = (Ok(1), Err(-1), Ok(3)); - let b = a.transpose1::(); - assert_eq!(b, Err(-1)); + let t = (1, 2, 3, 4, 5, 6); + + let a = t.split_to_tuple_at_1(); + assert_eq!(a, ((1,), (2, 3, 4, 5, 6))); + + let b = t.split_to_tuple_at_3(); + assert_eq!(b, ((1, 2, 3), (4, 5, 6))); + + let c = t.split_to_tuple_at_5(); + assert_eq!(c, ((1, 2, 3, 4, 5), (6,))); ``` -- combin + + - split_to_tuple_by + ```rust - let a = (1, 2).push_right(3); - assert_eq!(a, (1, 2, 3)); + let t = (1, 2, 3, 4, 5, 6); + let t2 = (1, 2, 3, 4, 5); + + let a = t.split_to_tuple_by_2(); + assert_eq!(a, ((1, 2), (3, 4), (5, 6))); - let b = (2, 1).push_left(3); - assert_eq!(b, (3, 2, 1)); + let b = t2.split_to_tuple_by_2(); + assert_eq!(b, ((1, 2), (3, 4), (5,))); - let c = (1, 2, 3).concat((4, 5, 6)); - assert_eq!(c, (1, 2, 3, 4, 5, 6)) + let c = t.split_to_tuple_by_3(); + assert_eq!(c, ((1, 2, 3), (4, 5, 6))); + + let d = t2.split_to_tuple_by_3(); + assert_eq!(d, ((1, 2, 3), (4, 5))); + + let e = t.split_to_tuple_by_6(); + assert_eq!(e, (((1, 2, 3, 4, 5, 6),))); ``` -- split - - split_parts - ```rust - let t = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - - let a = t.split_2_parts(); - assert_eq!(a, ((0, 1, 2, 3, 4), (5, 6, 7, 8, 9))); - - let b = t.split_3_parts(); - assert_eq!(b, ((0, 1, 2, 3), (4, 5, 6), (7, 8, 9))); - - let c = t.split_4_parts(); - assert_eq!(c, ((0, 1, 2), (3, 4, 5), (6, 7), (8, 9))); - - let d = t.split_5_parts(); - assert_eq!(d, ((0, 1), (2, 3), (4, 5), (6, 7), (8, 9))); - ``` - - split_at - ```rust - let t = (1, 2, 3, 4, 5, 6); - - let a = t.split_at_1(); - assert_eq!(a, (1, (2, 3, 4, 5, 6))); - - let b = t.split_at_3(); - assert_eq!(b, ((1, 2, 3), (4, 5, 6))); - - let c = t.split_at_5(); - assert_eq!(c, ((1, 2, 3, 4, 5), 6)); - ``` - - split_by - ```rust - let t = (1, 2, 3, 4, 5, 6); - let t2 = (1, 2, 3, 4, 5); - - let a = t.split_by_2(); - assert_eq!(a, ((1, 2), (3, 4), (5, 6))); - - let b = t2.split_by_2(); - assert_eq!(b, ((1, 2), (3, 4), 5)); - - let c = t.split_by_3(); - assert_eq!(c, ((1, 2, 3), (4, 5, 6))); - - let d = t2.split_by_3(); - assert_eq!(d, ((1, 2, 3), (4, 5))); - - let e = t.split_by_6(); - assert_eq!(e, ((1, 2, 3, 4, 5, 6))); - ``` - - split_to_tuple_at - ```rust - let t = (1, 2, 3, 4, 5, 6); - - let a = t.split_to_tuple_at_1(); - assert_eq!(a, ((1,), (2, 3, 4, 5, 6))); - - let b = t.split_to_tuple_at_3(); - assert_eq!(b, ((1, 2, 3), (4, 5, 6))); - - let c = t.split_to_tuple_at_5(); - assert_eq!(c, ((1, 2, 3, 4, 5), (6,))); - ``` - - split_to_tuple_by - ```rust - let t = (1, 2, 3, 4, 5, 6); - let t2 = (1, 2, 3, 4, 5); - - let a = t.split_to_tuple_by_2(); - assert_eq!(a, ((1, 2), (3, 4), (5, 6))); - - let b = t2.split_to_tuple_by_2(); - assert_eq!(b, ((1, 2), (3, 4), (5,))); - - let c = t.split_to_tuple_by_3(); - assert_eq!(c, ((1, 2, 3), (4, 5, 6))); - - let d = t2.split_to_tuple_by_3(); - assert_eq!(d, ((1, 2, 3), (4, 5))); - - let e = t.split_to_tuple_by_6(); - assert_eq!(e, (((1, 2, 3, 4, 5, 6),))); - ``` + - call + + ```rust + let r = (1, 2, 3).call(|a, b, c| a + b + c); + assert_eq!(r, 6); + ``` + +- apply + + ```rust + let a = (1, 2, 3); + fn foo(a: i32, b: i32, c: i32) -> i32 { + a + b + c + } + let r = foo.apply_tuple(a); + assert_eq!(r, 6) + ``` + +- swap + + ```rust + let mut a = (1, 2, 3, 4, 5); + a.swap(1, 3); + assert_eq!(a, (1, 4, 3, 2, 5)); + ``` + +- swap_n + + **Not enabled by default** + + ```toml + features = ["tuple_swap_n"] + ``` + + ```rust + let mut a = (1, 2, 3, 4, 5); + a.swap_1_3(); + assert_eq!(a, (1, 4, 3, 2, 5)); + ``` + +- sort + + Currently implemented sorting algorithm + + - selection sort (default alias) + + *** + + - sort + ```rust - let r = (1, 2, 3).call(|a, b, c| a + b + c); - assert_eq!(r, 6); + let mut a = (6, 2, 6, 8, 0, 5); + a.sort(); + assert_eq!(a, (0, 2, 5, 6, 6, 8)) ``` -- apply + + - sort_desc + ```rust - let a = (1, 2, 3); - fn foo(a: i32, b: i32, c: i32) -> i32 { - a + b + c - } - let r = foo.apply_tuple(a); - assert_eq!(r, 6) + let mut a = (6, 2, 6, 8, 0, 5); + a.sort_desc(); + assert_eq!(a, (8, 6, 6, 5, 2, 0)) ``` -- swap + + - sort_by + ```rust - let mut a = (1, 2, 3, 4, 5); - a.swap(1, 3); - assert_eq!(a, (1, 4, 3, 2, 5)); + let mut a = (6, 2, 6, 8, 0, 5); + a.sort_by(|a, b| + if a > b { core::cmp::Ordering::Less } + else { core::cmp::Ordering::Greater } + ); + assert_eq!(a, (0, 2, 5, 6, 6, 8)) ``` -- swap_n - **Not enabled by default** + - sort_by_key - ```toml - features = ["tuple_swap_n"] + ```rust + let mut a = ((6, 2), (6, 8), (0, 5)); + a.sort_by_key(|a| a.1); + assert_eq!(a, ((6, 2), (0, 5), (6, 8))) ``` + - sort_by_key_desc + ```rust - let mut a = (1, 2, 3, 4, 5); - a.swap_1_3(); - assert_eq!(a, (1, 4, 3, 2, 5)); + let mut a = ((6, 2), (6, 8), (0, 5)); + a.sort_by_key_desc(|a| a.1); + assert_eq!(a, ((6, 8), (0, 5), (6, 2))) ``` -- sort - currently implemented - - selection sort + *** + + - sorted / sorted_xx - ```rust - let mut a = (6, 2, 6, 8, 0, 5); - a.sort_selection(); - assert_eq!(a, (0, 2, 5, 6, 6, 8)) - ``` + Variants of Transferring Ownership + + ```rust + let a = (6, 2, 6, 8, 0, 5); + let a = a.sorted(); + assert_eq!(a, (0, 2, 5, 6, 6, 8)) + ``` diff --git a/tuples/src/sort.rs b/tuples/src/sort.rs index c437569..5e90bea 100644 --- a/tuples/src/sort.rs +++ b/tuples/src/sort.rs @@ -1,13 +1,17 @@ //! Sort tuples -use crate::{TupleSame, TupleSwap}; - /// Sort tuples, currently use sort_selection pub trait TupleSorted { /// Sort tuples, currently use sort_selection fn sorted(self) -> Self; } +/// Sort tuples in reverse order, currently use sort_selection +pub trait TupleSortedDesc { + /// Sort tuples in reverse order, currently use sort_selection + fn sorted_desc(self) -> Self; +} + /// Sort tuples, currently use sort_selection pub trait TupleSortedBy { /// Sort tuples, currently use sort_selection @@ -20,6 +24,12 @@ pub trait TupleSortedByKey { fn sorted_by_key(self, selector: impl FnMut(&T) -> K) -> Self; } +/// Sort tuples in reverse order, currently use sort_selection +pub trait TupleSortedByKeyDesc { + /// Sort tuples in reverse order, currently use sort_selection + fn sorted_by_key_desc(self, selector: impl FnMut(&T) -> K) -> Self; +} + impl> TupleSorted for S { fn sorted(mut self) -> Self { self.sort(); @@ -27,6 +37,13 @@ impl> TupleSorted for S { } } +impl> TupleSortedDesc for S { + fn sorted_desc(mut self) -> Self { + self.sort_desc(); + self + } +} + impl> TupleSortedBy for S { fn sorted_by(mut self, cmp: impl FnMut(&T, &T) -> core::cmp::Ordering) -> Self { self.sort_by(cmp); @@ -41,12 +58,25 @@ impl> TupleSortedByKey for S { } } +impl> TupleSortedByKeyDesc for S { + fn sorted_by_key_desc(mut self, selector: impl FnMut(&T) -> K) -> Self { + self.sort_by_key_desc(selector); + self + } +} + /// Sort tuples, currently an alias for sort_selection pub trait TupleSort { /// Sort tuples, currently an alias for sort_selection fn sort(&mut self); } +/// Sort tuples in reverse order, currently an alias for sort_selection +pub trait TupleSortDesc { + /// Sort tuples in reverse order, currently an alias for sort_selection + fn sort_desc(&mut self); +} + /// Sort tuples, currently an alias for sort_selection pub trait TupleSortBy { /// Sort tuples, currently an alias for sort_selection @@ -59,12 +89,24 @@ pub trait TupleSortByKey { fn sort_by_key(&mut self, selector: impl FnMut(&T) -> K); } +/// Sort tuples in reverse order, currently an alias for sort_selection +pub trait TupleSortByKeyDesc { + /// Sort tuples in reverse order, currently an alias for sort_selection + fn sort_by_key_desc(&mut self, selector: impl FnMut(&T) -> K); +} + impl> TupleSort for S { fn sort(&mut self) { self.sort_selection(); } } +impl> TupleSortDesc for S { + fn sort_desc(&mut self) { + self.sort_desc_selection(); + } +} + impl> TupleSortBy for S { fn sort_by(&mut self, cmp: impl FnMut(&T, &T) -> core::cmp::Ordering) { self.sort_by_selection(cmp); @@ -77,99 +119,150 @@ impl> TupleSortByKey for S { } } -/// Sort tuples using selection sort -pub trait TupleSortSelection { - /// Sort tuples using selection sort - /// - /// It has an `O(n2)` time complexity - fn sort_selection(&mut self); +impl> TupleSortByKeyDesc for S { + fn sort_by_key_desc(&mut self, selector: impl FnMut(&T) -> K) { + self.sort_by_key_desc_selection(selector); + } } -/// Sort tuples using selection sort -pub trait TupleSortBySelection { - /// Sort tuples using selection sort - /// - /// It has an `O(n2)` time complexity - fn sort_by_selection(&mut self, cmp: impl FnMut(&T, &T) -> core::cmp::Ordering); -} +pub use algorithms::selection::*; +/// Sorting algorithms +pub mod algorithms { + /// Selection sort, it has an `O(n2)` time complexity + pub mod selection { + use crate::{TupleSame, TupleSwap}; + + /// Sort tuples using selection sort + pub trait TupleSortSelection { + /// Sort tuples using selection sort + /// + /// It has an `O(n2)` time complexity + fn sort_selection(&mut self); + } -/// Sort tuples using selection sort -pub trait TupleSortByKeySelection { - /// Sort tuples using selection sort - /// - /// It has an `O(n2)` time complexity - fn sort_by_key_selection(&mut self, selector: impl FnMut(&T) -> K); -} + /// Sort tuples in reverse order using selection sort + pub trait TupleSortDescSelection { + /// Sort tuples in reverse order using selection sort + /// + /// It has an `O(n2)` time complexity + fn sort_desc_selection(&mut self); + } -impl + TupleSwap> TupleSortSelection for S { - #[inline] - fn sort_selection(&mut self) { - if sort_base(self, T::lt) { - return; + /// Sort tuples using selection sort + pub trait TupleSortBySelection { + /// Sort tuples using selection sort + /// + /// It has an `O(n2)` time complexity + fn sort_by_selection(&mut self, cmp: impl FnMut(&T, &T) -> core::cmp::Ordering); } - selection_sort(self, T::lt) - } -} -impl + TupleSwap> TupleSortBySelection for S { - #[inline] - fn sort_by_selection(&mut self, mut cmp: impl FnMut(&T, &T) -> core::cmp::Ordering) { - if sort_base(self, |a, b| matches!(cmp(a, b), core::cmp::Ordering::Less)) { - return; + /// Sort tuples using selection sort + pub trait TupleSortByKeySelection { + /// Sort tuples using selection sort + /// + /// It has an `O(n2)` time complexity + fn sort_by_key_selection(&mut self, selector: impl FnMut(&T) -> K); } - selection_sort(self, |a, b| matches!(cmp(a, b), core::cmp::Ordering::Less)) - } -} -impl + TupleSwap> TupleSortByKeySelection for S { - #[inline] - fn sort_by_key_selection(&mut self, mut selector: impl FnMut(&T) -> K) { - if sort_base(self, |a, b| selector(a) < selector(b)) { - return; + /// Sort tuples in reverse order using selection sort + pub trait TupleSortByKeyDescSelection { + /// Sort tuples in reverse order using selection sort + /// + /// It has an `O(n2)` time complexity + fn sort_by_key_desc_selection(&mut self, selector: impl FnMut(&T) -> K); } - selection_sort(self, |a, b| selector(a) < selector(b)) - } -} -fn sort_base + TupleSwap>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) -> bool { - if core::mem::size_of::() == 0 { - return true; - } + impl + TupleSwap> TupleSortSelection for S { + #[inline] + fn sort_selection(&mut self) { + if sort_base(self, T::lt) { + return; + } + selection_sort(self, T::lt) + } + } - let len = v.arity(); - if len <= 1 { - return true; - } - if len == 2 { - let a = v.get(0); - let b = v.get(1); + impl + TupleSwap> TupleSortDescSelection for S { + #[inline] + fn sort_desc_selection(&mut self) { + if sort_base(self, T::gt) { + return; + } + selection_sort(self, T::gt) + } + } - if is_less(a, b) { - return true; - } else if is_less(b, a) { - v.swap(0, 1); - return true; - } else { - return true; + impl + TupleSwap> TupleSortBySelection for S { + #[inline] + fn sort_by_selection(&mut self, mut cmp: impl FnMut(&T, &T) -> core::cmp::Ordering) { + if sort_base(self, |a, b| matches!(cmp(a, b), core::cmp::Ordering::Less)) { + return; + } + selection_sort(self, |a, b| matches!(cmp(a, b), core::cmp::Ordering::Less)) + } } - } - false -} + impl + TupleSwap> TupleSortByKeySelection for S { + #[inline] + fn sort_by_key_selection(&mut self, mut selector: impl FnMut(&T) -> K) { + if sort_base(self, |a, b| selector(a) < selector(b)) { + return; + } + selection_sort(self, |a, b| selector(a) < selector(b)) + } + } -fn selection_sort + TupleSwap>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) { - let len = v.arity(); - for i in 0..(len - 1) { - let mut min_index = i; + impl + TupleSwap> TupleSortByKeyDescSelection for S { + #[inline] + fn sort_by_key_desc_selection(&mut self, mut selector: impl FnMut(&T) -> K) { + if sort_base(self, |a, b| selector(a) > selector(b)) { + return; + } + selection_sort(self, |a, b| selector(a) > selector(b)) + } + } - for j in (i + 1)..len { - if is_less(v.get(j), v.get(min_index)) { - min_index = j; + fn sort_base + TupleSwap>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) -> bool { + if core::mem::size_of::() == 0 { + return true; + } + + let len = v.arity(); + if len <= 1 { + return true; + } + if len == 2 { + let a = v.get(0); + let b = v.get(1); + + if is_less(a, b) { + return true; + } else if is_less(b, a) { + v.swap(0, 1); + return true; + } else { + return true; + } } + + false } - if min_index != i { - v.swap(i, min_index); + fn selection_sort + TupleSwap>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) { + let len = v.arity(); + for i in 0..(len - 1) { + let mut min_index = i; + + for j in (i + 1)..len { + if is_less(v.get(j), v.get(min_index)) { + min_index = j; + } + } + + if min_index != i { + v.swap(i, min_index); + } + } } } } @@ -212,4 +305,46 @@ mod test_selection_sort { a.sort_selection(); assert_eq!(a, (0.125, 0.3, 0.1 + 0.2, 1.5, 3.0, 7.1, 9.9)) } + + #[test] + fn test6() { + let mut a = (6, 2, 6, 8, 0, 5); + a.sort_by(|a, b| if a > b { core::cmp::Ordering::Less } else { core::cmp::Ordering::Greater }); + assert_eq!(a, (8, 6, 6, 5, 2, 0)) + } + + #[test] + fn test7() { + let mut a = ((6, 2), (6, 8), (0, 5)); + a.sort_by_key(|a| a.1); + assert_eq!(a, ((6, 2), (0, 5), (6, 8))) + } + + #[test] + fn test8() { + let mut a = (6, 2, 6, 8, 0, 5); + a.sort_by(|a, b| a.cmp(b)); + assert_eq!(a, (0, 2, 5, 6, 6, 8)) + } + + #[test] + fn test9() { + let a = (6, 2, 6, 8, 0, 5); + let a = a.sorted(); + assert_eq!(a, (0, 2, 5, 6, 6, 8)) + } + + #[test] + fn test10() { + let mut a = (6, 2, 6, 8, 0, 5); + a.sort_desc(); + assert_eq!(a, (8, 6, 6, 5, 2, 0)) + } + + #[test] + fn test11() { + let mut a = ((6, 2), (6, 8), (0, 5)); + a.sort_by_key_desc(|a| a.1); + assert_eq!(a, ((6, 8), (0, 5), (6, 2))) + } } diff --git a/tuples/src/tuple_iter.rs b/tuples/src/tuple_iter.rs index 8552e15..77a13d9 100644 --- a/tuples/src/tuple_iter.rs +++ b/tuples/src/tuple_iter.rs @@ -17,19 +17,19 @@ pub trait TupleIntoIter { } pub trait TupleFromIter { - /// Like `Iter -> (T, T, T)` with panic on failure + /// Such as `Iter -> (T, T, T)`, panic on failure fn from_iter>(iter: I) -> Self; } pub trait TupleTryFromIter: Sized { - /// Like `Iter -> Option<(T, T, T)>` + /// Such as `Iter -> Option<(T, T, T)>` fn try_from_iter>(iter: I) -> Option; } pub trait TupleFromIterTry { type OutTuple; - /// Like `Iter -> (Option, Option, Option)` + /// Such as `Iter -> (Option, Option, Option)` fn from_iter_try>(iter: I) -> Self::OutTuple; } @@ -114,11 +114,11 @@ impl TupleFromIterTry for (T,) { include!("./gen/tuple_iter.rs"); pub trait TupleCollect { - /// Like `Iter -> (T, T, T)` with panic on failure + /// Such as `Iter -> (T, T, T)`, panic on failure fn collect_tuple>(self) -> B; - /// Like `Iter -> Option<(T, T, T)>` + /// Such as `Iter -> Option<(T, T, T)>` fn try_collect_tuple>(self) -> Option; - /// Like `Iter -> (Option, Option, Option)` + /// Such as `Iter -> (Option, Option, Option)` fn collect_tuple_try>(self) -> B::OutTuple; }