Skip to content

Commit e3e72cd

Browse files
committed
Add is_sorted impl for [T]
1 parent a34ba15 commit e3e72cd

File tree

4 files changed

+110
-22
lines changed

4 files changed

+110
-22
lines changed

src/libcore/iter/iterator.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,19 +2588,18 @@ pub trait Iterator {
25882588

25892589
/// Checks if the elements of this iterator are sorted.
25902590
///
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.
2591+
/// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
2592+
/// iterator yields exactly zero or one element, `true` is returned.
25942593
///
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.
2594+
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
2595+
/// implies that this function returns `false` if any two consecutive items are not
2596+
/// comparable.
25982597
///
25992598
/// # Examples
26002599
///
26012600
/// ```
26022601
/// #![feature(is_sorted)]
2603-
///
2602+
///
26042603
/// assert!([1, 2, 2, 9].iter().is_sorted());
26052604
/// assert!(![1, 3, 2, 4].iter().is_sorted());
26062605
/// assert!([0].iter().is_sorted());
@@ -2616,13 +2615,11 @@ pub trait Iterator {
26162615
self.is_sorted_by(|a, b| a.partial_cmp(b))
26172616
}
26182617

2619-
/// Checks if the elements of this iterator are sorted using the given
2620-
/// comparator function.
2618+
/// Checks if the elements of this iterator are sorted using the given comparator function.
26212619
///
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.
2620+
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
2621+
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
2622+
/// `is_sorted`; see its documentation for more information.
26262623
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
26272624
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
26282625
where
@@ -2644,19 +2641,18 @@ pub trait Iterator {
26442641
true
26452642
}
26462643

2647-
/// Checks if the elements of this iterator are sorted using the given
2648-
/// key extraction function.
2644+
/// Checks if the elements of this iterator are sorted using the given key extraction
2645+
/// function.
26492646
///
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.
2647+
/// Instead of comparing the iterator's elements directly, this function compares the keys of
2648+
/// the elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see
2649+
/// its documentation for more information.
26542650
///
26552651
/// # Examples
26562652
///
26572653
/// ```
26582654
/// #![feature(is_sorted)]
2659-
///
2655+
///
26602656
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
26612657
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
26622658
/// ```

src/libcore/slice/mod.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,7 @@ impl<T> [T] {
17911791
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
17921792
/// a[1..5].rotate_left(1);
17931793
/// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
1794-
/// ```
1794+
/// ```
17951795
#[stable(feature = "slice_rotate", since = "1.26.0")]
17961796
pub fn rotate_left(&mut self, mid: usize) {
17971797
assert!(mid <= self.len());
@@ -2258,6 +2258,83 @@ impl<T> [T] {
22582258
from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len))
22592259
}
22602260
}
2261+
2262+
/// Checks if the elements of this slice are sorted.
2263+
///
2264+
/// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
2265+
/// slice yields exactly zero or one element, `true` is returned.
2266+
///
2267+
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
2268+
/// implies that this function returns `false` if any two consecutive items are not
2269+
/// comparable.
2270+
///
2271+
/// # Examples
2272+
///
2273+
/// ```
2274+
/// #![feature(is_sorted)]
2275+
/// let empty: [i32; 0] = [];
2276+
///
2277+
/// assert!([1, 2, 2, 9].is_sorted());
2278+
/// assert!(![1, 3, 2, 4].is_sorted());
2279+
/// assert!([0].is_sorted());
2280+
/// assert!(empty.is_sorted());
2281+
/// assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
2282+
/// ```
2283+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2284+
pub fn is_sorted(&self) -> bool
2285+
where
2286+
T: PartialOrd,
2287+
{
2288+
self.is_sorted_by(|a, b| a.partial_cmp(b))
2289+
}
2290+
2291+
/// Checks if the elements of this slice are sorted using the given comparator function.
2292+
///
2293+
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
2294+
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
2295+
/// `is_sorted`; see its documentation for more information.
2296+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2297+
pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
2298+
where
2299+
F: FnMut(&T, &T) -> Option<Ordering>
2300+
{
2301+
let mut last = match self.first() {
2302+
Some(e) => e,
2303+
None => return true,
2304+
};
2305+
2306+
for curr in &self[1..] {
2307+
if compare(&last, &curr).map(|o| o == Ordering::Greater).unwrap_or(true) {
2308+
return false;
2309+
}
2310+
last = &curr;
2311+
}
2312+
2313+
true
2314+
}
2315+
2316+
/// Checks if the elements of this slice are sorted using the given key extraction function.
2317+
///
2318+
/// Instead of comparing the slice's elements directly, this function compares the keys of the
2319+
/// elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see its
2320+
/// documentation for more information.
2321+
///
2322+
/// # Examples
2323+
///
2324+
/// ```
2325+
/// #![feature(is_sorted)]
2326+
///
2327+
/// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
2328+
/// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
2329+
/// ```
2330+
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
2331+
pub fn is_sorted_by_key<F, K>(&self, mut f: F) -> bool
2332+
where
2333+
F: FnMut(&T) -> K,
2334+
K: PartialOrd
2335+
{
2336+
self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
2337+
}
22612338
}
22622339

22632340
#[lang = "slice_u8"]

src/libcore/tests/slice.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,3 +1327,18 @@ fn test_copy_within_panics_src_inverted() {
13271327
// 2 is greater than 1, so this range is invalid.
13281328
bytes.copy_within(2..1, 0);
13291329
}
1330+
1331+
#[test]
1332+
fn test_is_sorted() {
1333+
let empty: [i32; 0] = [];
1334+
1335+
assert!([1, 2, 2, 9].is_sorted());
1336+
assert!(![1, 3, 2].is_sorted());
1337+
assert!([0].is_sorted());
1338+
assert!(empty.is_sorted());
1339+
assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
1340+
assert!([-2, -1, 0, 3].is_sorted());
1341+
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1342+
assert!(!["c", "bb", "aaa"].is_sorted());
1343+
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
1344+
}

src/test/ui/feature-gates/feature-gate-is_sorted.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ fn main() {
1313
//^ ERROR: use of unstable library feature 'is_sorted'
1414
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
1515
//^ ERROR: use of unstable library feature 'is_sorted'
16-
}
16+
}

0 commit comments

Comments
 (0)