Auto merge of #43010 - stjepang:stabilize-sort-unstable, r=alexcrichton

Stabilize feature sort_unstable

Closes #40585
This commit is contained in:
bors 2017-07-02 23:54:32 +00:00
commit 1d2db7b9e8
10 changed files with 20 additions and 63 deletions

View File

@ -1,40 +0,0 @@
# `sort_unstable`
The tracking issue for this feature is: [#40585]
[#40585]: https://github.com/rust-lang/rust/issues/40585
------------------------
The default `sort` method on slices is stable. In other words, it guarantees
that the original order of equal elements is preserved after sorting. The
method has several undesirable characteristics:
1. It allocates a sizable chunk of memory.
2. If you don't need stability, it is not as performant as it could be.
An alternative is the new `sort_unstable` feature, which includes these
methods for sorting slices:
1. `sort_unstable`
2. `sort_unstable_by`
3. `sort_unstable_by_key`
Unstable sorting is generally faster and makes no allocations. The majority
of real-world sorting needs doesn't require stability, so these methods can
very often come in handy.
Another important difference is that `sort` lives in `libstd` and
`sort_unstable` lives in `libcore`. The reason is that the former makes
allocations and the latter doesn't.
A simple example:
```rust
#![feature(sort_unstable)]
let mut v = [-5, 4, 1, -3, 2];
v.sort_unstable();
assert!(v == [-5, -3, 1, 2, 4]);
```

View File

@ -14,7 +14,6 @@
#![feature(rand)] #![feature(rand)]
#![feature(repr_simd)] #![feature(repr_simd)]
#![feature(slice_rotate)] #![feature(slice_rotate)]
#![feature(sort_unstable)]
#![feature(test)] #![feature(test)]
extern crate rand; extern crate rand;

View File

@ -83,7 +83,6 @@
#![cfg_attr(not(test), feature(core_float))] #![cfg_attr(not(test), feature(core_float))]
#![cfg_attr(not(test), feature(exact_size_is_empty))] #![cfg_attr(not(test), feature(exact_size_is_empty))]
#![cfg_attr(not(test), feature(slice_rotate))] #![cfg_attr(not(test), feature(slice_rotate))]
#![cfg_attr(not(test), feature(sort_unstable))]
#![cfg_attr(not(test), feature(str_checked_slicing))] #![cfg_attr(not(test), feature(str_checked_slicing))]
#![cfg_attr(test, feature(rand, test))] #![cfg_attr(test, feature(rand, test))]
#![feature(allocator)] #![feature(allocator)]

View File

@ -1144,6 +1144,10 @@ impl<T> [T] {
/// ///
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
/// ///
/// When applicable, unstable sorting is preferred because it is generally faster than stable
/// sorting and it doesn't allocate auxiliary memory.
/// See [`sort_unstable`](#method.sort_unstable).
///
/// # Current implementation /// # Current implementation
/// ///
/// The current algorithm is an adaptive, iterative merge sort inspired by /// The current algorithm is an adaptive, iterative merge sort inspired by
@ -1174,6 +1178,10 @@ impl<T> [T] {
/// ///
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
/// ///
/// When applicable, unstable sorting is preferred because it is generally faster than stable
/// sorting and it doesn't allocate auxiliary memory.
/// See [`sort_unstable_by`](#method.sort_unstable_by).
///
/// # Current implementation /// # Current implementation
/// ///
/// The current algorithm is an adaptive, iterative merge sort inspired by /// The current algorithm is an adaptive, iterative merge sort inspired by
@ -1207,6 +1215,10 @@ impl<T> [T] {
/// ///
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
/// ///
/// When applicable, unstable sorting is preferred because it is generally faster than stable
/// sorting and it doesn't allocate auxiliary memory.
/// See [`sort_unstable_by_key`](#method.sort_unstable_by_key).
///
/// # Current implementation /// # Current implementation
/// ///
/// The current algorithm is an adaptive, iterative merge sort inspired by /// The current algorithm is an adaptive, iterative merge sort inspired by
@ -1251,8 +1263,6 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(sort_unstable)]
///
/// let mut v = [-5, 4, 1, -3, 2]; /// let mut v = [-5, 4, 1, -3, 2];
/// ///
/// v.sort_unstable(); /// v.sort_unstable();
@ -1260,8 +1270,7 @@ impl<T> [T] {
/// ``` /// ```
/// ///
/// [pdqsort]: https://github.com/orlp/pdqsort /// [pdqsort]: https://github.com/orlp/pdqsort
// FIXME #40585: Mention `sort_unstable` in the documentation for `sort`. #[stable(feature = "sort_unstable", since = "1.20.0")]
#[unstable(feature = "sort_unstable", issue = "40585")]
#[inline] #[inline]
pub fn sort_unstable(&mut self) pub fn sort_unstable(&mut self)
where T: Ord where T: Ord
@ -1288,8 +1297,6 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(sort_unstable)]
///
/// let mut v = [5, 4, 1, 3, 2]; /// let mut v = [5, 4, 1, 3, 2];
/// v.sort_unstable_by(|a, b| a.cmp(b)); /// v.sort_unstable_by(|a, b| a.cmp(b));
/// assert!(v == [1, 2, 3, 4, 5]); /// assert!(v == [1, 2, 3, 4, 5]);
@ -1300,8 +1307,7 @@ impl<T> [T] {
/// ``` /// ```
/// ///
/// [pdqsort]: https://github.com/orlp/pdqsort /// [pdqsort]: https://github.com/orlp/pdqsort
// FIXME #40585: Mention `sort_unstable_by` in the documentation for `sort_by`. #[stable(feature = "sort_unstable", since = "1.20.0")]
#[unstable(feature = "sort_unstable", issue = "40585")]
#[inline] #[inline]
pub fn sort_unstable_by<F>(&mut self, compare: F) pub fn sort_unstable_by<F>(&mut self, compare: F)
where F: FnMut(&T, &T) -> Ordering where F: FnMut(&T, &T) -> Ordering
@ -1328,8 +1334,6 @@ impl<T> [T] {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(sort_unstable)]
///
/// let mut v = [-5i32, 4, 1, -3, 2]; /// let mut v = [-5i32, 4, 1, -3, 2];
/// ///
/// v.sort_unstable_by_key(|k| k.abs()); /// v.sort_unstable_by_key(|k| k.abs());
@ -1337,8 +1341,7 @@ impl<T> [T] {
/// ``` /// ```
/// ///
/// [pdqsort]: https://github.com/orlp/pdqsort /// [pdqsort]: https://github.com/orlp/pdqsort
// FIXME #40585: Mention `sort_unstable_by_key` in the documentation for `sort_by_key`. #[stable(feature = "sort_unstable", since = "1.20.0")]
#[unstable(feature = "sort_unstable", issue = "40585")]
#[inline] #[inline]
pub fn sort_unstable_by_key<B, F>(&mut self, f: F) pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
where F: FnMut(&T) -> B, where F: FnMut(&T) -> B,

View File

@ -212,15 +212,15 @@ pub trait SliceExt {
#[stable(feature = "copy_from_slice", since = "1.9.0")] #[stable(feature = "copy_from_slice", since = "1.9.0")]
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy; fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
#[unstable(feature = "sort_unstable", issue = "40585")] #[stable(feature = "sort_unstable", since = "1.20.0")]
fn sort_unstable(&mut self) fn sort_unstable(&mut self)
where Self::Item: Ord; where Self::Item: Ord;
#[unstable(feature = "sort_unstable", issue = "40585")] #[stable(feature = "sort_unstable", since = "1.20.0")]
fn sort_unstable_by<F>(&mut self, compare: F) fn sort_unstable_by<F>(&mut self, compare: F)
where F: FnMut(&Self::Item, &Self::Item) -> Ordering; where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
#[unstable(feature = "sort_unstable", issue = "40585")] #[stable(feature = "sort_unstable", since = "1.20.0")]
fn sort_unstable_by_key<B, F>(&mut self, f: F) fn sort_unstable_by_key<B, F>(&mut self, f: F)
where F: FnMut(&Self::Item) -> B, where F: FnMut(&Self::Item) -> B,
B: Ord; B: Ord;

View File

@ -351,7 +351,7 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
if start_l < end_l { if start_l < end_l {
// The left block remains. // The left block remains.
// Move it's remaining out-of-order elements to the far right. // Move its remaining out-of-order elements to the far right.
debug_assert_eq!(width(l, r), block_l); debug_assert_eq!(width(l, r), block_l);
while start_l < end_l { while start_l < end_l {
unsafe { unsafe {
@ -363,7 +363,7 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
width(v.as_mut_ptr(), r) width(v.as_mut_ptr(), r)
} else if start_r < end_r { } else if start_r < end_r {
// The right block remains. // The right block remains.
// Move it's remaining out-of-order elements to the far left. // Move its remaining out-of-order elements to the far left.
debug_assert_eq!(width(l, r), block_r); debug_assert_eq!(width(l, r), block_r);
while start_r < end_r { while start_r < end_r {
unsafe { unsafe {

View File

@ -34,7 +34,6 @@
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(slice_rotate)] #![feature(slice_rotate)]
#![feature(sort_internals)] #![feature(sort_internals)]
#![feature(sort_unstable)]
#![feature(specialization)] #![feature(specialization)]
#![feature(step_by)] #![feature(step_by)]
#![feature(step_trait)] #![feature(step_trait)]

View File

@ -39,7 +39,6 @@
#![feature(specialization)] #![feature(specialization)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(discriminant_value)] #![feature(discriminant_value)]
#![feature(sort_unstable)]
#![feature(trace_macros)] #![feature(trace_macros)]
#![feature(test)] #![feature(test)]

View File

@ -20,7 +20,6 @@
#![feature(rand)] #![feature(rand)]
#![feature(conservative_impl_trait)] #![feature(conservative_impl_trait)]
#![feature(sort_unstable)]
extern crate graphviz; extern crate graphviz;
#[macro_use] extern crate rustc; #[macro_use] extern crate rustc;

View File

@ -26,7 +26,6 @@
#![feature(specialization)] #![feature(specialization)]
#![feature(discriminant_value)] #![feature(discriminant_value)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(sort_unstable)]
#[macro_use] #[macro_use]
extern crate log; extern crate log;