Skip to content

Commit f9a09e0

Browse files
committed
Better document for partial_sort_unstable
Signed-off-by: tison <wander4096@gmail.com>
1 parent 0e87d5d commit f9a09e0

1 file changed

Lines changed: 147 additions & 8 deletions

File tree

library/core/src/slice/mod.rs

Lines changed: 147 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)