@@ -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,77 @@ 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+ #[ inline]
2276+ #[ unstable( feature = "is_sorted" , reason = "new API" , issue = "53485" ) ]
2277+ pub fn is_sorted ( & self ) -> bool
2278+ where
2279+ T : PartialOrd ,
2280+ {
2281+ self . is_sorted_by ( |a, b| a. partial_cmp ( b) )
2282+ }
2283+
2284+ /// Checks if the elements of this slice are sorted using the given comparator function.
2285+ ///
2286+ /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
2287+ /// function to determine the ordering of two elements. Apart from that, it's equivalent to
2288+ /// [`is_sorted`]; see its documentation for more information.
2289+ ///
2290+ /// [`is_sorted`]: #method.is_sorted
2291+ #[ unstable( feature = "is_sorted" , reason = "new API" , issue = "53485" ) ]
2292+ pub fn is_sorted_by < F > ( & self , mut compare : F ) -> bool
2293+ where
2294+ F : FnMut ( & T , & T ) -> Option < Ordering >
2295+ {
2296+ self . iter ( ) . is_sorted_by ( |a, b| compare ( * a, * b) )
2297+ }
2298+
2299+ /// Checks if the elements of this slice are sorted using the given key extraction function.
2300+ ///
2301+ /// Instead of comparing the slice's elements directly, this function compares the keys of the
2302+ /// elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see its
2303+ /// documentation for more information.
2304+ ///
2305+ /// [`is_sorted`]: #method.is_sorted
2306+ ///
2307+ /// # Examples
2308+ ///
2309+ /// ```
2310+ /// #![feature(is_sorted)]
2311+ ///
2312+ /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
2313+ /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
2314+ /// ```
2315+ #[ inline]
2316+ #[ unstable( feature = "is_sorted" , reason = "new API" , issue = "53485" ) ]
2317+ pub fn is_sorted_by_key < F , K > ( & self , mut f : F ) -> bool
2318+ where
2319+ F : FnMut ( & T ) -> K ,
2320+ K : PartialOrd
2321+ {
2322+ self . is_sorted_by ( |a, b| f ( a) . partial_cmp ( & f ( b) ) )
2323+ }
22532324}
22542325
22552326#[ lang = "slice_u8" ]
@@ -2773,7 +2844,13 @@ macro_rules! len {
27732844
27742845// The shared definition of the `Iter` and `IterMut` iterators
27752846macro_rules! iterator {
2776- ( struct $name: ident -> $ptr: ty, $elem: ty, $raw_mut: tt, $( $mut_: tt ) * ) => {
2847+ (
2848+ struct $name: ident -> $ptr: ty,
2849+ $elem: ty,
2850+ $raw_mut: tt,
2851+ { $( $mut_: tt ) * } ,
2852+ { $( $extra: tt) * }
2853+ ) => {
27772854 impl <' a, T > $name<' a, T > {
27782855 // Helper function for creating a slice from the iterator.
27792856 #[ inline( always) ]
@@ -2950,6 +3027,8 @@ macro_rules! iterator {
29503027 i
29513028 } )
29523029 }
3030+
3031+ $( $extra) *
29533032 }
29543033
29553034 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -3087,7 +3166,17 @@ impl<'a, T> Iter<'a, T> {
30873166 }
30883167}
30893168
3090- iterator ! { struct Iter -> * const T , & ' a T , const , /* no mut */ }
3169+ iterator ! { struct Iter -> * const T , & ' a T , const , { /* no mut */ } , {
3170+ fn is_sorted_by<F >( self , mut compare: F ) -> bool
3171+ where
3172+ Self : Sized ,
3173+ F : FnMut ( & Self :: Item , & Self :: Item ) -> Option <Ordering >,
3174+ {
3175+ self . as_slice( ) . windows( 2 ) . all( |w| {
3176+ compare( &&w[ 0 ] , &&w[ 1 ] ) . map( |o| o != Ordering :: Greater ) . unwrap_or( false )
3177+ } )
3178+ }
3179+ } }
30913180
30923181#[ stable( feature = "rust1" , since = "1.0.0" ) ]
30933182impl < T > Clone for Iter < ' _ , T > {
@@ -3188,7 +3277,7 @@ impl<'a, T> IterMut<'a, T> {
31883277 }
31893278}
31903279
3191- iterator ! { struct IterMut -> * mut T , & ' a mut T , mut , mut }
3280+ iterator ! { struct IterMut -> * mut T , & ' a mut T , mut , { mut } , { } }
31923281
31933282/// An internal abstraction over the splitting iterators, so that
31943283/// splitn, splitn_mut etc can be implemented once.
0 commit comments