Skip to content

Commit 02477f6

Browse files
committed
Add is_sorted impl for [T]
1 parent 8dea0d0 commit 02477f6

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
@@ -2608,19 +2608,18 @@ pub trait Iterator {
26082608

26092609
/// Checks if the elements of this iterator are sorted.
26102610
///
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.
2611+
/// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
2612+
/// iterator yields exactly zero or one element, `true` is returned.
26142613
///
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.
2614+
/// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
2615+
/// implies that this function returns `false` if any two consecutive items are not
2616+
/// comparable.
26182617
///
26192618
/// # Examples
26202619
///
26212620
/// ```
26222621
/// #![feature(is_sorted)]
2623-
///
2622+
///
26242623
/// assert!([1, 2, 2, 9].iter().is_sorted());
26252624
/// assert!(![1, 3, 2, 4].iter().is_sorted());
26262625
/// assert!([0].iter().is_sorted());
@@ -2636,13 +2635,11 @@ pub trait Iterator {
26362635
self.is_sorted_by(|a, b| a.partial_cmp(b))
26372636
}
26382637

2639-
/// Checks if the elements of this iterator are sorted using the given
2640-
/// comparator function.
2638+
/// Checks if the elements of this iterator are sorted using the given comparator function.
26412639
///
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.
2640+
/// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
2641+
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
2642+
/// `is_sorted`; see its documentation for more information.
26462643
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
26472644
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
26482645
where
@@ -2664,19 +2661,18 @@ pub trait Iterator {
26642661
true
26652662
}
26662663

2667-
/// Checks if the elements of this iterator are sorted using the given
2668-
/// key extraction function.
2664+
/// Checks if the elements of this iterator are sorted using the given key extraction
2665+
/// function.
26692666
///
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.
2667+
/// Instead of comparing the iterator's elements directly, this function compares the keys of
2668+
/// the elements, as determined by `f`. Apart from that, it's equivalent to `is_sorted`; see
2669+
/// its documentation for more information.
26742670
///
26752671
/// # Examples
26762672
///
26772673
/// ```
26782674
/// #![feature(is_sorted)]
2679-
///
2675+
///
26802676
/// assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
26812677
/// assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
26822678
/// ```

src/libcore/slice/mod.rs

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

22552332
#[lang = "slice_u8"]

src/libcore/tests/slice.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,3 +1317,18 @@ fn test_copy_within_panics_src_inverted() {
13171317
// 2 is greater than 1, so this range is invalid.
13181318
bytes.copy_within(2..1, 0);
13191319
}
1320+
1321+
#[test]
1322+
fn test_is_sorted() {
1323+
let empty: [i32; 0] = [];
1324+
1325+
assert!([1, 2, 2, 9].is_sorted());
1326+
assert!(![1, 3, 2].is_sorted());
1327+
assert!([0].is_sorted());
1328+
assert!(empty.is_sorted());
1329+
assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
1330+
assert!([-2, -1, 0, 3].is_sorted());
1331+
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1332+
assert!(!["c", "bb", "aaa"].is_sorted());
1333+
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
1334+
}

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)