@@ -3242,8 +3242,64 @@ impl<T> [T] {
32423242 sort:: unstable:: sort ( self , & mut |a, b| f ( a) . lt ( & f ( b) ) ) ;
32433243 }
32443244
3245- /// Partially sorts the slice in ascending order **without** preserving the initial order
3246- /// of equal elements.
3245+ /// Partially sorts the slice in ascending order **without** preserving the initial order of equal elements.
3246+ ///
3247+ /// Upon completion, the elements in the specified `range` will be the elements of the slice
3248+ /// as if the whole slice were sorted in ascending order.
3249+ ///
3250+ /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3251+ /// allocate), and *O*(*n* + *k* \* log(*k*)) worst-case.
3252+ ///
3253+ /// If the implementation of [`Ord`] for `T` does not implement a [total order], the function
3254+ /// may panic; even if the function exits normally, the resulting order of elements in the slice
3255+ /// is unspecified. See also the note on panicking below.
3256+ ///
3257+ /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3258+ /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3259+ /// examples see the [`Ord`] documentation.
3260+ ///
3261+ /// All original elements will remain in the slice and any possible modifications via interior
3262+ /// mutability are observed in the input. Same is true if the implementation of [`Ord`] for `T` panics.
3263+ ///
3264+ /// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
3265+ /// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
3266+ /// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
3267+ /// `slice::partial_sort_unstable_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a
3268+ /// [total order] users can sort slices containing floating-point values. Alternatively, if all
3269+ /// values in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`]
3270+ /// forms a [total order], it's possible to sort the slice with `partial_sort_unstable_by(|a, b|
3271+ /// a.partial_cmp(b).unwrap())`.
3272+ ///
3273+ /// # Panics
3274+ ///
3275+ /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order], or if
3276+ /// the [`Ord`] implementation panics, or if the specified range is out of bounds.
3277+ ///
3278+ /// # Examples
3279+ ///
3280+ /// ```
3281+ /// #![feature(slice_partial_sort_unstable)]
3282+ ///
3283+ /// let mut v = [4, -5, 1, -3, 2];
3284+ ///
3285+ /// // empty range, nothing changed
3286+ /// v.partial_sort_unstable(0..0);
3287+ /// assert_eq!(v, [4, -5, 1, -3, 2]);
3288+ ///
3289+ /// // single element range, same as select_nth_unstable
3290+ /// v.partial_sort_unstable(2..3);
3291+ /// assert_eq!(v[2], 1);
3292+ ///
3293+ /// // partial sort a subrange
3294+ /// v.partial_sort_unstable(1..4);
3295+ /// assert_eq!(&v[1..4], [-3, 1, 2]);
3296+ ///
3297+ /// // partial sort the whole range, same as sort_unstable
3298+ /// v.partial_sort_unstable(..);
3299+ /// assert_eq!(v, [-5, -3, 1, 2, 4]);
3300+ /// ```
3301+ ///
3302+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
32473303 #[ unstable( feature = "slice_partial_sort_unstable" , issue = "149046" ) ]
32483304 #[ inline]
32493305 pub fn partial_sort_unstable < R > ( & mut self , range : R )
@@ -3257,19 +3313,53 @@ impl<T> [T] {
32573313 /// Partially sorts the slice in ascending order with a comparison function, **without**
32583314 /// preserving the initial order of equal elements.
32593315 ///
3316+ /// Upon completion, the elements in the specified `range` will be the elements of the slice
3317+ /// as if the whole slice were sorted in ascending order.
3318+ ///
3319+ /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3320+ /// allocate), and *O*(*n* + *k* \* log(*k*)) worst-case.
3321+ ///
3322+ /// If the comparison function `compare` does not implement a [total order], the function
3323+ /// may panic; even if the function exits normally, the resulting order of elements in the slice
3324+ /// is unspecified. See also the note on panicking below.
3325+ ///
3326+ /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3327+ /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3328+ /// examples see the [`Ord`] documentation.
3329+ ///
3330+ /// All original elements will remain in the slice and any possible modifications via interior
3331+ /// mutability are observed in the input. Same is true if `compare` panics.
3332+ ///
3333+ /// # Panics
3334+ ///
3335+ /// May panic if the `compare` does not implement a [total order], or if
3336+ /// the `compare` itself panics, or if the specified range is out of bounds.
3337+ ///
32603338 /// # Examples
32613339 ///
32623340 /// ```
32633341 /// #![feature(slice_partial_sort_unstable)]
32643342 ///
32653343 /// let mut v = [4, -5, 1, -3, 2];
3266- /// v.partial_sort_unstable_by(.., |a, b| a.cmp(b));
3267- /// assert_eq!(v, [-5, -3, 1, 2, 4]);
32683344 ///
3269- /// // reverse sorting
3345+ /// // empty range, nothing changed
3346+ /// v.partial_sort_unstable_by(0..0, |a, b| b.cmp(a));
3347+ /// assert_eq!(v, [4, -5, 1, -3, 2]);
3348+ ///
3349+ /// // single element range, same as select_nth_unstable
3350+ /// v.partial_sort_unstable_by(2..3, |a, b| b.cmp(a));
3351+ /// assert_eq!(v[2], 1);
3352+ ///
3353+ /// // partial sort a subrange
3354+ /// v.partial_sort_unstable_by(1..4, |a, b| b.cmp(a));
3355+ /// assert_eq!(&v[1..4], [2, 1, -3]);
3356+ ///
3357+ /// // partial sort the whole range, same as sort_unstable
32703358 /// v.partial_sort_unstable_by(.., |a, b| b.cmp(a));
32713359 /// assert_eq!(v, [4, 2, 1, -3, -5]);
32723360 /// ```
3361+ ///
3362+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
32733363 #[ unstable( feature = "slice_partial_sort_unstable" , issue = "149046" ) ]
32743364 #[ inline]
32753365 pub fn partial_sort_unstable_by < F , R > ( & mut self , range : R , mut compare : F )
@@ -3280,8 +3370,8 @@ impl<T> [T] {
32803370 let len = self . len ( ) ;
32813371 let Range { start, end } = slice:: range ( range, ..len) ;
32823372
3283- if start == end {
3284- // empty range, nothing to do
3373+ if start + 1 > end {
3374+ // target range is empty , nothing to do
32853375 return ;
32863376 }
32873377
@@ -3290,18 +3380,67 @@ impl<T> [T] {
32903380 sort:: select:: partition_at_index ( self , index, |a, b| compare ( a, b) == Less ) ;
32913381
32923382 if start + 2 > end {
3293- // the rest slice is of length 0 or 1, already sorted
3383+ // target range is a single element, nothing more to do
32943384 return ;
32953385 }
32963386
32973387 let index = end - start - 2 ;
32983388 let ( rest, _, _) =
32993389 sort:: select:: partition_at_index ( rest, index, |a, b| compare ( a, b) == Less ) ;
3390+
33003391 sort:: unstable:: sort ( rest, & mut |a, b| compare ( a, b) == Less ) ;
33013392 }
33023393
33033394 /// Partially sorts the slice in ascending order with a key extraction function, **without**
33043395 /// preserving the initial order of equal elements.
3396+ ///
3397+ /// Upon completion, the elements in the specified `range` will be the elements of the slice
3398+ /// as if the whole slice were sorted in ascending order.
3399+ ///
3400+ /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3401+ /// allocate), and *O*(*n* + *k* \* log(*k*)) worst-case.
3402+ ///
3403+ /// If the implementation of [`Ord`] for `K` does not implement a [total order], the function
3404+ /// may panic; even if the function exits normally, the resulting order of elements in the slice
3405+ /// is unspecified. See also the note on panicking below.
3406+ ///
3407+ /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3408+ /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3409+ /// examples see the [`Ord`] documentation.
3410+ ///
3411+ /// All original elements will remain in the slice and any possible modifications via interior
3412+ /// mutability are observed in the input. Same is true if the implementation of [`Ord`] for `K` panics.
3413+ ///
3414+ /// # Panics
3415+ ///
3416+ /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order], or if
3417+ /// the [`Ord`] implementation panics, or if the specified range is out of bounds.
3418+ ///
3419+ /// # Examples
3420+ ///
3421+ /// ```
3422+ /// #![feature(slice_partial_sort_unstable)]
3423+ ///
3424+ /// let mut v = [4i32, -5, 1, -3, 2];
3425+ ///
3426+ /// // empty range, nothing changed
3427+ /// v.partial_sort_unstable_by_key(0..0, |k| k.abs());
3428+ /// assert_eq!(v, [4, -5, 1, -3, 2]);
3429+ ///
3430+ /// // single element range, same as select_nth_unstable
3431+ /// v.partial_sort_unstable_by_key(2..3, |k| k.abs());
3432+ /// assert_eq!(v[2], -3);
3433+ ///
3434+ /// // partial sort a subrange
3435+ /// v.partial_sort_unstable_by_key(1..4, |k| k.abs());
3436+ /// assert_eq!(&v[1..4], [2, -3, 4]);
3437+ ///
3438+ /// // partial sort the whole range, same as sort_unstable
3439+ /// v.partial_sort_unstable_by_key(.., |k| k.abs());
3440+ /// assert_eq!(v, [1, 2, -3, 4, -5]);
3441+ /// ```
3442+ ///
3443+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
33053444 #[ unstable( feature = "slice_partial_sort_unstable" , issue = "149046" ) ]
33063445 #[ inline]
33073446 pub fn partial_sort_unstable_by_key < K , F , R > ( & mut self , range : R , mut f : F )
0 commit comments