162306a36Sopenharmony_ci// SPDX-License-Identifier: Apache-2.0 OR MIT 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci//! Utilities for the slice primitive type. 462306a36Sopenharmony_ci//! 562306a36Sopenharmony_ci//! *[See also the slice primitive type](slice).* 662306a36Sopenharmony_ci//! 762306a36Sopenharmony_ci//! Most of the structs in this module are iterator types which can only be created 862306a36Sopenharmony_ci//! using a certain function. For example, `slice.iter()` yields an [`Iter`]. 962306a36Sopenharmony_ci//! 1062306a36Sopenharmony_ci//! A few functions are provided to create a slice from a value reference 1162306a36Sopenharmony_ci//! or from a raw pointer. 1262306a36Sopenharmony_ci#![stable(feature = "rust1", since = "1.0.0")] 1362306a36Sopenharmony_ci// Many of the usings in this module are only used in the test configuration. 1462306a36Sopenharmony_ci// It's cleaner to just turn off the unused_imports warning than to fix them. 1562306a36Sopenharmony_ci#![cfg_attr(test, allow(unused_imports, dead_code))] 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ciuse core::borrow::{Borrow, BorrowMut}; 1862306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 1962306a36Sopenharmony_ciuse core::cmp::Ordering::{self, Less}; 2062306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 2162306a36Sopenharmony_ciuse core::mem::{self, SizedTypeProperties}; 2262306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 2362306a36Sopenharmony_ciuse core::ptr; 2462306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 2562306a36Sopenharmony_ciuse core::slice::sort; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ciuse crate::alloc::Allocator; 2862306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 2962306a36Sopenharmony_ciuse crate::alloc::{self, Global}; 3062306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 3162306a36Sopenharmony_ciuse crate::borrow::ToOwned; 3262306a36Sopenharmony_ciuse crate::boxed::Box; 3362306a36Sopenharmony_ciuse crate::vec::Vec; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#[cfg(test)] 3662306a36Sopenharmony_cimod tests; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#[unstable(feature = "slice_range", issue = "76393")] 3962306a36Sopenharmony_cipub use core::slice::range; 4062306a36Sopenharmony_ci#[unstable(feature = "array_chunks", issue = "74985")] 4162306a36Sopenharmony_cipub use core::slice::ArrayChunks; 4262306a36Sopenharmony_ci#[unstable(feature = "array_chunks", issue = "74985")] 4362306a36Sopenharmony_cipub use core::slice::ArrayChunksMut; 4462306a36Sopenharmony_ci#[unstable(feature = "array_windows", issue = "75027")] 4562306a36Sopenharmony_cipub use core::slice::ArrayWindows; 4662306a36Sopenharmony_ci#[stable(feature = "inherent_ascii_escape", since = "1.60.0")] 4762306a36Sopenharmony_cipub use core::slice::EscapeAscii; 4862306a36Sopenharmony_ci#[stable(feature = "slice_get_slice", since = "1.28.0")] 4962306a36Sopenharmony_cipub use core::slice::SliceIndex; 5062306a36Sopenharmony_ci#[stable(feature = "from_ref", since = "1.28.0")] 5162306a36Sopenharmony_cipub use core::slice::{from_mut, from_ref}; 5262306a36Sopenharmony_ci#[unstable(feature = "slice_from_ptr_range", issue = "89792")] 5362306a36Sopenharmony_cipub use core::slice::{from_mut_ptr_range, from_ptr_range}; 5462306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 5562306a36Sopenharmony_cipub use core::slice::{from_raw_parts, from_raw_parts_mut}; 5662306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 5762306a36Sopenharmony_cipub use core::slice::{Chunks, Windows}; 5862306a36Sopenharmony_ci#[stable(feature = "chunks_exact", since = "1.31.0")] 5962306a36Sopenharmony_cipub use core::slice::{ChunksExact, ChunksExactMut}; 6062306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 6162306a36Sopenharmony_cipub use core::slice::{ChunksMut, Split, SplitMut}; 6262306a36Sopenharmony_ci#[unstable(feature = "slice_group_by", issue = "80552")] 6362306a36Sopenharmony_cipub use core::slice::{GroupBy, GroupByMut}; 6462306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 6562306a36Sopenharmony_cipub use core::slice::{Iter, IterMut}; 6662306a36Sopenharmony_ci#[stable(feature = "rchunks", since = "1.31.0")] 6762306a36Sopenharmony_cipub use core::slice::{RChunks, RChunksExact, RChunksExactMut, RChunksMut}; 6862306a36Sopenharmony_ci#[stable(feature = "slice_rsplit", since = "1.27.0")] 6962306a36Sopenharmony_cipub use core::slice::{RSplit, RSplitMut}; 7062306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 7162306a36Sopenharmony_cipub use core::slice::{RSplitN, RSplitNMut, SplitN, SplitNMut}; 7262306a36Sopenharmony_ci#[stable(feature = "split_inclusive", since = "1.51.0")] 7362306a36Sopenharmony_cipub use core::slice::{SplitInclusive, SplitInclusiveMut}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 7662306a36Sopenharmony_ci// Basic slice extension methods 7762306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci// HACK(japaric) needed for the implementation of `vec!` macro during testing 8062306a36Sopenharmony_ci// N.B., see the `hack` module in this file for more details. 8162306a36Sopenharmony_ci#[cfg(test)] 8262306a36Sopenharmony_cipub use hack::into_vec; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci// HACK(japaric) needed for the implementation of `Vec::clone` during testing 8562306a36Sopenharmony_ci// N.B., see the `hack` module in this file for more details. 8662306a36Sopenharmony_ci#[cfg(test)] 8762306a36Sopenharmony_cipub use hack::to_vec; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci// HACK(japaric): With cfg(test) `impl [T]` is not available, these three 9062306a36Sopenharmony_ci// functions are actually methods that are in `impl [T]` but not in 9162306a36Sopenharmony_ci// `core::slice::SliceExt` - we need to supply these functions for the 9262306a36Sopenharmony_ci// `test_permutations` test 9362306a36Sopenharmony_cipub(crate) mod hack { 9462306a36Sopenharmony_ci use core::alloc::Allocator; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci use crate::boxed::Box; 9762306a36Sopenharmony_ci use crate::vec::Vec; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci // We shouldn't add inline attribute to this since this is used in 10062306a36Sopenharmony_ci // `vec!` macro mostly and causes perf regression. See #71204 for 10162306a36Sopenharmony_ci // discussion and perf results. 10262306a36Sopenharmony_ci pub fn into_vec<T, A: Allocator>(b: Box<[T], A>) -> Vec<T, A> { 10362306a36Sopenharmony_ci unsafe { 10462306a36Sopenharmony_ci let len = b.len(); 10562306a36Sopenharmony_ci let (b, alloc) = Box::into_raw_with_allocator(b); 10662306a36Sopenharmony_ci Vec::from_raw_parts_in(b as *mut T, len, len, alloc) 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 11162306a36Sopenharmony_ci #[inline] 11262306a36Sopenharmony_ci pub fn to_vec<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> { 11362306a36Sopenharmony_ci T::to_vec(s, alloc) 11462306a36Sopenharmony_ci } 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 11762306a36Sopenharmony_ci pub trait ConvertVec { 11862306a36Sopenharmony_ci fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> 11962306a36Sopenharmony_ci where 12062306a36Sopenharmony_ci Self: Sized; 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 12462306a36Sopenharmony_ci impl<T: Clone> ConvertVec for T { 12562306a36Sopenharmony_ci #[inline] 12662306a36Sopenharmony_ci default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> { 12762306a36Sopenharmony_ci struct DropGuard<'a, T, A: Allocator> { 12862306a36Sopenharmony_ci vec: &'a mut Vec<T, A>, 12962306a36Sopenharmony_ci num_init: usize, 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> { 13262306a36Sopenharmony_ci #[inline] 13362306a36Sopenharmony_ci fn drop(&mut self) { 13462306a36Sopenharmony_ci // SAFETY: 13562306a36Sopenharmony_ci // items were marked initialized in the loop below 13662306a36Sopenharmony_ci unsafe { 13762306a36Sopenharmony_ci self.vec.set_len(self.num_init); 13862306a36Sopenharmony_ci } 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci } 14162306a36Sopenharmony_ci let mut vec = Vec::with_capacity_in(s.len(), alloc); 14262306a36Sopenharmony_ci let mut guard = DropGuard { vec: &mut vec, num_init: 0 }; 14362306a36Sopenharmony_ci let slots = guard.vec.spare_capacity_mut(); 14462306a36Sopenharmony_ci // .take(slots.len()) is necessary for LLVM to remove bounds checks 14562306a36Sopenharmony_ci // and has better codegen than zip. 14662306a36Sopenharmony_ci for (i, b) in s.iter().enumerate().take(slots.len()) { 14762306a36Sopenharmony_ci guard.num_init = i; 14862306a36Sopenharmony_ci slots[i].write(b.clone()); 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci core::mem::forget(guard); 15162306a36Sopenharmony_ci // SAFETY: 15262306a36Sopenharmony_ci // the vec was allocated and initialized above to at least this length. 15362306a36Sopenharmony_ci unsafe { 15462306a36Sopenharmony_ci vec.set_len(s.len()); 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci vec 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 16162306a36Sopenharmony_ci impl<T: Copy> ConvertVec for T { 16262306a36Sopenharmony_ci #[inline] 16362306a36Sopenharmony_ci fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> { 16462306a36Sopenharmony_ci let mut v = Vec::with_capacity_in(s.len(), alloc); 16562306a36Sopenharmony_ci // SAFETY: 16662306a36Sopenharmony_ci // allocated above with the capacity of `s`, and initialize to `s.len()` in 16762306a36Sopenharmony_ci // ptr::copy_to_non_overlapping below. 16862306a36Sopenharmony_ci unsafe { 16962306a36Sopenharmony_ci s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); 17062306a36Sopenharmony_ci v.set_len(s.len()); 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci v 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci } 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci#[cfg(not(test))] 17862306a36Sopenharmony_ciimpl<T> [T] { 17962306a36Sopenharmony_ci /// Sorts the slice. 18062306a36Sopenharmony_ci /// 18162306a36Sopenharmony_ci /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case. 18262306a36Sopenharmony_ci /// 18362306a36Sopenharmony_ci /// When applicable, unstable sorting is preferred because it is generally faster than stable 18462306a36Sopenharmony_ci /// sorting and it doesn't allocate auxiliary memory. 18562306a36Sopenharmony_ci /// See [`sort_unstable`](slice::sort_unstable). 18662306a36Sopenharmony_ci /// 18762306a36Sopenharmony_ci /// # Current implementation 18862306a36Sopenharmony_ci /// 18962306a36Sopenharmony_ci /// The current algorithm is an adaptive, iterative merge sort inspired by 19062306a36Sopenharmony_ci /// [timsort](https://en.wikipedia.org/wiki/Timsort). 19162306a36Sopenharmony_ci /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 19262306a36Sopenharmony_ci /// two or more sorted sequences concatenated one after another. 19362306a36Sopenharmony_ci /// 19462306a36Sopenharmony_ci /// Also, it allocates temporary storage half the size of `self`, but for short slices a 19562306a36Sopenharmony_ci /// non-allocating insertion sort is used instead. 19662306a36Sopenharmony_ci /// 19762306a36Sopenharmony_ci /// # Examples 19862306a36Sopenharmony_ci /// 19962306a36Sopenharmony_ci /// ``` 20062306a36Sopenharmony_ci /// let mut v = [-5, 4, 1, -3, 2]; 20162306a36Sopenharmony_ci /// 20262306a36Sopenharmony_ci /// v.sort(); 20362306a36Sopenharmony_ci /// assert!(v == [-5, -3, 1, 2, 4]); 20462306a36Sopenharmony_ci /// ``` 20562306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 20662306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 20762306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 20862306a36Sopenharmony_ci #[inline] 20962306a36Sopenharmony_ci pub fn sort(&mut self) 21062306a36Sopenharmony_ci where 21162306a36Sopenharmony_ci T: Ord, 21262306a36Sopenharmony_ci { 21362306a36Sopenharmony_ci stable_sort(self, T::lt); 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /// Sorts the slice with a comparator function. 21762306a36Sopenharmony_ci /// 21862306a36Sopenharmony_ci /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case. 21962306a36Sopenharmony_ci /// 22062306a36Sopenharmony_ci /// The comparator function must define a total ordering for the elements in the slice. If 22162306a36Sopenharmony_ci /// the ordering is not total, the order of the elements is unspecified. An order is a 22262306a36Sopenharmony_ci /// total order if it is (for all `a`, `b` and `c`): 22362306a36Sopenharmony_ci /// 22462306a36Sopenharmony_ci /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and 22562306a36Sopenharmony_ci /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. 22662306a36Sopenharmony_ci /// 22762306a36Sopenharmony_ci /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use 22862306a36Sopenharmony_ci /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. 22962306a36Sopenharmony_ci /// 23062306a36Sopenharmony_ci /// ``` 23162306a36Sopenharmony_ci /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; 23262306a36Sopenharmony_ci /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); 23362306a36Sopenharmony_ci /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); 23462306a36Sopenharmony_ci /// ``` 23562306a36Sopenharmony_ci /// 23662306a36Sopenharmony_ci /// When applicable, unstable sorting is preferred because it is generally faster than stable 23762306a36Sopenharmony_ci /// sorting and it doesn't allocate auxiliary memory. 23862306a36Sopenharmony_ci /// See [`sort_unstable_by`](slice::sort_unstable_by). 23962306a36Sopenharmony_ci /// 24062306a36Sopenharmony_ci /// # Current implementation 24162306a36Sopenharmony_ci /// 24262306a36Sopenharmony_ci /// The current algorithm is an adaptive, iterative merge sort inspired by 24362306a36Sopenharmony_ci /// [timsort](https://en.wikipedia.org/wiki/Timsort). 24462306a36Sopenharmony_ci /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 24562306a36Sopenharmony_ci /// two or more sorted sequences concatenated one after another. 24662306a36Sopenharmony_ci /// 24762306a36Sopenharmony_ci /// Also, it allocates temporary storage half the size of `self`, but for short slices a 24862306a36Sopenharmony_ci /// non-allocating insertion sort is used instead. 24962306a36Sopenharmony_ci /// 25062306a36Sopenharmony_ci /// # Examples 25162306a36Sopenharmony_ci /// 25262306a36Sopenharmony_ci /// ``` 25362306a36Sopenharmony_ci /// let mut v = [5, 4, 1, 3, 2]; 25462306a36Sopenharmony_ci /// v.sort_by(|a, b| a.cmp(b)); 25562306a36Sopenharmony_ci /// assert!(v == [1, 2, 3, 4, 5]); 25662306a36Sopenharmony_ci /// 25762306a36Sopenharmony_ci /// // reverse sorting 25862306a36Sopenharmony_ci /// v.sort_by(|a, b| b.cmp(a)); 25962306a36Sopenharmony_ci /// assert!(v == [5, 4, 3, 2, 1]); 26062306a36Sopenharmony_ci /// ``` 26162306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 26262306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 26362306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 26462306a36Sopenharmony_ci #[inline] 26562306a36Sopenharmony_ci pub fn sort_by<F>(&mut self, mut compare: F) 26662306a36Sopenharmony_ci where 26762306a36Sopenharmony_ci F: FnMut(&T, &T) -> Ordering, 26862306a36Sopenharmony_ci { 26962306a36Sopenharmony_ci stable_sort(self, |a, b| compare(a, b) == Less); 27062306a36Sopenharmony_ci } 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci /// Sorts the slice with a key extraction function. 27362306a36Sopenharmony_ci /// 27462306a36Sopenharmony_ci /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*)) 27562306a36Sopenharmony_ci /// worst-case, where the key function is *O*(*m*). 27662306a36Sopenharmony_ci /// 27762306a36Sopenharmony_ci /// For expensive key functions (e.g. functions that are not simple property accesses or 27862306a36Sopenharmony_ci /// basic operations), [`sort_by_cached_key`](slice::sort_by_cached_key) is likely to be 27962306a36Sopenharmony_ci /// significantly faster, as it does not recompute element keys. 28062306a36Sopenharmony_ci /// 28162306a36Sopenharmony_ci /// When applicable, unstable sorting is preferred because it is generally faster than stable 28262306a36Sopenharmony_ci /// sorting and it doesn't allocate auxiliary memory. 28362306a36Sopenharmony_ci /// See [`sort_unstable_by_key`](slice::sort_unstable_by_key). 28462306a36Sopenharmony_ci /// 28562306a36Sopenharmony_ci /// # Current implementation 28662306a36Sopenharmony_ci /// 28762306a36Sopenharmony_ci /// The current algorithm is an adaptive, iterative merge sort inspired by 28862306a36Sopenharmony_ci /// [timsort](https://en.wikipedia.org/wiki/Timsort). 28962306a36Sopenharmony_ci /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 29062306a36Sopenharmony_ci /// two or more sorted sequences concatenated one after another. 29162306a36Sopenharmony_ci /// 29262306a36Sopenharmony_ci /// Also, it allocates temporary storage half the size of `self`, but for short slices a 29362306a36Sopenharmony_ci /// non-allocating insertion sort is used instead. 29462306a36Sopenharmony_ci /// 29562306a36Sopenharmony_ci /// # Examples 29662306a36Sopenharmony_ci /// 29762306a36Sopenharmony_ci /// ``` 29862306a36Sopenharmony_ci /// let mut v = [-5i32, 4, 1, -3, 2]; 29962306a36Sopenharmony_ci /// 30062306a36Sopenharmony_ci /// v.sort_by_key(|k| k.abs()); 30162306a36Sopenharmony_ci /// assert!(v == [1, 2, -3, 4, -5]); 30262306a36Sopenharmony_ci /// ``` 30362306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 30462306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 30562306a36Sopenharmony_ci #[stable(feature = "slice_sort_by_key", since = "1.7.0")] 30662306a36Sopenharmony_ci #[inline] 30762306a36Sopenharmony_ci pub fn sort_by_key<K, F>(&mut self, mut f: F) 30862306a36Sopenharmony_ci where 30962306a36Sopenharmony_ci F: FnMut(&T) -> K, 31062306a36Sopenharmony_ci K: Ord, 31162306a36Sopenharmony_ci { 31262306a36Sopenharmony_ci stable_sort(self, |a, b| f(a).lt(&f(b))); 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /// Sorts the slice with a key extraction function. 31662306a36Sopenharmony_ci /// 31762306a36Sopenharmony_ci /// During sorting, the key function is called at most once per element, by using 31862306a36Sopenharmony_ci /// temporary storage to remember the results of key evaluation. 31962306a36Sopenharmony_ci /// The order of calls to the key function is unspecified and may change in future versions 32062306a36Sopenharmony_ci /// of the standard library. 32162306a36Sopenharmony_ci /// 32262306a36Sopenharmony_ci /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* + *n* \* log(*n*)) 32362306a36Sopenharmony_ci /// worst-case, where the key function is *O*(*m*). 32462306a36Sopenharmony_ci /// 32562306a36Sopenharmony_ci /// For simple key functions (e.g., functions that are property accesses or 32662306a36Sopenharmony_ci /// basic operations), [`sort_by_key`](slice::sort_by_key) is likely to be 32762306a36Sopenharmony_ci /// faster. 32862306a36Sopenharmony_ci /// 32962306a36Sopenharmony_ci /// # Current implementation 33062306a36Sopenharmony_ci /// 33162306a36Sopenharmony_ci /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, 33262306a36Sopenharmony_ci /// which combines the fast average case of randomized quicksort with the fast worst case of 33362306a36Sopenharmony_ci /// heapsort, while achieving linear time on slices with certain patterns. It uses some 33462306a36Sopenharmony_ci /// randomization to avoid degenerate cases, but with a fixed seed to always provide 33562306a36Sopenharmony_ci /// deterministic behavior. 33662306a36Sopenharmony_ci /// 33762306a36Sopenharmony_ci /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the 33862306a36Sopenharmony_ci /// length of the slice. 33962306a36Sopenharmony_ci /// 34062306a36Sopenharmony_ci /// # Examples 34162306a36Sopenharmony_ci /// 34262306a36Sopenharmony_ci /// ``` 34362306a36Sopenharmony_ci /// let mut v = [-5i32, 4, 32, -3, 2]; 34462306a36Sopenharmony_ci /// 34562306a36Sopenharmony_ci /// v.sort_by_cached_key(|k| k.to_string()); 34662306a36Sopenharmony_ci /// assert!(v == [-3, -5, 2, 32, 4]); 34762306a36Sopenharmony_ci /// ``` 34862306a36Sopenharmony_ci /// 34962306a36Sopenharmony_ci /// [pdqsort]: https://github.com/orlp/pdqsort 35062306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 35162306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 35262306a36Sopenharmony_ci #[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")] 35362306a36Sopenharmony_ci #[inline] 35462306a36Sopenharmony_ci pub fn sort_by_cached_key<K, F>(&mut self, f: F) 35562306a36Sopenharmony_ci where 35662306a36Sopenharmony_ci F: FnMut(&T) -> K, 35762306a36Sopenharmony_ci K: Ord, 35862306a36Sopenharmony_ci { 35962306a36Sopenharmony_ci // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. 36062306a36Sopenharmony_ci macro_rules! sort_by_key { 36162306a36Sopenharmony_ci ($t:ty, $slice:ident, $f:ident) => {{ 36262306a36Sopenharmony_ci let mut indices: Vec<_> = 36362306a36Sopenharmony_ci $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect(); 36462306a36Sopenharmony_ci // The elements of `indices` are unique, as they are indexed, so any sort will be 36562306a36Sopenharmony_ci // stable with respect to the original slice. We use `sort_unstable` here because 36662306a36Sopenharmony_ci // it requires less memory allocation. 36762306a36Sopenharmony_ci indices.sort_unstable(); 36862306a36Sopenharmony_ci for i in 0..$slice.len() { 36962306a36Sopenharmony_ci let mut index = indices[i].1; 37062306a36Sopenharmony_ci while (index as usize) < i { 37162306a36Sopenharmony_ci index = indices[index as usize].1; 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci indices[i].1 = index; 37462306a36Sopenharmony_ci $slice.swap(i, index as usize); 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci }}; 37762306a36Sopenharmony_ci } 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci let sz_u8 = mem::size_of::<(K, u8)>(); 38062306a36Sopenharmony_ci let sz_u16 = mem::size_of::<(K, u16)>(); 38162306a36Sopenharmony_ci let sz_u32 = mem::size_of::<(K, u32)>(); 38262306a36Sopenharmony_ci let sz_usize = mem::size_of::<(K, usize)>(); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci let len = self.len(); 38562306a36Sopenharmony_ci if len < 2 { 38662306a36Sopenharmony_ci return; 38762306a36Sopenharmony_ci } 38862306a36Sopenharmony_ci if sz_u8 < sz_u16 && len <= (u8::MAX as usize) { 38962306a36Sopenharmony_ci return sort_by_key!(u8, self, f); 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { 39262306a36Sopenharmony_ci return sort_by_key!(u16, self, f); 39362306a36Sopenharmony_ci } 39462306a36Sopenharmony_ci if sz_u32 < sz_usize && len <= (u32::MAX as usize) { 39562306a36Sopenharmony_ci return sort_by_key!(u32, self, f); 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci sort_by_key!(usize, self, f) 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci /// Copies `self` into a new `Vec`. 40162306a36Sopenharmony_ci /// 40262306a36Sopenharmony_ci /// # Examples 40362306a36Sopenharmony_ci /// 40462306a36Sopenharmony_ci /// ``` 40562306a36Sopenharmony_ci /// let s = [10, 40, 30]; 40662306a36Sopenharmony_ci /// let x = s.to_vec(); 40762306a36Sopenharmony_ci /// // Here, `s` and `x` can be modified independently. 40862306a36Sopenharmony_ci /// ``` 40962306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 41062306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 41162306a36Sopenharmony_ci #[rustc_conversion_suggestion] 41262306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 41362306a36Sopenharmony_ci #[inline] 41462306a36Sopenharmony_ci pub fn to_vec(&self) -> Vec<T> 41562306a36Sopenharmony_ci where 41662306a36Sopenharmony_ci T: Clone, 41762306a36Sopenharmony_ci { 41862306a36Sopenharmony_ci self.to_vec_in(Global) 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci /// Copies `self` into a new `Vec` with an allocator. 42262306a36Sopenharmony_ci /// 42362306a36Sopenharmony_ci /// # Examples 42462306a36Sopenharmony_ci /// 42562306a36Sopenharmony_ci /// ``` 42662306a36Sopenharmony_ci /// #![feature(allocator_api)] 42762306a36Sopenharmony_ci /// 42862306a36Sopenharmony_ci /// use std::alloc::System; 42962306a36Sopenharmony_ci /// 43062306a36Sopenharmony_ci /// let s = [10, 40, 30]; 43162306a36Sopenharmony_ci /// let x = s.to_vec_in(System); 43262306a36Sopenharmony_ci /// // Here, `s` and `x` can be modified independently. 43362306a36Sopenharmony_ci /// ``` 43462306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 43562306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 43662306a36Sopenharmony_ci #[inline] 43762306a36Sopenharmony_ci #[unstable(feature = "allocator_api", issue = "32838")] 43862306a36Sopenharmony_ci pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A> 43962306a36Sopenharmony_ci where 44062306a36Sopenharmony_ci T: Clone, 44162306a36Sopenharmony_ci { 44262306a36Sopenharmony_ci // N.B., see the `hack` module in this file for more details. 44362306a36Sopenharmony_ci hack::to_vec(self, alloc) 44462306a36Sopenharmony_ci } 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci /// Converts `self` into a vector without clones or allocation. 44762306a36Sopenharmony_ci /// 44862306a36Sopenharmony_ci /// The resulting vector can be converted back into a box via 44962306a36Sopenharmony_ci /// `Vec<T>`'s `into_boxed_slice` method. 45062306a36Sopenharmony_ci /// 45162306a36Sopenharmony_ci /// # Examples 45262306a36Sopenharmony_ci /// 45362306a36Sopenharmony_ci /// ``` 45462306a36Sopenharmony_ci /// let s: Box<[i32]> = Box::new([10, 40, 30]); 45562306a36Sopenharmony_ci /// let x = s.into_vec(); 45662306a36Sopenharmony_ci /// // `s` cannot be used anymore because it has been converted into `x`. 45762306a36Sopenharmony_ci /// 45862306a36Sopenharmony_ci /// assert_eq!(x, vec![10, 40, 30]); 45962306a36Sopenharmony_ci /// ``` 46062306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 46162306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 46262306a36Sopenharmony_ci #[inline] 46362306a36Sopenharmony_ci pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { 46462306a36Sopenharmony_ci // N.B., see the `hack` module in this file for more details. 46562306a36Sopenharmony_ci hack::into_vec(self) 46662306a36Sopenharmony_ci } 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /// Creates a vector by copying a slice `n` times. 46962306a36Sopenharmony_ci /// 47062306a36Sopenharmony_ci /// # Panics 47162306a36Sopenharmony_ci /// 47262306a36Sopenharmony_ci /// This function will panic if the capacity would overflow. 47362306a36Sopenharmony_ci /// 47462306a36Sopenharmony_ci /// # Examples 47562306a36Sopenharmony_ci /// 47662306a36Sopenharmony_ci /// Basic usage: 47762306a36Sopenharmony_ci /// 47862306a36Sopenharmony_ci /// ``` 47962306a36Sopenharmony_ci /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]); 48062306a36Sopenharmony_ci /// ``` 48162306a36Sopenharmony_ci /// 48262306a36Sopenharmony_ci /// A panic upon overflow: 48362306a36Sopenharmony_ci /// 48462306a36Sopenharmony_ci /// ```should_panic 48562306a36Sopenharmony_ci /// // this will panic at runtime 48662306a36Sopenharmony_ci /// b"0123456789abcdef".repeat(usize::MAX); 48762306a36Sopenharmony_ci /// ``` 48862306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 48962306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 49062306a36Sopenharmony_ci #[stable(feature = "repeat_generic_slice", since = "1.40.0")] 49162306a36Sopenharmony_ci pub fn repeat(&self, n: usize) -> Vec<T> 49262306a36Sopenharmony_ci where 49362306a36Sopenharmony_ci T: Copy, 49462306a36Sopenharmony_ci { 49562306a36Sopenharmony_ci if n == 0 { 49662306a36Sopenharmony_ci return Vec::new(); 49762306a36Sopenharmony_ci } 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci // If `n` is larger than zero, it can be split as 50062306a36Sopenharmony_ci // `n = 2^expn + rem (2^expn > rem, expn >= 0, rem >= 0)`. 50162306a36Sopenharmony_ci // `2^expn` is the number represented by the leftmost '1' bit of `n`, 50262306a36Sopenharmony_ci // and `rem` is the remaining part of `n`. 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci // Using `Vec` to access `set_len()`. 50562306a36Sopenharmony_ci let capacity = self.len().checked_mul(n).expect("capacity overflow"); 50662306a36Sopenharmony_ci let mut buf = Vec::with_capacity(capacity); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci // `2^expn` repetition is done by doubling `buf` `expn`-times. 50962306a36Sopenharmony_ci buf.extend(self); 51062306a36Sopenharmony_ci { 51162306a36Sopenharmony_ci let mut m = n >> 1; 51262306a36Sopenharmony_ci // If `m > 0`, there are remaining bits up to the leftmost '1'. 51362306a36Sopenharmony_ci while m > 0 { 51462306a36Sopenharmony_ci // `buf.extend(buf)`: 51562306a36Sopenharmony_ci unsafe { 51662306a36Sopenharmony_ci ptr::copy_nonoverlapping( 51762306a36Sopenharmony_ci buf.as_ptr(), 51862306a36Sopenharmony_ci (buf.as_mut_ptr() as *mut T).add(buf.len()), 51962306a36Sopenharmony_ci buf.len(), 52062306a36Sopenharmony_ci ); 52162306a36Sopenharmony_ci // `buf` has capacity of `self.len() * n`. 52262306a36Sopenharmony_ci let buf_len = buf.len(); 52362306a36Sopenharmony_ci buf.set_len(buf_len * 2); 52462306a36Sopenharmony_ci } 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci m >>= 1; 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci } 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci // `rem` (`= n - 2^expn`) repetition is done by copying 53162306a36Sopenharmony_ci // first `rem` repetitions from `buf` itself. 53262306a36Sopenharmony_ci let rem_len = capacity - buf.len(); // `self.len() * rem` 53362306a36Sopenharmony_ci if rem_len > 0 { 53462306a36Sopenharmony_ci // `buf.extend(buf[0 .. rem_len])`: 53562306a36Sopenharmony_ci unsafe { 53662306a36Sopenharmony_ci // This is non-overlapping since `2^expn > rem`. 53762306a36Sopenharmony_ci ptr::copy_nonoverlapping( 53862306a36Sopenharmony_ci buf.as_ptr(), 53962306a36Sopenharmony_ci (buf.as_mut_ptr() as *mut T).add(buf.len()), 54062306a36Sopenharmony_ci rem_len, 54162306a36Sopenharmony_ci ); 54262306a36Sopenharmony_ci // `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`). 54362306a36Sopenharmony_ci buf.set_len(capacity); 54462306a36Sopenharmony_ci } 54562306a36Sopenharmony_ci } 54662306a36Sopenharmony_ci buf 54762306a36Sopenharmony_ci } 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci /// Flattens a slice of `T` into a single value `Self::Output`. 55062306a36Sopenharmony_ci /// 55162306a36Sopenharmony_ci /// # Examples 55262306a36Sopenharmony_ci /// 55362306a36Sopenharmony_ci /// ``` 55462306a36Sopenharmony_ci /// assert_eq!(["hello", "world"].concat(), "helloworld"); 55562306a36Sopenharmony_ci /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); 55662306a36Sopenharmony_ci /// ``` 55762306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 55862306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 55962306a36Sopenharmony_ci pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output 56062306a36Sopenharmony_ci where 56162306a36Sopenharmony_ci Self: Concat<Item>, 56262306a36Sopenharmony_ci { 56362306a36Sopenharmony_ci Concat::concat(self) 56462306a36Sopenharmony_ci } 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci /// Flattens a slice of `T` into a single value `Self::Output`, placing a 56762306a36Sopenharmony_ci /// given separator between each. 56862306a36Sopenharmony_ci /// 56962306a36Sopenharmony_ci /// # Examples 57062306a36Sopenharmony_ci /// 57162306a36Sopenharmony_ci /// ``` 57262306a36Sopenharmony_ci /// assert_eq!(["hello", "world"].join(" "), "hello world"); 57362306a36Sopenharmony_ci /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); 57462306a36Sopenharmony_ci /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]); 57562306a36Sopenharmony_ci /// ``` 57662306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 57762306a36Sopenharmony_ci #[stable(feature = "rename_connect_to_join", since = "1.3.0")] 57862306a36Sopenharmony_ci pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output 57962306a36Sopenharmony_ci where 58062306a36Sopenharmony_ci Self: Join<Separator>, 58162306a36Sopenharmony_ci { 58262306a36Sopenharmony_ci Join::join(self, sep) 58362306a36Sopenharmony_ci } 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci /// Flattens a slice of `T` into a single value `Self::Output`, placing a 58662306a36Sopenharmony_ci /// given separator between each. 58762306a36Sopenharmony_ci /// 58862306a36Sopenharmony_ci /// # Examples 58962306a36Sopenharmony_ci /// 59062306a36Sopenharmony_ci /// ``` 59162306a36Sopenharmony_ci /// # #![allow(deprecated)] 59262306a36Sopenharmony_ci /// assert_eq!(["hello", "world"].connect(" "), "hello world"); 59362306a36Sopenharmony_ci /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); 59462306a36Sopenharmony_ci /// ``` 59562306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 59662306a36Sopenharmony_ci #[stable(feature = "rust1", since = "1.0.0")] 59762306a36Sopenharmony_ci #[deprecated(since = "1.3.0", note = "renamed to join")] 59862306a36Sopenharmony_ci pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output 59962306a36Sopenharmony_ci where 60062306a36Sopenharmony_ci Self: Join<Separator>, 60162306a36Sopenharmony_ci { 60262306a36Sopenharmony_ci Join::join(self, sep) 60362306a36Sopenharmony_ci } 60462306a36Sopenharmony_ci} 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci#[cfg(not(test))] 60762306a36Sopenharmony_ciimpl [u8] { 60862306a36Sopenharmony_ci /// Returns a vector containing a copy of this slice where each byte 60962306a36Sopenharmony_ci /// is mapped to its ASCII upper case equivalent. 61062306a36Sopenharmony_ci /// 61162306a36Sopenharmony_ci /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', 61262306a36Sopenharmony_ci /// but non-ASCII letters are unchanged. 61362306a36Sopenharmony_ci /// 61462306a36Sopenharmony_ci /// To uppercase the value in-place, use [`make_ascii_uppercase`]. 61562306a36Sopenharmony_ci /// 61662306a36Sopenharmony_ci /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase 61762306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 61862306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 61962306a36Sopenharmony_ci #[must_use = "this returns the uppercase bytes as a new Vec, \ 62062306a36Sopenharmony_ci without modifying the original"] 62162306a36Sopenharmony_ci #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] 62262306a36Sopenharmony_ci #[inline] 62362306a36Sopenharmony_ci pub fn to_ascii_uppercase(&self) -> Vec<u8> { 62462306a36Sopenharmony_ci let mut me = self.to_vec(); 62562306a36Sopenharmony_ci me.make_ascii_uppercase(); 62662306a36Sopenharmony_ci me 62762306a36Sopenharmony_ci } 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci /// Returns a vector containing a copy of this slice where each byte 63062306a36Sopenharmony_ci /// is mapped to its ASCII lower case equivalent. 63162306a36Sopenharmony_ci /// 63262306a36Sopenharmony_ci /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', 63362306a36Sopenharmony_ci /// but non-ASCII letters are unchanged. 63462306a36Sopenharmony_ci /// 63562306a36Sopenharmony_ci /// To lowercase the value in-place, use [`make_ascii_lowercase`]. 63662306a36Sopenharmony_ci /// 63762306a36Sopenharmony_ci /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase 63862306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 63962306a36Sopenharmony_ci #[rustc_allow_incoherent_impl] 64062306a36Sopenharmony_ci #[must_use = "this returns the lowercase bytes as a new Vec, \ 64162306a36Sopenharmony_ci without modifying the original"] 64262306a36Sopenharmony_ci #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] 64362306a36Sopenharmony_ci #[inline] 64462306a36Sopenharmony_ci pub fn to_ascii_lowercase(&self) -> Vec<u8> { 64562306a36Sopenharmony_ci let mut me = self.to_vec(); 64662306a36Sopenharmony_ci me.make_ascii_lowercase(); 64762306a36Sopenharmony_ci me 64862306a36Sopenharmony_ci } 64962306a36Sopenharmony_ci} 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 65262306a36Sopenharmony_ci// Extension traits for slices over specific kinds of data 65362306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci/// Helper trait for [`[T]::concat`](slice::concat). 65662306a36Sopenharmony_ci/// 65762306a36Sopenharmony_ci/// Note: the `Item` type parameter is not used in this trait, 65862306a36Sopenharmony_ci/// but it allows impls to be more generic. 65962306a36Sopenharmony_ci/// Without it, we get this error: 66062306a36Sopenharmony_ci/// 66162306a36Sopenharmony_ci/// ```error 66262306a36Sopenharmony_ci/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica 66362306a36Sopenharmony_ci/// --> library/alloc/src/slice.rs:608:6 66462306a36Sopenharmony_ci/// | 66562306a36Sopenharmony_ci/// 608 | impl<T: Clone, V: Borrow<[T]>> Concat for [V] { 66662306a36Sopenharmony_ci/// | ^ unconstrained type parameter 66762306a36Sopenharmony_ci/// ``` 66862306a36Sopenharmony_ci/// 66962306a36Sopenharmony_ci/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls, 67062306a36Sopenharmony_ci/// such that multiple `T` types would apply: 67162306a36Sopenharmony_ci/// 67262306a36Sopenharmony_ci/// ``` 67362306a36Sopenharmony_ci/// # #[allow(dead_code)] 67462306a36Sopenharmony_ci/// pub struct Foo(Vec<u32>, Vec<String>); 67562306a36Sopenharmony_ci/// 67662306a36Sopenharmony_ci/// impl std::borrow::Borrow<[u32]> for Foo { 67762306a36Sopenharmony_ci/// fn borrow(&self) -> &[u32] { &self.0 } 67862306a36Sopenharmony_ci/// } 67962306a36Sopenharmony_ci/// 68062306a36Sopenharmony_ci/// impl std::borrow::Borrow<[String]> for Foo { 68162306a36Sopenharmony_ci/// fn borrow(&self) -> &[String] { &self.1 } 68262306a36Sopenharmony_ci/// } 68362306a36Sopenharmony_ci/// ``` 68462306a36Sopenharmony_ci#[unstable(feature = "slice_concat_trait", issue = "27747")] 68562306a36Sopenharmony_cipub trait Concat<Item: ?Sized> { 68662306a36Sopenharmony_ci #[unstable(feature = "slice_concat_trait", issue = "27747")] 68762306a36Sopenharmony_ci /// The resulting type after concatenation 68862306a36Sopenharmony_ci type Output; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci /// Implementation of [`[T]::concat`](slice::concat) 69162306a36Sopenharmony_ci #[unstable(feature = "slice_concat_trait", issue = "27747")] 69262306a36Sopenharmony_ci fn concat(slice: &Self) -> Self::Output; 69362306a36Sopenharmony_ci} 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci/// Helper trait for [`[T]::join`](slice::join) 69662306a36Sopenharmony_ci#[unstable(feature = "slice_concat_trait", issue = "27747")] 69762306a36Sopenharmony_cipub trait Join<Separator> { 69862306a36Sopenharmony_ci #[unstable(feature = "slice_concat_trait", issue = "27747")] 69962306a36Sopenharmony_ci /// The resulting type after concatenation 70062306a36Sopenharmony_ci type Output; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci /// Implementation of [`[T]::join`](slice::join) 70362306a36Sopenharmony_ci #[unstable(feature = "slice_concat_trait", issue = "27747")] 70462306a36Sopenharmony_ci fn join(slice: &Self, sep: Separator) -> Self::Output; 70562306a36Sopenharmony_ci} 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 70862306a36Sopenharmony_ci#[unstable(feature = "slice_concat_ext", issue = "27747")] 70962306a36Sopenharmony_ciimpl<T: Clone, V: Borrow<[T]>> Concat<T> for [V] { 71062306a36Sopenharmony_ci type Output = Vec<T>; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci fn concat(slice: &Self) -> Vec<T> { 71362306a36Sopenharmony_ci let size = slice.iter().map(|slice| slice.borrow().len()).sum(); 71462306a36Sopenharmony_ci let mut result = Vec::with_capacity(size); 71562306a36Sopenharmony_ci for v in slice { 71662306a36Sopenharmony_ci result.extend_from_slice(v.borrow()) 71762306a36Sopenharmony_ci } 71862306a36Sopenharmony_ci result 71962306a36Sopenharmony_ci } 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 72362306a36Sopenharmony_ci#[unstable(feature = "slice_concat_ext", issue = "27747")] 72462306a36Sopenharmony_ciimpl<T: Clone, V: Borrow<[T]>> Join<&T> for [V] { 72562306a36Sopenharmony_ci type Output = Vec<T>; 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci fn join(slice: &Self, sep: &T) -> Vec<T> { 72862306a36Sopenharmony_ci let mut iter = slice.iter(); 72962306a36Sopenharmony_ci let first = match iter.next() { 73062306a36Sopenharmony_ci Some(first) => first, 73162306a36Sopenharmony_ci None => return vec![], 73262306a36Sopenharmony_ci }; 73362306a36Sopenharmony_ci let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() + slice.len() - 1; 73462306a36Sopenharmony_ci let mut result = Vec::with_capacity(size); 73562306a36Sopenharmony_ci result.extend_from_slice(first.borrow()); 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci for v in iter { 73862306a36Sopenharmony_ci result.push(sep.clone()); 73962306a36Sopenharmony_ci result.extend_from_slice(v.borrow()) 74062306a36Sopenharmony_ci } 74162306a36Sopenharmony_ci result 74262306a36Sopenharmony_ci } 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 74662306a36Sopenharmony_ci#[unstable(feature = "slice_concat_ext", issue = "27747")] 74762306a36Sopenharmony_ciimpl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] { 74862306a36Sopenharmony_ci type Output = Vec<T>; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci fn join(slice: &Self, sep: &[T]) -> Vec<T> { 75162306a36Sopenharmony_ci let mut iter = slice.iter(); 75262306a36Sopenharmony_ci let first = match iter.next() { 75362306a36Sopenharmony_ci Some(first) => first, 75462306a36Sopenharmony_ci None => return vec![], 75562306a36Sopenharmony_ci }; 75662306a36Sopenharmony_ci let size = 75762306a36Sopenharmony_ci slice.iter().map(|v| v.borrow().len()).sum::<usize>() + sep.len() * (slice.len() - 1); 75862306a36Sopenharmony_ci let mut result = Vec::with_capacity(size); 75962306a36Sopenharmony_ci result.extend_from_slice(first.borrow()); 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci for v in iter { 76262306a36Sopenharmony_ci result.extend_from_slice(sep); 76362306a36Sopenharmony_ci result.extend_from_slice(v.borrow()) 76462306a36Sopenharmony_ci } 76562306a36Sopenharmony_ci result 76662306a36Sopenharmony_ci } 76762306a36Sopenharmony_ci} 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 77062306a36Sopenharmony_ci// Standard trait implementations for slices 77162306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 77462306a36Sopenharmony_ciimpl<T, A: Allocator> Borrow<[T]> for Vec<T, A> { 77562306a36Sopenharmony_ci fn borrow(&self) -> &[T] { 77662306a36Sopenharmony_ci &self[..] 77762306a36Sopenharmony_ci } 77862306a36Sopenharmony_ci} 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 78162306a36Sopenharmony_ciimpl<T, A: Allocator> BorrowMut<[T]> for Vec<T, A> { 78262306a36Sopenharmony_ci fn borrow_mut(&mut self) -> &mut [T] { 78362306a36Sopenharmony_ci &mut self[..] 78462306a36Sopenharmony_ci } 78562306a36Sopenharmony_ci} 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci// Specializable trait for implementing ToOwned::clone_into. This is 78862306a36Sopenharmony_ci// public in the crate and has the Allocator parameter so that 78962306a36Sopenharmony_ci// vec::clone_from use it too. 79062306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 79162306a36Sopenharmony_cipub(crate) trait SpecCloneIntoVec<T, A: Allocator> { 79262306a36Sopenharmony_ci fn clone_into(&self, target: &mut Vec<T, A>); 79362306a36Sopenharmony_ci} 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 79662306a36Sopenharmony_ciimpl<T: Clone, A: Allocator> SpecCloneIntoVec<T, A> for [T] { 79762306a36Sopenharmony_ci default fn clone_into(&self, target: &mut Vec<T, A>) { 79862306a36Sopenharmony_ci // drop anything in target that will not be overwritten 79962306a36Sopenharmony_ci target.truncate(self.len()); 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci // target.len <= self.len due to the truncate above, so the 80262306a36Sopenharmony_ci // slices here are always in-bounds. 80362306a36Sopenharmony_ci let (init, tail) = self.split_at(target.len()); 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci // reuse the contained values' allocations/resources. 80662306a36Sopenharmony_ci target.clone_from_slice(init); 80762306a36Sopenharmony_ci target.extend_from_slice(tail); 80862306a36Sopenharmony_ci } 80962306a36Sopenharmony_ci} 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 81262306a36Sopenharmony_ciimpl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] { 81362306a36Sopenharmony_ci fn clone_into(&self, target: &mut Vec<T, A>) { 81462306a36Sopenharmony_ci target.clear(); 81562306a36Sopenharmony_ci target.extend_from_slice(self); 81662306a36Sopenharmony_ci } 81762306a36Sopenharmony_ci} 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 82062306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 82162306a36Sopenharmony_ciimpl<T: Clone> ToOwned for [T] { 82262306a36Sopenharmony_ci type Owned = Vec<T>; 82362306a36Sopenharmony_ci #[cfg(not(test))] 82462306a36Sopenharmony_ci fn to_owned(&self) -> Vec<T> { 82562306a36Sopenharmony_ci self.to_vec() 82662306a36Sopenharmony_ci } 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci #[cfg(test)] 82962306a36Sopenharmony_ci fn to_owned(&self) -> Vec<T> { 83062306a36Sopenharmony_ci hack::to_vec(self, Global) 83162306a36Sopenharmony_ci } 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci fn clone_into(&self, target: &mut Vec<T>) { 83462306a36Sopenharmony_ci SpecCloneIntoVec::clone_into(self, target); 83562306a36Sopenharmony_ci } 83662306a36Sopenharmony_ci} 83762306a36Sopenharmony_ci 83862306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 83962306a36Sopenharmony_ci// Sorting 84062306a36Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci#[inline] 84362306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 84462306a36Sopenharmony_cifn stable_sort<T, F>(v: &mut [T], mut is_less: F) 84562306a36Sopenharmony_ciwhere 84662306a36Sopenharmony_ci F: FnMut(&T, &T) -> bool, 84762306a36Sopenharmony_ci{ 84862306a36Sopenharmony_ci if T::IS_ZST { 84962306a36Sopenharmony_ci // Sorting has no meaningful behavior on zero-sized types. Do nothing. 85062306a36Sopenharmony_ci return; 85162306a36Sopenharmony_ci } 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci let elem_alloc_fn = |len: usize| -> *mut T { 85462306a36Sopenharmony_ci // SAFETY: Creating the layout is safe as long as merge_sort never calls this with len > 85562306a36Sopenharmony_ci // v.len(). Alloc in general will only be used as 'shadow-region' to store temporary swap 85662306a36Sopenharmony_ci // elements. 85762306a36Sopenharmony_ci unsafe { alloc::alloc(alloc::Layout::array::<T>(len).unwrap_unchecked()) as *mut T } 85862306a36Sopenharmony_ci }; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci let elem_dealloc_fn = |buf_ptr: *mut T, len: usize| { 86162306a36Sopenharmony_ci // SAFETY: Creating the layout is safe as long as merge_sort never calls this with len > 86262306a36Sopenharmony_ci // v.len(). The caller must ensure that buf_ptr was created by elem_alloc_fn with the same 86362306a36Sopenharmony_ci // len. 86462306a36Sopenharmony_ci unsafe { 86562306a36Sopenharmony_ci alloc::dealloc(buf_ptr as *mut u8, alloc::Layout::array::<T>(len).unwrap_unchecked()); 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci }; 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_ci let run_alloc_fn = |len: usize| -> *mut sort::TimSortRun { 87062306a36Sopenharmony_ci // SAFETY: Creating the layout is safe as long as merge_sort never calls this with an 87162306a36Sopenharmony_ci // obscene length or 0. 87262306a36Sopenharmony_ci unsafe { 87362306a36Sopenharmony_ci alloc::alloc(alloc::Layout::array::<sort::TimSortRun>(len).unwrap_unchecked()) 87462306a36Sopenharmony_ci as *mut sort::TimSortRun 87562306a36Sopenharmony_ci } 87662306a36Sopenharmony_ci }; 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci let run_dealloc_fn = |buf_ptr: *mut sort::TimSortRun, len: usize| { 87962306a36Sopenharmony_ci // SAFETY: The caller must ensure that buf_ptr was created by elem_alloc_fn with the same 88062306a36Sopenharmony_ci // len. 88162306a36Sopenharmony_ci unsafe { 88262306a36Sopenharmony_ci alloc::dealloc( 88362306a36Sopenharmony_ci buf_ptr as *mut u8, 88462306a36Sopenharmony_ci alloc::Layout::array::<sort::TimSortRun>(len).unwrap_unchecked(), 88562306a36Sopenharmony_ci ); 88662306a36Sopenharmony_ci } 88762306a36Sopenharmony_ci }; 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci sort::merge_sort(v, &mut is_less, elem_alloc_fn, elem_dealloc_fn, run_alloc_fn, run_dealloc_fn); 89062306a36Sopenharmony_ci} 891