diff options
| author | Kevin Leimkuhler <kevin@kleimkuhler.com> | 2018-10-11 15:59:54 -0700 |
|---|---|---|
| committer | Kevin Leimkuhler <kevin@kleimkuhler.com> | 2019-01-17 22:34:43 -0800 |
| commit | 02477f6f99c22509825a85bd090e42f935b33983 (patch) | |
| tree | 7aeca0eade74c1122439e2efe69c5589289512dd | |
| parent | 8dea0d0172d5a50b75dbde8ece24201f0d5b2125 (diff) | |
| download | rust-02477f6f99c22509825a85bd090e42f935b33983.tar.gz rust-02477f6f99c22509825a85bd090e42f935b33983.zip | |
Add is_sorted impl for [T]
| -rw-r--r-- | src/libcore/iter/iterator.rs | 36 | ||||
| -rw-r--r-- | src/libcore/slice/mod.rs | 79 | ||||
| -rw-r--r-- | src/libcore/tests/slice.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/feature-gates/feature-gate-is_sorted.rs | 2 |
4 files changed, 110 insertions, 22 deletions
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 6c3f8d91912..879cc8357cd 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -2608,19 +2608,18 @@ pub trait Iterator { /// Checks if the elements of this iterator are sorted. /// - /// That is, for each element `a` and its following element `b`, `a <= b` - /// must hold. If the iterator yields exactly zero or one element, `true` - /// is returned. + /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the + /// iterator yields exactly zero or one element, `true` is returned. /// - /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above - /// definition implies that this function returns `false` if any two - /// consecutive items are not comparable. + /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition + /// implies that this function returns `false` if any two consecutive items are not + /// comparable. /// /// # Examples /// /// ``` /// #![feature(is_sorted)] - /// + /// /// assert!([1, 2, 2, 9].iter().is_sorted()); /// assert!(![1, 3, 2, 4].iter().is_sorted()); /// assert!([0].iter().is_sorted()); @@ -2636,13 +2635,11 @@ pub trait Iterator { self.is_sorted_by(|a, b| a.partial_cmp(b)) } - /// Checks if the elements of this iterator are sorted using the given - /// comparator function. + /// Checks if the elements of this iterator are sorted using the given comparator function. /// - /// Instead of using `PartialOrd::partial_cmp`, this function uses the given - /// `compare` function to determine the ordering of two elements. Apart from - /// that, it's equivalent to `is_sorted`; see its documentation for more - /// information. + /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` + /// function to determine the ordering of two elements. Apart from that, it's equivalent to + /// `is_sorted`; see its documentation for more information. #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted_by<F>(mut self, mut compare: F) -> bool where @@ -2664,19 +2661,18 @@ pub trait Iterator { true } - /// Checks if the elements of this iterator are sorted using the given - /// key extraction function. + /// Checks if the elements of this iterator are sorted using the given key extraction + /// function. /// - /// Instead of comparing the iterator's elements directly, this function - /// compares the keys of the elements, as determined by `f`. Apart from - /// that, it's equivalent to `is_sorted`; see its documentation for more - /// information. + /// Instead of comparing the iterator's elements directly, this function compares the keys of + /// the elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see + /// its documentation for more information. /// /// # Examples /// /// ``` /// #![feature(is_sorted)] - /// + /// /// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); /// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 7fdc2acb8cc..d4cac3e4f4b 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1783,7 +1783,7 @@ impl<T> [T] { /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; /// a[1..5].rotate_left(1); /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']); - /// ``` + /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] pub fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); @@ -2250,6 +2250,83 @@ impl<T> [T] { from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len)) } } + + /// Checks if the elements of this slice are sorted. + /// + /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the + /// slice yields exactly zero or one element, `true` is returned. + /// + /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition + /// implies that this function returns `false` if any two consecutive items are not + /// comparable. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// let empty: [i32; 0] = []; + /// + /// assert!([1, 2, 2, 9].is_sorted()); + /// assert!(![1, 3, 2, 4].is_sorted()); + /// assert!([0].is_sorted()); + /// assert!(empty.is_sorted()); + /// assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted(&self) -> bool + where + T: PartialOrd, + { + self.is_sorted_by(|a, b| a.partial_cmp(b)) + } + + /// Checks if the elements of this slice are sorted using the given comparator function. + /// + /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare` + /// function to determine the ordering of two elements. Apart from that, it's equivalent to + /// `is_sorted`; see its documentation for more information. + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted_by<F>(&self, mut compare: F) -> bool + where + F: FnMut(&T, &T) -> Option<Ordering> + { + let mut last = match self.first() { + Some(e) => e, + None => return true, + }; + + for curr in &self[1..] { + if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) { + return false; + } + last = &curr; + } + + true + } + + /// Checks if the elements of this slice are sorted using the given key extraction function. + /// + /// Instead of comparing the slice's elements directly, this function compares the keys of the + /// elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see its + /// documentation for more information. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_sorted)] + /// + /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); + /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + /// ``` + #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + pub fn is_sorted_by_key<F, K>(&self, mut f: F) -> bool + where + F: FnMut(&T) -> K, + K: PartialOrd + { + self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b))) + } } #[lang = "slice_u8"] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 2c96efbda76..e210e83122c 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1317,3 +1317,18 @@ fn test_copy_within_panics_src_inverted() { // 2 is greater than 1, so this range is invalid. bytes.copy_within(2..1, 0); } + +#[test] +fn test_is_sorted() { + let empty: [i32; 0] = []; + + assert!([1, 2, 2, 9].is_sorted()); + assert!(![1, 3, 2].is_sorted()); + assert!([0].is_sorted()); + assert!(empty.is_sorted()); + assert!(![0.0, 1.0, std::f32::NAN].is_sorted()); + assert!([-2, -1, 0, 3].is_sorted()); + assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); + assert!(!["c", "bb", "aaa"].is_sorted()); + assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); +} diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index 6b0f943b6c7..82fee379a4f 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -13,4 +13,4 @@ fn main() { //^ ERROR: use of unstable library feature 'is_sorted' assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); //^ ERROR: use of unstable library feature 'is_sorted' -} \ No newline at end of file +} |
