@@ -179,15 +179,25 @@ impl<T> [T] {
179
179
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
180
180
/// worst-case.
181
181
///
182
- /// If `T: Ord` does not implement a total order the resulting order is unspecified. All
183
- /// original elements will remain in the slice and any possible modifications via interior
184
- /// mutability are observed in the input. Same is true if `T: Ord` panics.
182
+ /// If the implementation of [`Ord`] for `T` does not implement a [total order] the resulting
183
+ /// order of elements in the slice is unspecified. All original elements will remain in the
184
+ /// slice and any possible modifications via interior mutability are observed in the input. Same
185
+ /// is true if the implementation of [`Ord`] for `T` panics.
185
186
///
186
187
/// When applicable, unstable sorting is preferred because it is generally faster than stable
187
188
/// sorting and it doesn't allocate auxiliary memory. See
188
189
/// [`sort_unstable`](slice::sort_unstable). The exception are partially sorted slices, which
189
190
/// may be better served with `slice::sort`.
190
191
///
192
+ /// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] requires
193
+ /// additional precautions. For example Rust defines `NaN != NaN`, which doesn't fulfill the
194
+ /// reflexivity requirement posed by [`Ord`]. By using an alternative comparison function with
195
+ /// [`slice::sort_by`] such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a [total
196
+ /// order] users can sort slices containing floating point numbers. Alternatively, if one can
197
+ /// guarantee that all values in the slice are comparable with [`PartialOrd::partial_cmp`] *and*
198
+ /// the implementation forms a [total order], it's possible to sort the slice with `sort_by(|a,
199
+ /// b| a.partial_cmp(b).unwrap())`.
200
+ ///
191
201
/// # Current implementation
192
202
///
193
203
/// The current implementation is based on [driftsort] by Orson Peters and Lukas Bergdoll, which
@@ -201,18 +211,19 @@ impl<T> [T] {
201
211
///
202
212
/// # Panics
203
213
///
204
- /// May panic if `T: Ord` does not implement a total order.
214
+ /// May panic if the implementation of [` Ord`] for `T` does not implement a [ total order] .
205
215
///
206
216
/// # Examples
207
217
///
208
218
/// ```
209
- /// let mut v = [-5, 4 , 1, -3, 2];
219
+ /// let mut v = [4, -5 , 1, -3, 2];
210
220
///
211
221
/// v.sort();
212
- /// assert !(v == [-5, -3, 1, 2, 4]);
222
+ /// assert_eq !(v, [-5, -3, 1, 2, 4]);
213
223
/// ```
214
224
///
215
225
/// [driftsort]: https://github.com/Voultapher/driftsort
226
+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
216
227
#[ cfg( not( no_global_oom_handling) ) ]
217
228
#[ rustc_allow_incoherent_impl]
218
229
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -224,30 +235,19 @@ impl<T> [T] {
224
235
stable_sort ( self , T :: lt) ;
225
236
}
226
237
227
- /// Sorts the slice with a comparator function, preserving initial order of equal elements.
238
+ /// Sorts the slice with a comparison function, preserving initial order of equal elements.
228
239
///
229
240
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
230
241
/// worst-case.
231
242
///
232
- /// The comparator function should define a total ordering for the elements in the slice. If the
233
- /// ordering is not total, the order of the elements is unspecified.
234
- ///
235
- /// If the comparator function does not implement a total order the resulting order is
236
- /// unspecified. All original elements will remain in the slice and any possible modifications
237
- /// via interior mutability are observed in the input. Same is true if the comparator function
238
- /// panics. A total order (for all `a`, `b` and `c`):
239
- ///
240
- /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
241
- /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
243
+ /// If the comparison function `compare` does not implement a [total order] the resulting order
244
+ /// of elements in the slice is unspecified. All original elements will remain in the slice and
245
+ /// any possible modifications via interior mutability are observed in the input. Same is true
246
+ /// if `compare` panics.
242
247
///
243
- /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
244
- /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
245
- ///
246
- /// ```
247
- /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
248
- /// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
249
- /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
250
- /// ```
248
+ /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
249
+ /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
250
+ /// examples see the [`Ord`] documentation.
251
251
///
252
252
/// # Current implementation
253
253
///
@@ -262,21 +262,22 @@ impl<T> [T] {
262
262
///
263
263
/// # Panics
264
264
///
265
- /// May panic if `compare` does not implement a total order.
265
+ /// May panic if `compare` does not implement a [ total order] .
266
266
///
267
267
/// # Examples
268
268
///
269
269
/// ```
270
- /// let mut v = [5, 4 , 1, 3, 2];
270
+ /// let mut v = [4, -5 , 1, - 3, 2];
271
271
/// v.sort_by(|a, b| a.cmp(b));
272
- /// assert !(v == [1, 2, 3, 4, 5 ]);
272
+ /// assert_eq !(v, [-5, -3, 1, 2, 4 ]);
273
273
///
274
274
/// // reverse sorting
275
275
/// v.sort_by(|a, b| b.cmp(a));
276
- /// assert !(v == [5, 4, 3, 2, 1 ]);
276
+ /// assert_eq !(v, [4, 2, 1, -3, -5 ]);
277
277
/// ```
278
278
///
279
279
/// [driftsort]: https://github.com/Voultapher/driftsort
280
+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
280
281
#[ cfg( not( no_global_oom_handling) ) ]
281
282
#[ rustc_allow_incoherent_impl]
282
283
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -293,9 +294,10 @@ impl<T> [T] {
293
294
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
294
295
/// worst-case, where the key function is *O*(*m*).
295
296
///
296
- /// If `K: Ord` does not implement a total order the resulting order is unspecified.
297
- /// All original elements will remain in the slice and any possible modifications via interior
298
- /// mutability are observed in the input. Same is true if `K: Ord` panics.
297
+ /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
298
+ /// order of elements in the slice is unspecified. All original elements will remain in the
299
+ /// slice and any possible modifications via interior mutability are observed in the input. Same
300
+ /// is true if the implementation of [`Ord`] for `K` panics.
299
301
///
300
302
/// # Current implementation
301
303
///
@@ -310,18 +312,19 @@ impl<T> [T] {
310
312
///
311
313
/// # Panics
312
314
///
313
- /// May panic if `K: Ord` does not implement a total order.
315
+ /// May panic if the implementation of [` Ord`] for `K` does not implement a [ total order] .
314
316
///
315
317
/// # Examples
316
318
///
317
319
/// ```
318
- /// let mut v = [-5i32, 4 , 1, -3, 2];
320
+ /// let mut v = [4i32, -5 , 1, -3, 2];
319
321
///
320
322
/// v.sort_by_key(|k| k.abs());
321
- /// assert !(v == [1, 2, -3, 4, -5]);
323
+ /// assert_eq !(v, [1, 2, -3, 4, -5]);
322
324
/// ```
323
325
///
324
326
/// [driftsort]: https://github.com/Voultapher/driftsort
327
+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
325
328
#[ cfg( not( no_global_oom_handling) ) ]
326
329
#[ rustc_allow_incoherent_impl]
327
330
#[ stable( feature = "slice_sort_by_key" , since = "1.7.0" ) ]
@@ -343,9 +346,10 @@ impl<T> [T] {
343
346
/// storage to remember the results of key evaluation. The order of calls to the key function is
344
347
/// unspecified and may change in future versions of the standard library.
345
348
///
346
- /// If `K: Ord` does not implement a total order the resulting order is unspecified.
347
- /// All original elements will remain in the slice and any possible modifications via interior
348
- /// mutability are observed in the input. Same is true if `K: Ord` panics.
349
+ /// If the implementation of [`Ord`] for `K` does not implement a [total order] the resulting
350
+ /// order of elements in the slice is unspecified. All original elements will remain in the
351
+ /// slice and any possible modifications via interior mutability are observed in the input. Same
352
+ /// is true if the implementation of [`Ord`] for `K` panics.
349
353
///
350
354
/// For simple key functions (e.g., functions that are property accesses or basic operations),
351
355
/// [`sort_by_key`](slice::sort_by_key) is likely to be faster.
@@ -364,18 +368,20 @@ impl<T> [T] {
364
368
///
365
369
/// # Panics
366
370
///
367
- /// May panic if `K: Ord` does not implement a total order.
371
+ /// May panic if the implementation of [` Ord`] for `K` does not implement a [ total order] .
368
372
///
369
373
/// # Examples
370
374
///
371
375
/// ```
372
- /// let mut v = [-5i32, 4, 32 , -3, 2];
376
+ /// let mut v = [4i32, -5, 1 , -3, 2, 10 ];
373
377
///
378
+ /// // Strings are sorted by lexicographical order.
374
379
/// v.sort_by_cached_key(|k| k.to_string());
375
- /// assert !(v == [-3, -5, 2, 32 , 4]);
380
+ /// assert_eq !(v, [-3, -5, 1, 10, 2 , 4]);
376
381
/// ```
377
382
///
378
383
/// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
384
+ /// [total order]: https://en.wikipedia.org/wiki/Total_order
379
385
#[ cfg( not( no_global_oom_handling) ) ]
380
386
#[ rustc_allow_incoherent_impl]
381
387
#[ stable( feature = "slice_sort_by_cached_key" , since = "1.34.0" ) ]
0 commit comments