Skip to content

Commit a34ba15

Browse files
committed
Add initial impl of is_sorted to Iterator
1 parent b3af092 commit a34ba15

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
@@ -2585,6 +2585,90 @@ pub trait Iterator {
25852585
}
25862586
}
25872587
}
2588+
2589+
/// Checks if the elements of this iterator are sorted.
2590+
///
2591+
/// That is, for each element `a` and its following element `b`, `a <= b`
2592+
/// must hold. If the iterator yields exactly zero or one element, `true`
2593+
/// is returned.
2594+
///
2595+
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above
2596+
/// definition implies that this function returns `false` if any two
2597+
/// consecutive items are not comparable.
2598+
///
2599+
/// # Examples
2600+
///
2601+
/// ```
2602+
/// #![feature(is_sorted)]
2603+
///
2604+
/// assert!([1, 2, 2, 9].iter().is_sorted());
2605+
/// assert!(![1, 3, 2, 4].iter().is_sorted());
2606+
/// assert!([0].iter().is_sorted());
2607+
/// assert!(std::iter::empty::<i32>().is_sorted());
2608+
/// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
2609+
/// ```
2610+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2611+
fn is_sorted(self) -> bool
2612+
where
2613+
Self: Sized,
2614+
Self::Item: PartialOrd,
2615+
{
2616+
self.is_sorted_by(|a, b| a.partial_cmp(b))
2617+
}
2618+
2619+
/// Checks if the elements of this iterator are sorted using the given
2620+
/// comparator function.
2621+
///
2622+
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given
2623+
/// `compare` function to determine the ordering of two elements. Apart from
2624+
/// that, it's equivalent to `is_sorted`; see its documentation for more
2625+
/// information.
2626+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2627+
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
2628+
where
2629+
Self: Sized,
2630+
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>
2631+
{
2632+
let mut last = match self.next() {
2633+
Some(e) => e,
2634+
None => return true,
2635+
};
2636+
2637+
while let Some(curr) = self.next() {
2638+
if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) {
2639+
return false;
2640+
}
2641+
last = curr;
2642+
}
2643+
2644+
true
2645+
}
2646+
2647+
/// Checks if the elements of this iterator are sorted using the given
2648+
/// key extraction function.
2649+
///
2650+
/// Instead of comparing the iterator's elements directly, this function
2651+
/// compares the keys of the elements, as determined by `f`. Apart from
2652+
/// that, it's equivalent to `is_sorted`; see its documentation for more
2653+
/// information.
2654+
///
2655+
/// # Examples
2656+
///
2657+
/// ```
2658+
/// #![feature(is_sorted)]
2659+
///
2660+
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
2661+
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
2662+
/// ```
2663+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2664+
fn is_sorted_by_key<F, K>(self, mut f: F) -> bool
2665+
where
2666+
Self: Sized,
2667+
F: FnMut(&Self::Item) -> K,
2668+
K: PartialOrd
2669+
{
2670+
self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
2671+
}
25882672
}
25892673

25902674
/// 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
@@ -88,6 +88,7 @@
8888
#![feature(extern_types)]
8989
#![feature(fundamental)]
9090
#![feature(intrinsics)]
91+
#![feature(is_sorted)]
9192
#![feature(lang_items)]
9293
#![feature(link_llvm_intrinsics)]
9394
#![feature(never_type)]

src/libcore/tests/iter.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,3 +2162,16 @@ fn test_monad_laws_associativity() {
21622162
assert_eq!((0..10).flat_map(f).flat_map(g).sum::<usize>(),
21632163
(0..10).flat_map(|x| f(x).flat_map(g)).sum::<usize>());
21642164
}
2165+
2166+
#[test]
2167+
fn test_is_sorted() {
2168+
assert!([1, 2, 2, 9].iter().is_sorted());
2169+
assert!(![1, 3, 2].iter().is_sorted());
2170+
assert!([0].iter().is_sorted());
2171+
assert!(std::iter::empty::<i32>().is_sorted());
2172+
assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
2173+
assert!([-2, -1, 0, 3].iter().is_sorted());
2174+
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
2175+
assert!(!["c", "bb", "aaa"].iter().is_sorted());
2176+
assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
2177+
}

src/libcore/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#![feature(flt2dec)]
2020
#![feature(fmt_internals)]
2121
#![feature(hashmap_internals)]
22+
#![feature(is_sorted)]
2223
#![feature(iter_unfold)]
2324
#![feature(pattern)]
2425
#![feature(range_is_empty)]
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)