Skip to content

Commit 8dea0d0

Browse files
committed
Add initial impl of is_sorted to Iterator
1 parent daa53a5 commit 8dea0d0

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

src/libcore/iter/iterator.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,6 +2605,90 @@ pub trait Iterator {
26052605
}
26062606
}
26072607
}
2608+
2609+
/// Checks if the elements of this iterator are sorted.
2610+
///
2611+
/// That is, for each element `a` and its following element `b`, `a <= b`
2612+
/// must hold. If the iterator yields exactly zero or one element, `true`
2613+
/// is returned.
2614+
///
2615+
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above
2616+
/// definition implies that this function returns `false` if any two
2617+
/// consecutive items are not comparable.
2618+
///
2619+
/// # Examples
2620+
///
2621+
/// ```
2622+
/// #![feature(is_sorted)]
2623+
///
2624+
/// assert!([1, 2, 2, 9].iter().is_sorted());
2625+
/// assert!(![1, 3, 2, 4].iter().is_sorted());
2626+
/// assert!([0].iter().is_sorted());
2627+
/// assert!(std::iter::empty::<i32>().is_sorted());
2628+
/// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
2629+
/// ```
2630+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2631+
fn is_sorted(self) -> bool
2632+
where
2633+
Self: Sized,
2634+
Self::Item: PartialOrd,
2635+
{
2636+
self.is_sorted_by(|a, b| a.partial_cmp(b))
2637+
}
2638+
2639+
/// Checks if the elements of this iterator are sorted using the given
2640+
/// comparator function.
2641+
///
2642+
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given
2643+
/// `compare` function to determine the ordering of two elements. Apart from
2644+
/// that, it's equivalent to `is_sorted`; see its documentation for more
2645+
/// information.
2646+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2647+
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
2648+
where
2649+
Self: Sized,
2650+
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>
2651+
{
2652+
let mut last = match self.next() {
2653+
Some(e) => e,
2654+
None => return true,
2655+
};
2656+
2657+
while let Some(curr) = self.next() {
2658+
if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) {
2659+
return false;
2660+
}
2661+
last = curr;
2662+
}
2663+
2664+
true
2665+
}
2666+
2667+
/// Checks if the elements of this iterator are sorted using the given
2668+
/// key extraction function.
2669+
///
2670+
/// Instead of comparing the iterator's elements directly, this function
2671+
/// compares the keys of the elements, as determined by `f`. Apart from
2672+
/// that, it's equivalent to `is_sorted`; see its documentation for more
2673+
/// information.
2674+
///
2675+
/// # Examples
2676+
///
2677+
/// ```
2678+
/// #![feature(is_sorted)]
2679+
///
2680+
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
2681+
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
2682+
/// ```
2683+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2684+
fn is_sorted_by_key<F, K>(self, mut f: F) -> bool
2685+
where
2686+
Self: Sized,
2687+
F: FnMut(&Self::Item) -> K,
2688+
K: PartialOrd
2689+
{
2690+
self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
2691+
}
26082692
}
26092693

26102694
/// Select an element from an iterator based on the given "projection"

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#![feature(extern_types)]
8080
#![feature(fundamental)]
8181
#![feature(intrinsics)]
82+
#![feature(is_sorted)]
8283
#![feature(iter_once_with)]
8384
#![feature(lang_items)]
8485
#![feature(link_llvm_intrinsics)]

src/libcore/tests/iter.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,3 +2235,16 @@ fn test_monad_laws_associativity() {
22352235
assert_eq!((0..10).flat_map(f).flat_map(g).sum::<usize>(),
22362236
(0..10).flat_map(|x| f(x).flat_map(g)).sum::<usize>());
22372237
}
2238+
2239+
#[test]
2240+
fn test_is_sorted() {
2241+
assert!([1, 2, 2, 9].iter().is_sorted());
2242+
assert!(![1, 3, 2].iter().is_sorted());
2243+
assert!([0].iter().is_sorted());
2244+
assert!(std::iter::empty::<i32>().is_sorted());
2245+
assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
2246+
assert!([-2, -1, 0, 3].iter().is_sorted());
2247+
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
2248+
assert!(!["c", "bb", "aaa"].iter().is_sorted());
2249+
assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
2250+
}

src/libcore/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(flt2dec)]
1111
#![feature(fmt_internals)]
1212
#![feature(hashmap_internals)]
13+
#![feature(is_sorted)]
1314
#![feature(iter_copied)]
1415
#![feature(iter_nth_back)]
1516
#![feature(iter_once_with)]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
assert!([1, 2, 2, 9].iter().is_sorted());
13+
//^ ERROR: use of unstable library feature 'is_sorted'
14+
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
15+
//^ ERROR: use of unstable library feature 'is_sorted'
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
2+
--> $DIR/feature-gate-is_sorted.rs:12:33
3+
|
4+
LL | assert!([1, 2, 2, 9].iter().is_sorted());
5+
| ^^^^^^^^^
6+
|
7+
= help: add #![feature(is_sorted)] to the crate attributes to enable
8+
9+
error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485)
10+
--> $DIR/feature-gate-is_sorted.rs:14:39
11+
|
12+
LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
13+
| ^^^^^^^^^^^^^^^^
14+
|
15+
= help: add #![feature(is_sorted)] to the crate attributes to enable
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)