forked from mirrors/linux
		
	rust: alloc: remove our fork of the alloc crate
				
					
				
			It is not used anymore as `VecExt` now provides the functionality we depend on. Reviewed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com> Link: https://lore.kernel.org/r/20240328013603.206764-5-wedsonaf@gmail.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									11795ae4cc
								
							
						
					
					
						commit
						9d0441bab7
					
				
					 15 changed files with 0 additions and 9885 deletions
				
			
		| 
						 | 
					@ -1,36 +0,0 @@
 | 
				
			||||||
# `alloc`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These source files come from the Rust standard library, hosted in
 | 
					 | 
				
			||||||
the <https://github.com/rust-lang/rust> repository, licensed under
 | 
					 | 
				
			||||||
"Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
 | 
					 | 
				
			||||||
see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Please note that these files should be kept as close as possible to
 | 
					 | 
				
			||||||
upstream. In general, only additions should be performed (e.g. new
 | 
					 | 
				
			||||||
methods). Eventually, changes should make it into upstream so that,
 | 
					 | 
				
			||||||
at some point, this fork can be dropped from the kernel tree.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The Rust upstream version on top of which these files are based matches
 | 
					 | 
				
			||||||
the output of `scripts/min-tool-version.sh rustc`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Rationale
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On one hand, kernel folks wanted to keep `alloc` in-tree to have more
 | 
					 | 
				
			||||||
freedom in both workflow and actual features if actually needed
 | 
					 | 
				
			||||||
(e.g. receiver types if we ended up using them), which is reasonable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On the other hand, Rust folks wanted to keep `alloc` as close as
 | 
					 | 
				
			||||||
upstream as possible and avoid as much divergence as possible, which
 | 
					 | 
				
			||||||
is also reasonable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We agreed on a middle-ground: we would keep a subset of `alloc`
 | 
					 | 
				
			||||||
in-tree that would be as small and as close as possible to upstream.
 | 
					 | 
				
			||||||
Then, upstream can start adding the functions that we add to `alloc`
 | 
					 | 
				
			||||||
etc., until we reach a point where the kernel already knows exactly
 | 
					 | 
				
			||||||
what it needs in `alloc` and all the new methods are merged into
 | 
					 | 
				
			||||||
upstream, so that we can drop `alloc` from the kernel tree and go back
 | 
					 | 
				
			||||||
to using the upstream one.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
By doing this, the kernel can go a bit faster now, and Rust can
 | 
					 | 
				
			||||||
slowly incorporate and discuss the changes as needed.
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,452 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//! Memory allocation APIs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![stable(feature = "alloc_module", since = "1.28.0")]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
use core::hint;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
use core::ptr::{self, NonNull};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "alloc_module", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[doc(inline)]
 | 
					 | 
				
			||||||
pub use core::alloc::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern "Rust" {
 | 
					 | 
				
			||||||
    // These are the magic symbols to call the global allocator. rustc generates
 | 
					 | 
				
			||||||
    // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
    // (the code expanding that attribute macro generates those functions), or to call
 | 
					 | 
				
			||||||
    // the default implementations in std (`__rdl_alloc` etc. in `library/std/src/alloc.rs`)
 | 
					 | 
				
			||||||
    // otherwise.
 | 
					 | 
				
			||||||
    // The rustc fork of LLVM 14 and earlier also special-cases these function names to be able to optimize them
 | 
					 | 
				
			||||||
    // like `malloc`, `realloc`, and `free`, respectively.
 | 
					 | 
				
			||||||
    #[rustc_allocator]
 | 
					 | 
				
			||||||
    #[rustc_nounwind]
 | 
					 | 
				
			||||||
    fn __rust_alloc(size: usize, align: usize) -> *mut u8;
 | 
					 | 
				
			||||||
    #[rustc_deallocator]
 | 
					 | 
				
			||||||
    #[rustc_nounwind]
 | 
					 | 
				
			||||||
    fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
 | 
					 | 
				
			||||||
    #[rustc_reallocator]
 | 
					 | 
				
			||||||
    #[rustc_nounwind]
 | 
					 | 
				
			||||||
    fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
 | 
					 | 
				
			||||||
    #[rustc_allocator_zeroed]
 | 
					 | 
				
			||||||
    #[rustc_nounwind]
 | 
					 | 
				
			||||||
    fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static __rust_no_alloc_shim_is_unstable: u8;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// The global memory allocator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This type implements the [`Allocator`] trait by forwarding calls
 | 
					 | 
				
			||||||
/// to the allocator registered with the `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
/// if there is one, or the `std` crate’s default.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note: while this type is unstable, the functionality it provides can be
 | 
					 | 
				
			||||||
/// accessed through the [free functions in `alloc`](self#functions).
 | 
					 | 
				
			||||||
#[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
#[derive(Copy, Clone, Default, Debug)]
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
pub struct Global;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
pub use std::alloc::Global;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Allocate memory with the global allocator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
 | 
					 | 
				
			||||||
/// of the allocator registered with the `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
/// if there is one, or the `std` crate’s default.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function is expected to be deprecated in favor of the `alloc` method
 | 
					 | 
				
			||||||
/// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Safety
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See [`GlobalAlloc::alloc`].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// use std::alloc::{alloc, dealloc, handle_alloc_error, Layout};
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// unsafe {
 | 
					 | 
				
			||||||
///     let layout = Layout::new::<u16>();
 | 
					 | 
				
			||||||
///     let ptr = alloc(layout);
 | 
					 | 
				
			||||||
///     if ptr.is_null() {
 | 
					 | 
				
			||||||
///         handle_alloc_error(layout);
 | 
					 | 
				
			||||||
///     }
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
///     *(ptr as *mut u16) = 42;
 | 
					 | 
				
			||||||
///     assert_eq!(*(ptr as *mut u16), 42);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
///     dealloc(ptr, layout);
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[stable(feature = "global_alloc", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[must_use = "losing the pointer will leak memory"]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        // Make sure we don't accidentally allow omitting the allocator shim in
 | 
					 | 
				
			||||||
        // stable code until it is actually stabilized.
 | 
					 | 
				
			||||||
        core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        __rust_alloc(layout.size(), layout.align())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Deallocate memory with the global allocator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function forwards calls to the [`GlobalAlloc::dealloc`] method
 | 
					 | 
				
			||||||
/// of the allocator registered with the `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
/// if there is one, or the `std` crate’s default.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function is expected to be deprecated in favor of the `dealloc` method
 | 
					 | 
				
			||||||
/// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Safety
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See [`GlobalAlloc::dealloc`].
 | 
					 | 
				
			||||||
#[stable(feature = "global_alloc", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
 | 
					 | 
				
			||||||
    unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Reallocate memory with the global allocator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function forwards calls to the [`GlobalAlloc::realloc`] method
 | 
					 | 
				
			||||||
/// of the allocator registered with the `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
/// if there is one, or the `std` crate’s default.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function is expected to be deprecated in favor of the `realloc` method
 | 
					 | 
				
			||||||
/// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Safety
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See [`GlobalAlloc::realloc`].
 | 
					 | 
				
			||||||
#[stable(feature = "global_alloc", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[must_use = "losing the pointer will leak memory"]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
 | 
					 | 
				
			||||||
    unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Allocate zero-initialized memory with the global allocator.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
 | 
					 | 
				
			||||||
/// of the allocator registered with the `#[global_allocator]` attribute
 | 
					 | 
				
			||||||
/// if there is one, or the `std` crate’s default.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function is expected to be deprecated in favor of the `alloc_zeroed` method
 | 
					 | 
				
			||||||
/// of the [`Global`] type when it and the [`Allocator`] trait become stable.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Safety
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// See [`GlobalAlloc::alloc_zeroed`].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// use std::alloc::{alloc_zeroed, dealloc, Layout};
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// unsafe {
 | 
					 | 
				
			||||||
///     let layout = Layout::new::<u16>();
 | 
					 | 
				
			||||||
///     let ptr = alloc_zeroed(layout);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
///     assert_eq!(*(ptr as *mut u16), 0);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
///     dealloc(ptr, layout);
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[stable(feature = "global_alloc", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[must_use = "losing the pointer will leak memory"]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
 | 
					 | 
				
			||||||
    unsafe { __rust_alloc_zeroed(layout.size(), layout.align()) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
impl Global {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        match layout.size() {
 | 
					 | 
				
			||||||
            0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)),
 | 
					 | 
				
			||||||
            // SAFETY: `layout` is non-zero in size,
 | 
					 | 
				
			||||||
            size => unsafe {
 | 
					 | 
				
			||||||
                let raw_ptr = if zeroed { alloc_zeroed(layout) } else { alloc(layout) };
 | 
					 | 
				
			||||||
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
 | 
					 | 
				
			||||||
                Ok(NonNull::slice_from_raw_parts(ptr, size))
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // SAFETY: Same as `Allocator::grow`
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn grow_impl(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        ptr: NonNull<u8>,
 | 
					 | 
				
			||||||
        old_layout: Layout,
 | 
					 | 
				
			||||||
        new_layout: Layout,
 | 
					 | 
				
			||||||
        zeroed: bool,
 | 
					 | 
				
			||||||
    ) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        debug_assert!(
 | 
					 | 
				
			||||||
            new_layout.size() >= old_layout.size(),
 | 
					 | 
				
			||||||
            "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match old_layout.size() {
 | 
					 | 
				
			||||||
            0 => self.alloc_impl(new_layout, zeroed),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // SAFETY: `new_size` is non-zero as `old_size` is greater than or equal to `new_size`
 | 
					 | 
				
			||||||
            // as required by safety conditions. Other conditions must be upheld by the caller
 | 
					 | 
				
			||||||
            old_size if old_layout.align() == new_layout.align() => unsafe {
 | 
					 | 
				
			||||||
                let new_size = new_layout.size();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // `realloc` probably checks for `new_size >= old_layout.size()` or something similar.
 | 
					 | 
				
			||||||
                hint::assert_unchecked(new_size >= old_layout.size());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
 | 
					 | 
				
			||||||
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
 | 
					 | 
				
			||||||
                if zeroed {
 | 
					 | 
				
			||||||
                    raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Ok(NonNull::slice_from_raw_parts(ptr, new_size))
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // SAFETY: because `new_layout.size()` must be greater than or equal to `old_size`,
 | 
					 | 
				
			||||||
            // both the old and new memory allocation are valid for reads and writes for `old_size`
 | 
					 | 
				
			||||||
            // bytes. Also, because the old allocation wasn't yet deallocated, it cannot overlap
 | 
					 | 
				
			||||||
            // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract
 | 
					 | 
				
			||||||
            // for `dealloc` must be upheld by the caller.
 | 
					 | 
				
			||||||
            old_size => unsafe {
 | 
					 | 
				
			||||||
                let new_ptr = self.alloc_impl(new_layout, zeroed)?;
 | 
					 | 
				
			||||||
                ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_size);
 | 
					 | 
				
			||||||
                self.deallocate(ptr, old_layout);
 | 
					 | 
				
			||||||
                Ok(new_ptr)
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
unsafe impl Allocator for Global {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        self.alloc_impl(layout, false)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        self.alloc_impl(layout, true)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
 | 
					 | 
				
			||||||
        if layout.size() != 0 {
 | 
					 | 
				
			||||||
            // SAFETY: `layout` is non-zero in size,
 | 
					 | 
				
			||||||
            // other conditions must be upheld by the caller
 | 
					 | 
				
			||||||
            unsafe { dealloc(ptr.as_ptr(), layout) }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn grow(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        ptr: NonNull<u8>,
 | 
					 | 
				
			||||||
        old_layout: Layout,
 | 
					 | 
				
			||||||
        new_layout: Layout,
 | 
					 | 
				
			||||||
    ) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        // SAFETY: all conditions must be upheld by the caller
 | 
					 | 
				
			||||||
        unsafe { self.grow_impl(ptr, old_layout, new_layout, false) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn grow_zeroed(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        ptr: NonNull<u8>,
 | 
					 | 
				
			||||||
        old_layout: Layout,
 | 
					 | 
				
			||||||
        new_layout: Layout,
 | 
					 | 
				
			||||||
    ) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        // SAFETY: all conditions must be upheld by the caller
 | 
					 | 
				
			||||||
        unsafe { self.grow_impl(ptr, old_layout, new_layout, true) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn shrink(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        ptr: NonNull<u8>,
 | 
					 | 
				
			||||||
        old_layout: Layout,
 | 
					 | 
				
			||||||
        new_layout: Layout,
 | 
					 | 
				
			||||||
    ) -> Result<NonNull<[u8]>, AllocError> {
 | 
					 | 
				
			||||||
        debug_assert!(
 | 
					 | 
				
			||||||
            new_layout.size() <= old_layout.size(),
 | 
					 | 
				
			||||||
            "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        match new_layout.size() {
 | 
					 | 
				
			||||||
            // SAFETY: conditions must be upheld by the caller
 | 
					 | 
				
			||||||
            0 => unsafe {
 | 
					 | 
				
			||||||
                self.deallocate(ptr, old_layout);
 | 
					 | 
				
			||||||
                Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0))
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller
 | 
					 | 
				
			||||||
            new_size if old_layout.align() == new_layout.align() => unsafe {
 | 
					 | 
				
			||||||
                // `realloc` probably checks for `new_size <= old_layout.size()` or something similar.
 | 
					 | 
				
			||||||
                hint::assert_unchecked(new_size <= old_layout.size());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
 | 
					 | 
				
			||||||
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
 | 
					 | 
				
			||||||
                Ok(NonNull::slice_from_raw_parts(ptr, new_size))
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // SAFETY: because `new_size` must be smaller than or equal to `old_layout.size()`,
 | 
					 | 
				
			||||||
            // both the old and new memory allocation are valid for reads and writes for `new_size`
 | 
					 | 
				
			||||||
            // bytes. Also, because the old allocation wasn't yet deallocated, it cannot overlap
 | 
					 | 
				
			||||||
            // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract
 | 
					 | 
				
			||||||
            // for `dealloc` must be upheld by the caller.
 | 
					 | 
				
			||||||
            new_size => unsafe {
 | 
					 | 
				
			||||||
                let new_ptr = self.allocate(new_layout)?;
 | 
					 | 
				
			||||||
                ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), new_size);
 | 
					 | 
				
			||||||
                self.deallocate(ptr, old_layout);
 | 
					 | 
				
			||||||
                Ok(new_ptr)
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// The allocator for unique pointers.
 | 
					 | 
				
			||||||
#[cfg(all(not(no_global_oom_handling), not(test)))]
 | 
					 | 
				
			||||||
#[lang = "exchange_malloc"]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 | 
					 | 
				
			||||||
    let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
 | 
					 | 
				
			||||||
    match Global.allocate(layout) {
 | 
					 | 
				
			||||||
        Ok(ptr) => ptr.as_mut_ptr(),
 | 
					 | 
				
			||||||
        Err(_) => handle_alloc_error(layout),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// # Allocation error handler
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
extern "Rust" {
 | 
					 | 
				
			||||||
    // This is the magic symbol to call the global alloc error handler. rustc generates
 | 
					 | 
				
			||||||
    // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
 | 
					 | 
				
			||||||
    // default implementations below (`__rdl_oom`) otherwise.
 | 
					 | 
				
			||||||
    fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Signal a memory allocation error.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Callers of memory allocation APIs wishing to cease execution
 | 
					 | 
				
			||||||
/// in response to an allocation error are encouraged to call this function,
 | 
					 | 
				
			||||||
/// rather than directly invoking [`panic!`] or similar.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This function is guaranteed to diverge (not return normally with a value), but depending on
 | 
					 | 
				
			||||||
/// global configuration, it may either panic (resulting in unwinding or aborting as per
 | 
					 | 
				
			||||||
/// configuration for all panics), or abort the process (with no unwinding).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The default behavior is:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
///  * If the binary links against `std` (typically the case), then
 | 
					 | 
				
			||||||
///   print a message to standard error and abort the process.
 | 
					 | 
				
			||||||
///   This behavior can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
 | 
					 | 
				
			||||||
///   Future versions of Rust may panic by default instead.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// * If the binary does not link against `std` (all of its crates are marked
 | 
					 | 
				
			||||||
///   [`#![no_std]`][no_std]), then call [`panic!`] with a message.
 | 
					 | 
				
			||||||
///   [The panic handler] applies as to any panic.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
 | 
					 | 
				
			||||||
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
 | 
					 | 
				
			||||||
/// [The panic handler]: https://doc.rust-lang.org/reference/runtime.html#the-panic_handler-attribute
 | 
					 | 
				
			||||||
/// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute
 | 
					 | 
				
			||||||
#[stable(feature = "global_alloc", since = "1.28.0")]
 | 
					 | 
				
			||||||
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
 | 
					 | 
				
			||||||
#[cfg(all(not(no_global_oom_handling), not(test)))]
 | 
					 | 
				
			||||||
#[cold]
 | 
					 | 
				
			||||||
pub const fn handle_alloc_error(layout: Layout) -> ! {
 | 
					 | 
				
			||||||
    const fn ct_error(_: Layout) -> ! {
 | 
					 | 
				
			||||||
        panic!("allocation failed");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn rt_error(layout: Layout) -> ! {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            __rust_alloc_error_handler(layout.size(), layout.align());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(feature = "panic_immediate_abort"))]
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        core::intrinsics::const_eval_select((layout,), ct_error, rt_error)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(feature = "panic_immediate_abort")]
 | 
					 | 
				
			||||||
    ct_error(layout)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// For alloc test `std::alloc::handle_alloc_error` can be used directly.
 | 
					 | 
				
			||||||
#[cfg(all(not(no_global_oom_handling), test))]
 | 
					 | 
				
			||||||
pub use std::alloc::handle_alloc_error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(all(not(no_global_oom_handling), not(test)))]
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[allow(unused_attributes)]
 | 
					 | 
				
			||||||
#[unstable(feature = "alloc_internals", issue = "none")]
 | 
					 | 
				
			||||||
pub mod __alloc_error_handler {
 | 
					 | 
				
			||||||
    // called via generated `__rust_alloc_error_handler` if there is no
 | 
					 | 
				
			||||||
    // `#[alloc_error_handler]`.
 | 
					 | 
				
			||||||
    #[rustc_std_internal_symbol]
 | 
					 | 
				
			||||||
    pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
 | 
					 | 
				
			||||||
        extern "Rust" {
 | 
					 | 
				
			||||||
            // This symbol is emitted by rustc next to __rust_alloc_error_handler.
 | 
					 | 
				
			||||||
            // Its value depends on the -Zoom={panic,abort} compiler option.
 | 
					 | 
				
			||||||
            static __rust_alloc_error_handler_should_panic: u8;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
 | 
					 | 
				
			||||||
            panic!("memory allocation of {size} bytes failed")
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            core::panicking::panic_nounwind_fmt(
 | 
					 | 
				
			||||||
                format_args!("memory allocation of {size} bytes failed"),
 | 
					 | 
				
			||||||
                /* force_no_backtrace */ false,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
/// Specialize clones into pre-allocated, uninitialized memory.
 | 
					 | 
				
			||||||
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
 | 
					 | 
				
			||||||
pub(crate) trait WriteCloneIntoRaw: Sized {
 | 
					 | 
				
			||||||
    unsafe fn write_clone_into_raw(&self, target: *mut Self);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T: Clone> WriteCloneIntoRaw for T {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
 | 
					 | 
				
			||||||
        // Having allocated *first* may allow the optimizer to create
 | 
					 | 
				
			||||||
        // the cloned value in-place, skipping the local and move.
 | 
					 | 
				
			||||||
        unsafe { target.write(self.clone()) };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T: Copy> WriteCloneIntoRaw for T {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn write_clone_into_raw(&self, target: *mut Self) {
 | 
					 | 
				
			||||||
        // We can always copy in-place, without ever involving a local value.
 | 
					 | 
				
			||||||
        unsafe { target.copy_from_nonoverlapping(self, 1) };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										2463
									
								
								rust/alloc/boxed.rs
									
									
									
									
									
								
							
							
						
						
									
										2463
									
								
								rust/alloc/boxed.rs
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,160 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//! Collection types.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
pub mod binary_heap;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
mod btree;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
pub mod linked_list;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
pub mod vec_deque;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub mod btree_map {
 | 
					 | 
				
			||||||
    //! An ordered map based on a B-Tree.
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    pub use super::btree::map::*;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub mod btree_set {
 | 
					 | 
				
			||||||
    //! An ordered set based on a B-Tree.
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    pub use super::btree::set::*;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[doc(no_inline)]
 | 
					 | 
				
			||||||
pub use binary_heap::BinaryHeap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[doc(no_inline)]
 | 
					 | 
				
			||||||
pub use btree_map::BTreeMap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[doc(no_inline)]
 | 
					 | 
				
			||||||
pub use btree_set::BTreeSet;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[doc(no_inline)]
 | 
					 | 
				
			||||||
pub use linked_list::LinkedList;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[doc(no_inline)]
 | 
					 | 
				
			||||||
pub use vec_deque::VecDeque;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::{Layout, LayoutError};
 | 
					 | 
				
			||||||
use core::fmt::Display;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// The error type for `try_reserve` methods.
 | 
					 | 
				
			||||||
#[derive(Clone, PartialEq, Eq, Debug)]
 | 
					 | 
				
			||||||
#[stable(feature = "try_reserve", since = "1.57.0")]
 | 
					 | 
				
			||||||
pub struct TryReserveError {
 | 
					 | 
				
			||||||
    kind: TryReserveErrorKind,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl TryReserveError {
 | 
					 | 
				
			||||||
    /// Details about the allocation that caused the error
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[unstable(
 | 
					 | 
				
			||||||
        feature = "try_reserve_kind",
 | 
					 | 
				
			||||||
        reason = "Uncertain how much info should be exposed",
 | 
					 | 
				
			||||||
        issue = "48043"
 | 
					 | 
				
			||||||
    )]
 | 
					 | 
				
			||||||
    pub fn kind(&self) -> TryReserveErrorKind {
 | 
					 | 
				
			||||||
        self.kind.clone()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Details of the allocation that caused a `TryReserveError`
 | 
					 | 
				
			||||||
#[derive(Clone, PartialEq, Eq, Debug)]
 | 
					 | 
				
			||||||
#[unstable(
 | 
					 | 
				
			||||||
    feature = "try_reserve_kind",
 | 
					 | 
				
			||||||
    reason = "Uncertain how much info should be exposed",
 | 
					 | 
				
			||||||
    issue = "48043"
 | 
					 | 
				
			||||||
)]
 | 
					 | 
				
			||||||
pub enum TryReserveErrorKind {
 | 
					 | 
				
			||||||
    /// Error due to the computed capacity exceeding the collection's maximum
 | 
					 | 
				
			||||||
    /// (usually `isize::MAX` bytes).
 | 
					 | 
				
			||||||
    CapacityOverflow,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The memory allocator returned an error
 | 
					 | 
				
			||||||
    AllocError {
 | 
					 | 
				
			||||||
        /// The layout of allocation request that failed
 | 
					 | 
				
			||||||
        layout: Layout,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #[doc(hidden)]
 | 
					 | 
				
			||||||
        #[unstable(
 | 
					 | 
				
			||||||
            feature = "container_error_extra",
 | 
					 | 
				
			||||||
            issue = "none",
 | 
					 | 
				
			||||||
            reason = "\
 | 
					 | 
				
			||||||
            Enable exposing the allocator’s custom error value \
 | 
					 | 
				
			||||||
            if an associated type is added in the future: \
 | 
					 | 
				
			||||||
            https://github.com/rust-lang/wg-allocators/issues/23"
 | 
					 | 
				
			||||||
        )]
 | 
					 | 
				
			||||||
        non_exhaustive: (),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(
 | 
					 | 
				
			||||||
    feature = "try_reserve_kind",
 | 
					 | 
				
			||||||
    reason = "Uncertain how much info should be exposed",
 | 
					 | 
				
			||||||
    issue = "48043"
 | 
					 | 
				
			||||||
)]
 | 
					 | 
				
			||||||
impl From<TryReserveErrorKind> for TryReserveError {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(kind: TryReserveErrorKind) -> Self {
 | 
					 | 
				
			||||||
        Self { kind }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")]
 | 
					 | 
				
			||||||
impl From<LayoutError> for TryReserveErrorKind {
 | 
					 | 
				
			||||||
    /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn from(_: LayoutError) -> Self {
 | 
					 | 
				
			||||||
        TryReserveErrorKind::CapacityOverflow
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "try_reserve", since = "1.57.0")]
 | 
					 | 
				
			||||||
impl Display for TryReserveError {
 | 
					 | 
				
			||||||
    fn fmt(
 | 
					 | 
				
			||||||
        &self,
 | 
					 | 
				
			||||||
        fmt: &mut core::fmt::Formatter<'_>,
 | 
					 | 
				
			||||||
    ) -> core::result::Result<(), core::fmt::Error> {
 | 
					 | 
				
			||||||
        fmt.write_str("memory allocation failed")?;
 | 
					 | 
				
			||||||
        let reason = match self.kind {
 | 
					 | 
				
			||||||
            TryReserveErrorKind::CapacityOverflow => {
 | 
					 | 
				
			||||||
                " because the computed capacity exceeded the collection's maximum"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            TryReserveErrorKind::AllocError { .. } => {
 | 
					 | 
				
			||||||
                " because the memory allocator returned an error"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        fmt.write_str(reason)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// An intermediate trait for specialization of `Extend`.
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
trait SpecExtend<I: IntoIterator> {
 | 
					 | 
				
			||||||
    /// Extends `self` with the contents of the given iterator.
 | 
					 | 
				
			||||||
    fn spec_extend(&mut self, iter: I);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "try_reserve", since = "1.57.0")]
 | 
					 | 
				
			||||||
impl core::error::Error for TryReserveError {}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,289 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//! # The Rust core allocation and collections library
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This library provides smart pointers and collections for managing
 | 
					 | 
				
			||||||
//! heap-allocated values.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This library, like core, normally doesn’t need to be used directly
 | 
					 | 
				
			||||||
//! since its contents are re-exported in the [`std` crate](../std/index.html).
 | 
					 | 
				
			||||||
//! Crates that use the `#![no_std]` attribute however will typically
 | 
					 | 
				
			||||||
//! not depend on `std`, so they’d use this crate instead.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ## Boxed values
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
 | 
					 | 
				
			||||||
//! [`Box`], and the owner can decide to mutate the contents, which live on the
 | 
					 | 
				
			||||||
//! heap.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This type can be sent among threads efficiently as the size of a `Box` value
 | 
					 | 
				
			||||||
//! is the same as that of a pointer. Tree-like data structures are often built
 | 
					 | 
				
			||||||
//! with boxes because each node often has only one owner, the parent.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ## Reference counted pointers
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
 | 
					 | 
				
			||||||
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
 | 
					 | 
				
			||||||
//! only allows access to `&T`, a shared reference.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This type is useful when inherited mutability (such as using [`Box`]) is too
 | 
					 | 
				
			||||||
//! constraining for an application, and is often paired with the [`Cell`] or
 | 
					 | 
				
			||||||
//! [`RefCell`] types in order to allow mutation.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ## Atomically reference counted pointers
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
 | 
					 | 
				
			||||||
//! provides all the same functionality of [`Rc`], except it requires that the
 | 
					 | 
				
			||||||
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
 | 
					 | 
				
			||||||
//! sendable while [`Rc<T>`][`Rc`] is not.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! This type allows for shared access to the contained data, and is often
 | 
					 | 
				
			||||||
//! paired with synchronization primitives such as mutexes to allow mutation of
 | 
					 | 
				
			||||||
//! shared resources.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ## Collections
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Implementations of the most common general purpose data structures are
 | 
					 | 
				
			||||||
//! defined in this library. They are re-exported through the
 | 
					 | 
				
			||||||
//! [standard collections library](../std/collections/index.html).
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! ## Heap interfaces
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
 | 
					 | 
				
			||||||
//! default global allocator. It is not compatible with the libc allocator API.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! [`Arc`]: sync
 | 
					 | 
				
			||||||
//! [`Box`]: boxed
 | 
					 | 
				
			||||||
//! [`Cell`]: core::cell
 | 
					 | 
				
			||||||
//! [`Rc`]: rc
 | 
					 | 
				
			||||||
//! [`RefCell`]: core::cell
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be
 | 
					 | 
				
			||||||
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
 | 
					 | 
				
			||||||
// rustc itself never sets the feature, so this line has no effect there.
 | 
					 | 
				
			||||||
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
#![allow(unused_attributes)]
 | 
					 | 
				
			||||||
#![stable(feature = "alloc", since = "1.36.0")]
 | 
					 | 
				
			||||||
#![doc(
 | 
					 | 
				
			||||||
    html_playground_url = "https://play.rust-lang.org/",
 | 
					 | 
				
			||||||
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
 | 
					 | 
				
			||||||
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
 | 
					 | 
				
			||||||
)]
 | 
					 | 
				
			||||||
#![doc(cfg_hide(
 | 
					 | 
				
			||||||
    not(test),
 | 
					 | 
				
			||||||
    not(any(test, bootstrap)),
 | 
					 | 
				
			||||||
    any(not(feature = "miri-test-libstd"), test, doctest),
 | 
					 | 
				
			||||||
    no_global_oom_handling,
 | 
					 | 
				
			||||||
    not(no_global_oom_handling),
 | 
					 | 
				
			||||||
    not(no_rc),
 | 
					 | 
				
			||||||
    not(no_sync),
 | 
					 | 
				
			||||||
    target_has_atomic = "ptr"
 | 
					 | 
				
			||||||
))]
 | 
					 | 
				
			||||||
#![doc(rust_logo)]
 | 
					 | 
				
			||||||
#![feature(rustdoc_internals)]
 | 
					 | 
				
			||||||
#![no_std]
 | 
					 | 
				
			||||||
#![needs_allocator]
 | 
					 | 
				
			||||||
// Lints:
 | 
					 | 
				
			||||||
#![deny(unsafe_op_in_unsafe_fn)]
 | 
					 | 
				
			||||||
#![deny(fuzzy_provenance_casts)]
 | 
					 | 
				
			||||||
#![warn(deprecated_in_future)]
 | 
					 | 
				
			||||||
#![warn(missing_debug_implementations)]
 | 
					 | 
				
			||||||
#![warn(missing_docs)]
 | 
					 | 
				
			||||||
#![allow(explicit_outlives_requirements)]
 | 
					 | 
				
			||||||
#![warn(multiple_supertrait_upcastable)]
 | 
					 | 
				
			||||||
#![allow(internal_features)]
 | 
					 | 
				
			||||||
#![allow(rustdoc::redundant_explicit_links)]
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Library features:
 | 
					 | 
				
			||||||
// tidy-alphabetical-start
 | 
					 | 
				
			||||||
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
 | 
					 | 
				
			||||||
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
 | 
					 | 
				
			||||||
#![cfg_attr(test, feature(is_sorted))]
 | 
					 | 
				
			||||||
#![cfg_attr(test, feature(new_uninit))]
 | 
					 | 
				
			||||||
#![feature(alloc_layout_extra)]
 | 
					 | 
				
			||||||
#![feature(allocator_api)]
 | 
					 | 
				
			||||||
#![feature(array_chunks)]
 | 
					 | 
				
			||||||
#![feature(array_into_iter_constructors)]
 | 
					 | 
				
			||||||
#![feature(array_windows)]
 | 
					 | 
				
			||||||
#![feature(ascii_char)]
 | 
					 | 
				
			||||||
#![feature(assert_matches)]
 | 
					 | 
				
			||||||
#![feature(async_iterator)]
 | 
					 | 
				
			||||||
#![feature(coerce_unsized)]
 | 
					 | 
				
			||||||
#![feature(const_align_of_val)]
 | 
					 | 
				
			||||||
#![feature(const_box)]
 | 
					 | 
				
			||||||
#![cfg_attr(not(no_borrow), feature(const_cow_is_borrowed))]
 | 
					 | 
				
			||||||
#![feature(const_eval_select)]
 | 
					 | 
				
			||||||
#![feature(const_maybe_uninit_as_mut_ptr)]
 | 
					 | 
				
			||||||
#![feature(const_maybe_uninit_write)]
 | 
					 | 
				
			||||||
#![feature(const_pin)]
 | 
					 | 
				
			||||||
#![feature(const_refs_to_cell)]
 | 
					 | 
				
			||||||
#![feature(const_size_of_val)]
 | 
					 | 
				
			||||||
#![feature(const_waker)]
 | 
					 | 
				
			||||||
#![feature(core_intrinsics)]
 | 
					 | 
				
			||||||
#![feature(deprecated_suggestion)]
 | 
					 | 
				
			||||||
#![feature(dispatch_from_dyn)]
 | 
					 | 
				
			||||||
#![feature(error_generic_member_access)]
 | 
					 | 
				
			||||||
#![feature(error_in_core)]
 | 
					 | 
				
			||||||
#![feature(exact_size_is_empty)]
 | 
					 | 
				
			||||||
#![feature(extend_one)]
 | 
					 | 
				
			||||||
#![feature(fmt_internals)]
 | 
					 | 
				
			||||||
#![feature(fn_traits)]
 | 
					 | 
				
			||||||
#![feature(hasher_prefixfree_extras)]
 | 
					 | 
				
			||||||
#![feature(hint_assert_unchecked)]
 | 
					 | 
				
			||||||
#![feature(inline_const)]
 | 
					 | 
				
			||||||
#![feature(inplace_iteration)]
 | 
					 | 
				
			||||||
#![feature(iter_advance_by)]
 | 
					 | 
				
			||||||
#![feature(iter_next_chunk)]
 | 
					 | 
				
			||||||
#![feature(iter_repeat_n)]
 | 
					 | 
				
			||||||
#![feature(layout_for_ptr)]
 | 
					 | 
				
			||||||
#![feature(maybe_uninit_slice)]
 | 
					 | 
				
			||||||
#![feature(maybe_uninit_uninit_array)]
 | 
					 | 
				
			||||||
#![feature(maybe_uninit_uninit_array_transpose)]
 | 
					 | 
				
			||||||
#![feature(non_null_convenience)]
 | 
					 | 
				
			||||||
#![feature(panic_internals)]
 | 
					 | 
				
			||||||
#![feature(pattern)]
 | 
					 | 
				
			||||||
#![feature(ptr_internals)]
 | 
					 | 
				
			||||||
#![feature(ptr_metadata)]
 | 
					 | 
				
			||||||
#![feature(ptr_sub_ptr)]
 | 
					 | 
				
			||||||
#![feature(receiver_trait)]
 | 
					 | 
				
			||||||
#![feature(set_ptr_value)]
 | 
					 | 
				
			||||||
#![feature(sized_type_properties)]
 | 
					 | 
				
			||||||
#![feature(slice_from_ptr_range)]
 | 
					 | 
				
			||||||
#![feature(slice_ptr_get)]
 | 
					 | 
				
			||||||
#![feature(slice_ptr_len)]
 | 
					 | 
				
			||||||
#![feature(slice_range)]
 | 
					 | 
				
			||||||
#![feature(std_internals)]
 | 
					 | 
				
			||||||
#![feature(str_internals)]
 | 
					 | 
				
			||||||
#![feature(strict_provenance)]
 | 
					 | 
				
			||||||
#![feature(trusted_fused)]
 | 
					 | 
				
			||||||
#![feature(trusted_len)]
 | 
					 | 
				
			||||||
#![feature(trusted_random_access)]
 | 
					 | 
				
			||||||
#![feature(try_trait_v2)]
 | 
					 | 
				
			||||||
#![feature(tuple_trait)]
 | 
					 | 
				
			||||||
#![feature(unchecked_math)]
 | 
					 | 
				
			||||||
#![feature(unicode_internals)]
 | 
					 | 
				
			||||||
#![feature(unsize)]
 | 
					 | 
				
			||||||
#![feature(utf8_chunks)]
 | 
					 | 
				
			||||||
// tidy-alphabetical-end
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Language features:
 | 
					 | 
				
			||||||
// tidy-alphabetical-start
 | 
					 | 
				
			||||||
#![cfg_attr(not(test), feature(coroutine_trait))]
 | 
					 | 
				
			||||||
#![cfg_attr(test, feature(panic_update_hook))]
 | 
					 | 
				
			||||||
#![cfg_attr(test, feature(test))]
 | 
					 | 
				
			||||||
#![feature(allocator_internals)]
 | 
					 | 
				
			||||||
#![feature(allow_internal_unstable)]
 | 
					 | 
				
			||||||
#![feature(associated_type_bounds)]
 | 
					 | 
				
			||||||
#![feature(c_unwind)]
 | 
					 | 
				
			||||||
#![feature(cfg_sanitize)]
 | 
					 | 
				
			||||||
#![feature(const_mut_refs)]
 | 
					 | 
				
			||||||
#![feature(const_precise_live_drops)]
 | 
					 | 
				
			||||||
#![feature(const_ptr_write)]
 | 
					 | 
				
			||||||
#![feature(const_trait_impl)]
 | 
					 | 
				
			||||||
#![feature(const_try)]
 | 
					 | 
				
			||||||
#![feature(decl_macro)]
 | 
					 | 
				
			||||||
#![feature(dropck_eyepatch)]
 | 
					 | 
				
			||||||
#![feature(exclusive_range_pattern)]
 | 
					 | 
				
			||||||
#![feature(fundamental)]
 | 
					 | 
				
			||||||
#![feature(hashmap_internals)]
 | 
					 | 
				
			||||||
#![feature(lang_items)]
 | 
					 | 
				
			||||||
#![feature(min_specialization)]
 | 
					 | 
				
			||||||
#![feature(multiple_supertrait_upcastable)]
 | 
					 | 
				
			||||||
#![feature(negative_impls)]
 | 
					 | 
				
			||||||
#![feature(never_type)]
 | 
					 | 
				
			||||||
#![feature(pointer_is_aligned)]
 | 
					 | 
				
			||||||
#![feature(rustc_allow_const_fn_unstable)]
 | 
					 | 
				
			||||||
#![feature(rustc_attrs)]
 | 
					 | 
				
			||||||
#![feature(slice_internals)]
 | 
					 | 
				
			||||||
#![feature(staged_api)]
 | 
					 | 
				
			||||||
#![feature(stmt_expr_attributes)]
 | 
					 | 
				
			||||||
#![feature(unboxed_closures)]
 | 
					 | 
				
			||||||
#![feature(unsized_fn_params)]
 | 
					 | 
				
			||||||
#![feature(with_negative_coherence)]
 | 
					 | 
				
			||||||
// tidy-alphabetical-end
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Rustdoc features:
 | 
					 | 
				
			||||||
#![feature(doc_cfg)]
 | 
					 | 
				
			||||||
#![feature(doc_cfg_hide)]
 | 
					 | 
				
			||||||
// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]`
 | 
					 | 
				
			||||||
// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad
 | 
					 | 
				
			||||||
// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs
 | 
					 | 
				
			||||||
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
 | 
					 | 
				
			||||||
#![feature(intra_doc_pointers)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Allow testing this library
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
#[macro_use]
 | 
					 | 
				
			||||||
extern crate std;
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
extern crate test;
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod testing;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Module with internal macros used by other modules (needs to be included before other modules).
 | 
					 | 
				
			||||||
#[cfg(not(no_macros))]
 | 
					 | 
				
			||||||
#[macro_use]
 | 
					 | 
				
			||||||
mod macros;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mod raw_vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Heaps provided for low-level allocation strategies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod alloc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Primitive types using the heaps above
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Need to conditionally define the mod from `boxed.rs` to avoid
 | 
					 | 
				
			||||||
// duplicating the lang-items when building in test cfg; but also need
 | 
					 | 
				
			||||||
// to allow code to have `use boxed::Box;` declarations.
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
pub mod boxed;
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod boxed {
 | 
					 | 
				
			||||||
    pub use std::boxed::Box;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#[cfg(not(no_borrow))]
 | 
					 | 
				
			||||||
pub mod borrow;
 | 
					 | 
				
			||||||
pub mod collections;
 | 
					 | 
				
			||||||
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
 | 
					 | 
				
			||||||
pub mod ffi;
 | 
					 | 
				
			||||||
#[cfg(not(no_fmt))]
 | 
					 | 
				
			||||||
pub mod fmt;
 | 
					 | 
				
			||||||
#[cfg(not(no_rc))]
 | 
					 | 
				
			||||||
pub mod rc;
 | 
					 | 
				
			||||||
pub mod slice;
 | 
					 | 
				
			||||||
#[cfg(not(no_str))]
 | 
					 | 
				
			||||||
pub mod str;
 | 
					 | 
				
			||||||
#[cfg(not(no_string))]
 | 
					 | 
				
			||||||
pub mod string;
 | 
					 | 
				
			||||||
#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
 | 
					 | 
				
			||||||
pub mod sync;
 | 
					 | 
				
			||||||
#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
 | 
					 | 
				
			||||||
pub mod task;
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests;
 | 
					 | 
				
			||||||
pub mod vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
 | 
					 | 
				
			||||||
pub mod __export {
 | 
					 | 
				
			||||||
    pub use core::format_args;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
#[allow(dead_code)] // Not used in all configurations
 | 
					 | 
				
			||||||
pub(crate) mod test_helpers {
 | 
					 | 
				
			||||||
    /// Copied from `std::test_helpers::test_rng`, since these tests rely on the
 | 
					 | 
				
			||||||
    /// seed not being the same for every RNG invocation too.
 | 
					 | 
				
			||||||
    pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
 | 
					 | 
				
			||||||
        use std::hash::{BuildHasher, Hash, Hasher};
 | 
					 | 
				
			||||||
        let mut hasher = std::hash::RandomState::new().build_hasher();
 | 
					 | 
				
			||||||
        std::panic::Location::caller().hash(&mut hasher);
 | 
					 | 
				
			||||||
        let hc64 = hasher.finish();
 | 
					 | 
				
			||||||
        let seed_vec =
 | 
					 | 
				
			||||||
            hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
 | 
					 | 
				
			||||||
        let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
 | 
					 | 
				
			||||||
        rand::SeedableRng::from_seed(seed)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,610 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use core::alloc::LayoutError;
 | 
					 | 
				
			||||||
use core::cmp;
 | 
					 | 
				
			||||||
use core::hint;
 | 
					 | 
				
			||||||
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
 | 
					 | 
				
			||||||
use core::ptr::{self, NonNull, Unique};
 | 
					 | 
				
			||||||
use core::slice;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use crate::alloc::handle_alloc_error;
 | 
					 | 
				
			||||||
use crate::alloc::{Allocator, Global, Layout};
 | 
					 | 
				
			||||||
use crate::boxed::Box;
 | 
					 | 
				
			||||||
use crate::collections::TryReserveError;
 | 
					 | 
				
			||||||
use crate::collections::TryReserveErrorKind::*;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum AllocInit {
 | 
					 | 
				
			||||||
    /// The contents of the new memory are uninitialized.
 | 
					 | 
				
			||||||
    Uninitialized,
 | 
					 | 
				
			||||||
    /// The new memory is guaranteed to be zeroed.
 | 
					 | 
				
			||||||
    #[allow(dead_code)]
 | 
					 | 
				
			||||||
    Zeroed,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[repr(transparent)]
 | 
					 | 
				
			||||||
#[cfg_attr(target_pointer_width = "16", rustc_layout_scalar_valid_range_end(0x7fff))]
 | 
					 | 
				
			||||||
#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0x7fff_ffff))]
 | 
					 | 
				
			||||||
#[cfg_attr(target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0x7fff_ffff_ffff_ffff))]
 | 
					 | 
				
			||||||
struct Cap(usize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Cap {
 | 
					 | 
				
			||||||
    const ZERO: Cap = unsafe { Cap(0) };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
 | 
					 | 
				
			||||||
/// a buffer of memory on the heap without having to worry about all the corner cases
 | 
					 | 
				
			||||||
/// involved. This type is excellent for building your own data structures like Vec and VecDeque.
 | 
					 | 
				
			||||||
/// In particular:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// * Produces `Unique::dangling()` on zero-sized types.
 | 
					 | 
				
			||||||
/// * Produces `Unique::dangling()` on zero-length allocations.
 | 
					 | 
				
			||||||
/// * Avoids freeing `Unique::dangling()`.
 | 
					 | 
				
			||||||
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
 | 
					 | 
				
			||||||
/// * Guards against 32-bit systems allocating more than isize::MAX bytes.
 | 
					 | 
				
			||||||
/// * Guards against overflowing your length.
 | 
					 | 
				
			||||||
/// * Calls `handle_alloc_error` for fallible allocations.
 | 
					 | 
				
			||||||
/// * Contains a `ptr::Unique` and thus endows the user with all related benefits.
 | 
					 | 
				
			||||||
/// * Uses the excess returned from the allocator to use the largest available capacity.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This type does not in anyway inspect the memory that it manages. When dropped it *will*
 | 
					 | 
				
			||||||
/// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec`
 | 
					 | 
				
			||||||
/// to handle the actual things *stored* inside of a `RawVec`.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note that the excess of a zero-sized types is always infinite, so `capacity()` always returns
 | 
					 | 
				
			||||||
/// `usize::MAX`. This means that you need to be careful when round-tripping this type with a
 | 
					 | 
				
			||||||
/// `Box<[T]>`, since `capacity()` won't yield the length.
 | 
					 | 
				
			||||||
#[allow(missing_debug_implementations)]
 | 
					 | 
				
			||||||
pub(crate) struct RawVec<T, A: Allocator = Global> {
 | 
					 | 
				
			||||||
    ptr: Unique<T>,
 | 
					 | 
				
			||||||
    /// Never used for ZSTs; it's `capacity()`'s responsibility to return usize::MAX in that case.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Safety
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// `cap` must be in the `0..=isize::MAX` range.
 | 
					 | 
				
			||||||
    cap: Cap,
 | 
					 | 
				
			||||||
    alloc: A,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T> RawVec<T, Global> {
 | 
					 | 
				
			||||||
    /// HACK(Centril): This exists because stable `const fn` can only call stable `const fn`, so
 | 
					 | 
				
			||||||
    /// they cannot call `Self::new()`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// If you change `RawVec<T>::new` or dependencies, please take care to not introduce anything
 | 
					 | 
				
			||||||
    /// that would truly const-call something unstable.
 | 
					 | 
				
			||||||
    pub const NEW: Self = Self::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Creates the biggest possible `RawVec` (on the system heap)
 | 
					 | 
				
			||||||
    /// without allocating. If `T` has positive size, then this makes a
 | 
					 | 
				
			||||||
    /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
 | 
					 | 
				
			||||||
    /// `RawVec` with capacity `usize::MAX`. Useful for implementing
 | 
					 | 
				
			||||||
    /// delayed allocation.
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    pub const fn new() -> Self {
 | 
					 | 
				
			||||||
        Self::new_in(Global)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Creates a `RawVec` (on the system heap) with exactly the
 | 
					 | 
				
			||||||
    /// capacity and alignment requirements for a `[T; capacity]`. This is
 | 
					 | 
				
			||||||
    /// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is
 | 
					 | 
				
			||||||
    /// zero-sized. Note that if `T` is zero-sized this means you will
 | 
					 | 
				
			||||||
    /// *not* get a `RawVec` with the requested capacity.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panics
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Panics if the requested capacity exceeds `isize::MAX` bytes.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Aborts
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Aborts on OOM.
 | 
					 | 
				
			||||||
    #[cfg(not(any(no_global_oom_handling, test)))]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn with_capacity(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
        Self::with_capacity_in(capacity, Global)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Like `with_capacity`, but guarantees the buffer is zeroed.
 | 
					 | 
				
			||||||
    #[cfg(not(any(no_global_oom_handling, test)))]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn with_capacity_zeroed(capacity: usize) -> Self {
 | 
					 | 
				
			||||||
        Self::with_capacity_zeroed_in(capacity, Global)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, A: Allocator> RawVec<T, A> {
 | 
					 | 
				
			||||||
    // Tiny Vecs are dumb. Skip to:
 | 
					 | 
				
			||||||
    // - 8 if the element size is 1, because any heap allocators is likely
 | 
					 | 
				
			||||||
    //   to round up a request of less than 8 bytes to at least 8 bytes.
 | 
					 | 
				
			||||||
    // - 4 if elements are moderate-sized (<= 1 KiB).
 | 
					 | 
				
			||||||
    // - 1 otherwise, to avoid wasting too much space for very short Vecs.
 | 
					 | 
				
			||||||
    pub(crate) const MIN_NON_ZERO_CAP: usize = if mem::size_of::<T>() == 1 {
 | 
					 | 
				
			||||||
        8
 | 
					 | 
				
			||||||
    } else if mem::size_of::<T>() <= 1024 {
 | 
					 | 
				
			||||||
        4
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Like `new`, but parameterized over the choice of allocator for
 | 
					 | 
				
			||||||
    /// the returned `RawVec`.
 | 
					 | 
				
			||||||
    pub const fn new_in(alloc: A) -> Self {
 | 
					 | 
				
			||||||
        // `cap: 0` means "unallocated". zero-sized types are ignored.
 | 
					 | 
				
			||||||
        Self { ptr: Unique::dangling(), cap: Cap::ZERO, alloc }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Like `with_capacity`, but parameterized over the choice of
 | 
					 | 
				
			||||||
    /// allocator for the returned `RawVec`.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
 | 
					 | 
				
			||||||
        Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Like `try_with_capacity`, but parameterized over the choice of
 | 
					 | 
				
			||||||
    /// allocator for the returned `RawVec`.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
 | 
					 | 
				
			||||||
        Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Like `with_capacity_zeroed`, but parameterized over the choice
 | 
					 | 
				
			||||||
    /// of allocator for the returned `RawVec`.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
 | 
					 | 
				
			||||||
        Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Note that this will correctly reconstitute any `cap` changes
 | 
					 | 
				
			||||||
    /// that may have been performed. (See description of type for details.)
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Safety
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// * `len` must be greater than or equal to the most recently requested capacity, and
 | 
					 | 
				
			||||||
    /// * `len` must be less than or equal to `self.capacity()`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Note, that the requested capacity and `self.capacity()` could differ, as
 | 
					 | 
				
			||||||
    /// an allocator could overallocate and return a greater memory block than requested.
 | 
					 | 
				
			||||||
    pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>], A> {
 | 
					 | 
				
			||||||
        // Sanity-check one half of the safety requirement (we cannot check the other half).
 | 
					 | 
				
			||||||
        debug_assert!(
 | 
					 | 
				
			||||||
            len <= self.capacity(),
 | 
					 | 
				
			||||||
            "`len` must be smaller than or equal to `self.capacity()`"
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let me = ManuallyDrop::new(self);
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
 | 
					 | 
				
			||||||
            Box::from_raw_in(slice, ptr::read(&me.alloc))
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self {
 | 
					 | 
				
			||||||
        // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
 | 
					 | 
				
			||||||
        if T::IS_ZST || capacity == 0 {
 | 
					 | 
				
			||||||
            Self::new_in(alloc)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // We avoid `unwrap_or_else` here because it bloats the amount of
 | 
					 | 
				
			||||||
            // LLVM IR generated.
 | 
					 | 
				
			||||||
            let layout = match Layout::array::<T>(capacity) {
 | 
					 | 
				
			||||||
                Ok(layout) => layout,
 | 
					 | 
				
			||||||
                Err(_) => capacity_overflow(),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            match alloc_guard(layout.size()) {
 | 
					 | 
				
			||||||
                Ok(_) => {}
 | 
					 | 
				
			||||||
                Err(_) => capacity_overflow(),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let result = match init {
 | 
					 | 
				
			||||||
                AllocInit::Uninitialized => alloc.allocate(layout),
 | 
					 | 
				
			||||||
                AllocInit::Zeroed => alloc.allocate_zeroed(layout),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            let ptr = match result {
 | 
					 | 
				
			||||||
                Ok(ptr) => ptr,
 | 
					 | 
				
			||||||
                Err(_) => handle_alloc_error(layout),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Allocators currently return a `NonNull<[u8]>` whose length
 | 
					 | 
				
			||||||
            // matches the size requested. If that ever changes, the capacity
 | 
					 | 
				
			||||||
            // here should change to `ptr.len() / mem::size_of::<T>()`.
 | 
					 | 
				
			||||||
            Self {
 | 
					 | 
				
			||||||
                ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
 | 
					 | 
				
			||||||
                cap: unsafe { Cap(capacity) },
 | 
					 | 
				
			||||||
                alloc,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn try_allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Result<Self, TryReserveError> {
 | 
					 | 
				
			||||||
        // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
 | 
					 | 
				
			||||||
        if T::IS_ZST || capacity == 0 {
 | 
					 | 
				
			||||||
            return Ok(Self::new_in(alloc));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let layout = Layout::array::<T>(capacity).map_err(|_| CapacityOverflow)?;
 | 
					 | 
				
			||||||
        alloc_guard(layout.size())?;
 | 
					 | 
				
			||||||
        let result = match init {
 | 
					 | 
				
			||||||
            AllocInit::Uninitialized => alloc.allocate(layout),
 | 
					 | 
				
			||||||
            AllocInit::Zeroed => alloc.allocate_zeroed(layout),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        let ptr = result.map_err(|_| AllocError { layout, non_exhaustive: () })?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Allocators currently return a `NonNull<[u8]>` whose length
 | 
					 | 
				
			||||||
        // matches the size requested. If that ever changes, the capacity
 | 
					 | 
				
			||||||
        // here should change to `ptr.len() / mem::size_of::<T>()`.
 | 
					 | 
				
			||||||
        Ok(Self {
 | 
					 | 
				
			||||||
            ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
 | 
					 | 
				
			||||||
            cap: unsafe { Cap(capacity) },
 | 
					 | 
				
			||||||
            alloc,
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Safety
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The `ptr` must be allocated (via the given allocator `alloc`), and with the given
 | 
					 | 
				
			||||||
    /// `capacity`.
 | 
					 | 
				
			||||||
    /// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit
 | 
					 | 
				
			||||||
    /// systems). For ZSTs capacity is ignored.
 | 
					 | 
				
			||||||
    /// If the `ptr` and `capacity` come from a `RawVec` created via `alloc`, then this is
 | 
					 | 
				
			||||||
    /// guaranteed.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self {
 | 
					 | 
				
			||||||
        let cap = if T::IS_ZST { Cap::ZERO } else { unsafe { Cap(capacity) } };
 | 
					 | 
				
			||||||
        Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Gets a raw pointer to the start of the allocation. Note that this is
 | 
					 | 
				
			||||||
    /// `Unique::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
 | 
					 | 
				
			||||||
    /// be careful.
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn ptr(&self) -> *mut T {
 | 
					 | 
				
			||||||
        self.ptr.as_ptr()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Gets the capacity of the allocation.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This will always be `usize::MAX` if `T` is zero-sized.
 | 
					 | 
				
			||||||
    #[inline(always)]
 | 
					 | 
				
			||||||
    pub fn capacity(&self) -> usize {
 | 
					 | 
				
			||||||
        if T::IS_ZST { usize::MAX } else { self.cap.0 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns a shared reference to the allocator backing this `RawVec`.
 | 
					 | 
				
			||||||
    pub fn allocator(&self) -> &A {
 | 
					 | 
				
			||||||
        &self.alloc
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn current_memory(&self) -> Option<(NonNull<u8>, Layout)> {
 | 
					 | 
				
			||||||
        if T::IS_ZST || self.cap.0 == 0 {
 | 
					 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // We could use Layout::array here which ensures the absence of isize and usize overflows
 | 
					 | 
				
			||||||
            // and could hypothetically handle differences between stride and size, but this memory
 | 
					 | 
				
			||||||
            // has already been allocated so we know it can't overflow and currently rust does not
 | 
					 | 
				
			||||||
            // support such types. So we can do better by skipping some checks and avoid an unwrap.
 | 
					 | 
				
			||||||
            let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                let align = mem::align_of::<T>();
 | 
					 | 
				
			||||||
                let size = mem::size_of::<T>().unchecked_mul(self.cap.0);
 | 
					 | 
				
			||||||
                let layout = Layout::from_size_align_unchecked(size, align);
 | 
					 | 
				
			||||||
                Some((self.ptr.cast().into(), layout))
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Ensures that the buffer contains at least enough space to hold `len +
 | 
					 | 
				
			||||||
    /// additional` elements. If it doesn't already have enough capacity, will
 | 
					 | 
				
			||||||
    /// reallocate enough space plus comfortable slack space to get amortized
 | 
					 | 
				
			||||||
    /// *O*(1) behavior. Will limit this behavior if it would needlessly cause
 | 
					 | 
				
			||||||
    /// itself to panic.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
 | 
					 | 
				
			||||||
    /// the requested space. This is not really unsafe, but the unsafe
 | 
					 | 
				
			||||||
    /// code *you* write that relies on the behavior of this function may break.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This is ideal for implementing a bulk-push operation like `extend`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panics
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Panics if the new capacity exceeds `isize::MAX` _bytes_.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Aborts
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Aborts on OOM.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn reserve(&mut self, len: usize, additional: usize) {
 | 
					 | 
				
			||||||
        // Callers expect this function to be very cheap when there is already sufficient capacity.
 | 
					 | 
				
			||||||
        // Therefore, we move all the resizing and error-handling logic from grow_amortized and
 | 
					 | 
				
			||||||
        // handle_reserve behind a call, while making sure that this function is likely to be
 | 
					 | 
				
			||||||
        // inlined as just a comparison and a call if the comparison fails.
 | 
					 | 
				
			||||||
        #[cold]
 | 
					 | 
				
			||||||
        fn do_reserve_and_handle<T, A: Allocator>(
 | 
					 | 
				
			||||||
            slf: &mut RawVec<T, A>,
 | 
					 | 
				
			||||||
            len: usize,
 | 
					 | 
				
			||||||
            additional: usize,
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
            handle_reserve(slf.grow_amortized(len, additional));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.needs_to_grow(len, additional) {
 | 
					 | 
				
			||||||
            do_reserve_and_handle(self, len, additional);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// A specialized version of `reserve()` used only by the hot and
 | 
					 | 
				
			||||||
    /// oft-instantiated `Vec::push()`, which does its own capacity check.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline(never)]
 | 
					 | 
				
			||||||
    pub fn reserve_for_push(&mut self, len: usize) {
 | 
					 | 
				
			||||||
        handle_reserve(self.grow_amortized(len, 1));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The same as `reserve`, but returns on errors instead of panicking or aborting.
 | 
					 | 
				
			||||||
    pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        if self.needs_to_grow(len, additional) {
 | 
					 | 
				
			||||||
            self.grow_amortized(len, additional)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            // Inform the optimizer that the reservation has succeeded or wasn't needed
 | 
					 | 
				
			||||||
            hint::assert_unchecked(!self.needs_to_grow(len, additional));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting.
 | 
					 | 
				
			||||||
    #[inline(never)]
 | 
					 | 
				
			||||||
    pub fn try_reserve_for_push(&mut self, len: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        self.grow_amortized(len, 1)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Ensures that the buffer contains at least enough space to hold `len +
 | 
					 | 
				
			||||||
    /// additional` elements. If it doesn't already, will reallocate the
 | 
					 | 
				
			||||||
    /// minimum possible amount of memory necessary. Generally this will be
 | 
					 | 
				
			||||||
    /// exactly the amount of memory necessary, but in principle the allocator
 | 
					 | 
				
			||||||
    /// is free to give back more than we asked for.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
 | 
					 | 
				
			||||||
    /// the requested space. This is not really unsafe, but the unsafe code
 | 
					 | 
				
			||||||
    /// *you* write that relies on the behavior of this function may break.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panics
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Panics if the new capacity exceeds `isize::MAX` _bytes_.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Aborts
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Aborts on OOM.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    pub fn reserve_exact(&mut self, len: usize, additional: usize) {
 | 
					 | 
				
			||||||
        handle_reserve(self.try_reserve_exact(len, additional));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
 | 
					 | 
				
			||||||
    pub fn try_reserve_exact(
 | 
					 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        len: usize,
 | 
					 | 
				
			||||||
        additional: usize,
 | 
					 | 
				
			||||||
    ) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        if self.needs_to_grow(len, additional) {
 | 
					 | 
				
			||||||
            self.grow_exact(len, additional)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            // Inform the optimizer that the reservation has succeeded or wasn't needed
 | 
					 | 
				
			||||||
            hint::assert_unchecked(!self.needs_to_grow(len, additional));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Shrinks the buffer down to the specified capacity. If the given amount
 | 
					 | 
				
			||||||
    /// is 0, actually completely deallocates.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panics
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Panics if the given amount is *larger* than the current capacity.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Aborts
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Aborts on OOM.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    pub fn shrink_to_fit(&mut self, cap: usize) {
 | 
					 | 
				
			||||||
        handle_reserve(self.shrink(cap));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, A: Allocator> RawVec<T, A> {
 | 
					 | 
				
			||||||
    /// Returns if the buffer needs to grow to fulfill the needed extra capacity.
 | 
					 | 
				
			||||||
    /// Mainly used to make inlining reserve-calls possible without inlining `grow`.
 | 
					 | 
				
			||||||
    fn needs_to_grow(&self, len: usize, additional: usize) -> bool {
 | 
					 | 
				
			||||||
        additional > self.capacity().wrapping_sub(len)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// # Safety:
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// `cap` must not exceed `isize::MAX`.
 | 
					 | 
				
			||||||
    unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) {
 | 
					 | 
				
			||||||
        // Allocators currently return a `NonNull<[u8]>` whose length matches
 | 
					 | 
				
			||||||
        // the size requested. If that ever changes, the capacity here should
 | 
					 | 
				
			||||||
        // change to `ptr.len() / mem::size_of::<T>()`.
 | 
					 | 
				
			||||||
        self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) };
 | 
					 | 
				
			||||||
        self.cap = unsafe { Cap(cap) };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // This method is usually instantiated many times. So we want it to be as
 | 
					 | 
				
			||||||
    // small as possible, to improve compile times. But we also want as much of
 | 
					 | 
				
			||||||
    // its contents to be statically computable as possible, to make the
 | 
					 | 
				
			||||||
    // generated code run faster. Therefore, this method is carefully written
 | 
					 | 
				
			||||||
    // so that all of the code that depends on `T` is within it, while as much
 | 
					 | 
				
			||||||
    // of the code that doesn't depend on `T` as possible is in functions that
 | 
					 | 
				
			||||||
    // are non-generic over `T`.
 | 
					 | 
				
			||||||
    fn grow_amortized(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        // This is ensured by the calling contexts.
 | 
					 | 
				
			||||||
        debug_assert!(additional > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            // Since we return a capacity of `usize::MAX` when `elem_size` is
 | 
					 | 
				
			||||||
            // 0, getting to here necessarily means the `RawVec` is overfull.
 | 
					 | 
				
			||||||
            return Err(CapacityOverflow.into());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Nothing we can really do about these checks, sadly.
 | 
					 | 
				
			||||||
        let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // This guarantees exponential growth. The doubling cannot overflow
 | 
					 | 
				
			||||||
        // because `cap <= isize::MAX` and the type of `cap` is `usize`.
 | 
					 | 
				
			||||||
        let cap = cmp::max(self.cap.0 * 2, required_cap);
 | 
					 | 
				
			||||||
        let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let new_layout = Layout::array::<T>(cap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // `finish_grow` is non-generic over `T`.
 | 
					 | 
				
			||||||
        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
 | 
					 | 
				
			||||||
        // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items
 | 
					 | 
				
			||||||
        unsafe { self.set_ptr_and_cap(ptr, cap) };
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // The constraints on this method are much the same as those on
 | 
					 | 
				
			||||||
    // `grow_amortized`, but this method is usually instantiated less often so
 | 
					 | 
				
			||||||
    // it's less critical.
 | 
					 | 
				
			||||||
    fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            // Since we return a capacity of `usize::MAX` when the type size is
 | 
					 | 
				
			||||||
            // 0, getting to here necessarily means the `RawVec` is overfull.
 | 
					 | 
				
			||||||
            return Err(CapacityOverflow.into());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
 | 
					 | 
				
			||||||
        let new_layout = Layout::array::<T>(cap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // `finish_grow` is non-generic over `T`.
 | 
					 | 
				
			||||||
        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
 | 
					 | 
				
			||||||
        // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than isize::MAX items
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            self.set_ptr_and_cap(ptr, cap);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
 | 
					 | 
				
			||||||
        // See current_memory() why this assert is here
 | 
					 | 
				
			||||||
        let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // If shrinking to 0, deallocate the buffer. We don't reach this point
 | 
					 | 
				
			||||||
        // for the T::IS_ZST case since current_memory() will have returned
 | 
					 | 
				
			||||||
        // None.
 | 
					 | 
				
			||||||
        if cap == 0 {
 | 
					 | 
				
			||||||
            unsafe { self.alloc.deallocate(ptr, layout) };
 | 
					 | 
				
			||||||
            self.ptr = Unique::dangling();
 | 
					 | 
				
			||||||
            self.cap = Cap::ZERO;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            let ptr = unsafe {
 | 
					 | 
				
			||||||
                // `Layout::array` cannot overflow here because it would have
 | 
					 | 
				
			||||||
                // overflowed earlier when capacity was larger.
 | 
					 | 
				
			||||||
                let new_size = mem::size_of::<T>().unchecked_mul(cap);
 | 
					 | 
				
			||||||
                let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
 | 
					 | 
				
			||||||
                self.alloc
 | 
					 | 
				
			||||||
                    .shrink(ptr, layout, new_layout)
 | 
					 | 
				
			||||||
                    .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            // SAFETY: if the allocation is valid, then the capacity is too
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                self.set_ptr_and_cap(ptr, cap);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This function is outside `RawVec` to minimize compile times. See the comment
 | 
					 | 
				
			||||||
// above `RawVec::grow_amortized` for details. (The `A` parameter isn't
 | 
					 | 
				
			||||||
// significant, because the number of different `A` types seen in practice is
 | 
					 | 
				
			||||||
// much smaller than the number of `T` types.)
 | 
					 | 
				
			||||||
#[inline(never)]
 | 
					 | 
				
			||||||
fn finish_grow<A>(
 | 
					 | 
				
			||||||
    new_layout: Result<Layout, LayoutError>,
 | 
					 | 
				
			||||||
    current_memory: Option<(NonNull<u8>, Layout)>,
 | 
					 | 
				
			||||||
    alloc: &mut A,
 | 
					 | 
				
			||||||
) -> Result<NonNull<[u8]>, TryReserveError>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    A: Allocator,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Check for the error here to minimize the size of `RawVec::grow_*`.
 | 
					 | 
				
			||||||
    let new_layout = new_layout.map_err(|_| CapacityOverflow)?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alloc_guard(new_layout.size())?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let memory = if let Some((ptr, old_layout)) = current_memory {
 | 
					 | 
				
			||||||
        debug_assert_eq!(old_layout.align(), new_layout.align());
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            // The allocator checks for alignment equality
 | 
					 | 
				
			||||||
            hint::assert_unchecked(old_layout.align() == new_layout.align());
 | 
					 | 
				
			||||||
            alloc.grow(ptr, old_layout, new_layout)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        alloc.allocate(new_layout)
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () }.into())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
 | 
					 | 
				
			||||||
    /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        if let Some((ptr, layout)) = self.current_memory() {
 | 
					 | 
				
			||||||
            unsafe { self.alloc.deallocate(ptr, layout) }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Central function for reserve error handling.
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn handle_reserve(result: Result<(), TryReserveError>) {
 | 
					 | 
				
			||||||
    match result.map_err(|e| e.kind()) {
 | 
					 | 
				
			||||||
        Err(CapacityOverflow) => capacity_overflow(),
 | 
					 | 
				
			||||||
        Err(AllocError { layout, .. }) => handle_alloc_error(layout),
 | 
					 | 
				
			||||||
        Ok(()) => { /* yay */ }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// We need to guarantee the following:
 | 
					 | 
				
			||||||
// * We don't ever allocate `> isize::MAX` byte-size objects.
 | 
					 | 
				
			||||||
// * We don't overflow `usize::MAX` and actually allocate too little.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// On 64-bit we just need to check for overflow since trying to allocate
 | 
					 | 
				
			||||||
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
 | 
					 | 
				
			||||||
// an extra guard for this in case we're running on a platform which can use
 | 
					 | 
				
			||||||
// all 4GB in user-space, e.g., PAE or x32.
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
    if usize::BITS < 64 && alloc_size > isize::MAX as usize {
 | 
					 | 
				
			||||||
        Err(CapacityOverflow.into())
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// One central function responsible for reporting capacity overflows. This'll
 | 
					 | 
				
			||||||
// ensure that the code generation related to these panics is minimal as there's
 | 
					 | 
				
			||||||
// only one location which panics rather than a bunch throughout the module.
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 | 
					 | 
				
			||||||
fn capacity_overflow() -> ! {
 | 
					 | 
				
			||||||
    panic!("capacity overflow");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,890 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//! Utilities for the slice primitive type.
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! *[See also the slice primitive type](slice).*
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! Most of the structs in this module are iterator types which can only be created
 | 
					 | 
				
			||||||
//! using a certain function. For example, `slice.iter()` yields an [`Iter`].
 | 
					 | 
				
			||||||
//!
 | 
					 | 
				
			||||||
//! A few functions are provided to create a slice from a value reference
 | 
					 | 
				
			||||||
//! or from a raw pointer.
 | 
					 | 
				
			||||||
#![stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
// Many of the usings in this module are only used in the test configuration.
 | 
					 | 
				
			||||||
// It's cleaner to just turn off the unused_imports warning than to fix them.
 | 
					 | 
				
			||||||
#![cfg_attr(test, allow(unused_imports, dead_code))]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use core::borrow::{Borrow, BorrowMut};
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use core::cmp::Ordering::{self, Less};
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use core::mem::{self, SizedTypeProperties};
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use core::ptr;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use core::slice::sort;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::Allocator;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use crate::alloc::{self, Global};
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use crate::borrow::ToOwned;
 | 
					 | 
				
			||||||
use crate::boxed::Box;
 | 
					 | 
				
			||||||
use crate::vec::Vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_range", issue = "76393")]
 | 
					 | 
				
			||||||
pub use core::slice::range;
 | 
					 | 
				
			||||||
#[unstable(feature = "array_chunks", issue = "74985")]
 | 
					 | 
				
			||||||
pub use core::slice::ArrayChunks;
 | 
					 | 
				
			||||||
#[unstable(feature = "array_chunks", issue = "74985")]
 | 
					 | 
				
			||||||
pub use core::slice::ArrayChunksMut;
 | 
					 | 
				
			||||||
#[unstable(feature = "array_windows", issue = "75027")]
 | 
					 | 
				
			||||||
pub use core::slice::ArrayWindows;
 | 
					 | 
				
			||||||
#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
 | 
					 | 
				
			||||||
pub use core::slice::EscapeAscii;
 | 
					 | 
				
			||||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
 | 
					 | 
				
			||||||
pub use core::slice::SliceIndex;
 | 
					 | 
				
			||||||
#[stable(feature = "from_ref", since = "1.28.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{from_mut, from_ref};
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_from_ptr_range", issue = "89792")]
 | 
					 | 
				
			||||||
pub use core::slice::{from_mut_ptr_range, from_ptr_range};
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 | 
					 | 
				
			||||||
#[stable(feature = "slice_group_by", since = "1.77.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{ChunkBy, ChunkByMut};
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{Chunks, Windows};
 | 
					 | 
				
			||||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{ChunksExact, ChunksExactMut};
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{ChunksMut, Split, SplitMut};
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{Iter, IterMut};
 | 
					 | 
				
			||||||
#[stable(feature = "rchunks", since = "1.31.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
 | 
					 | 
				
			||||||
#[stable(feature = "slice_rsplit", since = "1.27.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{RSplit, RSplitMut};
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{RSplitN, RSplitNMut, SplitN, SplitNMut};
 | 
					 | 
				
			||||||
#[stable(feature = "split_inclusive", since = "1.51.0")]
 | 
					 | 
				
			||||||
pub use core::slice::{SplitInclusive, SplitInclusiveMut};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
// Basic slice extension methods
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HACK(japaric) needed for the implementation of `vec!` macro during testing
 | 
					 | 
				
			||||||
// N.B., see the `hack` module in this file for more details.
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
pub use hack::into_vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HACK(japaric) needed for the implementation of `Vec::clone` during testing
 | 
					 | 
				
			||||||
// N.B., see the `hack` module in this file for more details.
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
pub use hack::to_vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HACK(japaric): With cfg(test) `impl [T]` is not available, these three
 | 
					 | 
				
			||||||
// functions are actually methods that are in `impl [T]` but not in
 | 
					 | 
				
			||||||
// `core::slice::SliceExt` - we need to supply these functions for the
 | 
					 | 
				
			||||||
// `test_permutations` test
 | 
					 | 
				
			||||||
pub(crate) mod hack {
 | 
					 | 
				
			||||||
    use core::alloc::Allocator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    use crate::boxed::Box;
 | 
					 | 
				
			||||||
    use crate::vec::Vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // We shouldn't add inline attribute to this since this is used in
 | 
					 | 
				
			||||||
    // `vec!` macro mostly and causes perf regression. See #71204 for
 | 
					 | 
				
			||||||
    // discussion and perf results.
 | 
					 | 
				
			||||||
    pub fn into_vec<T, A: Allocator>(b: Box<[T], A>) -> Vec<T, A> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let len = b.len();
 | 
					 | 
				
			||||||
            let (b, alloc) = Box::into_raw_with_allocator(b);
 | 
					 | 
				
			||||||
            Vec::from_raw_parts_in(b as *mut T, len, len, alloc)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn to_vec<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> {
 | 
					 | 
				
			||||||
        T::to_vec(s, alloc)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    pub trait ConvertVec {
 | 
					 | 
				
			||||||
        fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A>
 | 
					 | 
				
			||||||
        where
 | 
					 | 
				
			||||||
            Self: Sized;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    impl<T: Clone> ConvertVec for T {
 | 
					 | 
				
			||||||
        #[inline]
 | 
					 | 
				
			||||||
        default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
 | 
					 | 
				
			||||||
            struct DropGuard<'a, T, A: Allocator> {
 | 
					 | 
				
			||||||
                vec: &'a mut Vec<T, A>,
 | 
					 | 
				
			||||||
                num_init: usize,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
 | 
					 | 
				
			||||||
                #[inline]
 | 
					 | 
				
			||||||
                fn drop(&mut self) {
 | 
					 | 
				
			||||||
                    // SAFETY:
 | 
					 | 
				
			||||||
                    // items were marked initialized in the loop below
 | 
					 | 
				
			||||||
                    unsafe {
 | 
					 | 
				
			||||||
                        self.vec.set_len(self.num_init);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            let mut vec = Vec::with_capacity_in(s.len(), alloc);
 | 
					 | 
				
			||||||
            let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
 | 
					 | 
				
			||||||
            let slots = guard.vec.spare_capacity_mut();
 | 
					 | 
				
			||||||
            // .take(slots.len()) is necessary for LLVM to remove bounds checks
 | 
					 | 
				
			||||||
            // and has better codegen than zip.
 | 
					 | 
				
			||||||
            for (i, b) in s.iter().enumerate().take(slots.len()) {
 | 
					 | 
				
			||||||
                guard.num_init = i;
 | 
					 | 
				
			||||||
                slots[i].write(b.clone());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            core::mem::forget(guard);
 | 
					 | 
				
			||||||
            // SAFETY:
 | 
					 | 
				
			||||||
            // the vec was allocated and initialized above to at least this length.
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                vec.set_len(s.len());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            vec
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    impl<T: Copy> ConvertVec for T {
 | 
					 | 
				
			||||||
        #[inline]
 | 
					 | 
				
			||||||
        fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
 | 
					 | 
				
			||||||
            let mut v = Vec::with_capacity_in(s.len(), alloc);
 | 
					 | 
				
			||||||
            // SAFETY:
 | 
					 | 
				
			||||||
            // allocated above with the capacity of `s`, and initialize to `s.len()` in
 | 
					 | 
				
			||||||
            // ptr::copy_to_non_overlapping below.
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
 | 
					 | 
				
			||||||
                v.set_len(s.len());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            v
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
impl<T> [T] {
 | 
					 | 
				
			||||||
    /// Sorts the slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// 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`](slice::sort_unstable).
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Current implementation
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The current algorithm is an adaptive, iterative merge sort inspired by
 | 
					 | 
				
			||||||
    /// [timsort](https://en.wikipedia.org/wiki/Timsort).
 | 
					 | 
				
			||||||
    /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of
 | 
					 | 
				
			||||||
    /// two or more sorted sequences concatenated one after another.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Also, it allocates temporary storage half the size of `self`, but for short slices a
 | 
					 | 
				
			||||||
    /// non-allocating insertion sort is used instead.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut v = [-5, 4, 1, -3, 2];
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// v.sort();
 | 
					 | 
				
			||||||
    /// assert!(v == [-5, -3, 1, 2, 4]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn sort(&mut self)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        T: Ord,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        stable_sort(self, T::lt);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Sorts the slice with a comparator function.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The comparator function must define a total ordering for the elements in the slice. If
 | 
					 | 
				
			||||||
    /// the ordering is not total, the order of the elements is unspecified. An order is a
 | 
					 | 
				
			||||||
    /// total order if it is (for all `a`, `b` and `c`):
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
 | 
					 | 
				
			||||||
    /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
 | 
					 | 
				
			||||||
    /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
 | 
					 | 
				
			||||||
    /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
 | 
					 | 
				
			||||||
    /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// 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`](slice::sort_unstable_by).
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Current implementation
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The current algorithm is an adaptive, iterative merge sort inspired by
 | 
					 | 
				
			||||||
    /// [timsort](https://en.wikipedia.org/wiki/Timsort).
 | 
					 | 
				
			||||||
    /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of
 | 
					 | 
				
			||||||
    /// two or more sorted sequences concatenated one after another.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Also, it allocates temporary storage half the size of `self`, but for short slices a
 | 
					 | 
				
			||||||
    /// non-allocating insertion sort is used instead.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut v = [5, 4, 1, 3, 2];
 | 
					 | 
				
			||||||
    /// v.sort_by(|a, b| a.cmp(b));
 | 
					 | 
				
			||||||
    /// assert!(v == [1, 2, 3, 4, 5]);
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// // reverse sorting
 | 
					 | 
				
			||||||
    /// v.sort_by(|a, b| b.cmp(a));
 | 
					 | 
				
			||||||
    /// assert!(v == [5, 4, 3, 2, 1]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn sort_by<F>(&mut self, mut compare: F)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        F: FnMut(&T, &T) -> Ordering,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        stable_sort(self, |a, b| compare(a, b) == Less);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Sorts the slice with a key extraction function.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
 | 
					 | 
				
			||||||
    /// worst-case, where the key function is *O*(*m*).
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// For expensive key functions (e.g. functions that are not simple property accesses or
 | 
					 | 
				
			||||||
    /// basic operations), [`sort_by_cached_key`](slice::sort_by_cached_key) is likely to be
 | 
					 | 
				
			||||||
    /// significantly faster, as it does not recompute element keys.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// 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`](slice::sort_unstable_by_key).
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Current implementation
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The current algorithm is an adaptive, iterative merge sort inspired by
 | 
					 | 
				
			||||||
    /// [timsort](https://en.wikipedia.org/wiki/Timsort).
 | 
					 | 
				
			||||||
    /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of
 | 
					 | 
				
			||||||
    /// two or more sorted sequences concatenated one after another.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Also, it allocates temporary storage half the size of `self`, but for short slices a
 | 
					 | 
				
			||||||
    /// non-allocating insertion sort is used instead.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut v = [-5i32, 4, 1, -3, 2];
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// v.sort_by_key(|k| k.abs());
 | 
					 | 
				
			||||||
    /// assert!(v == [1, 2, -3, 4, -5]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "slice_sort_by_key", since = "1.7.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn sort_by_key<K, F>(&mut self, mut f: F)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        F: FnMut(&T) -> K,
 | 
					 | 
				
			||||||
        K: Ord,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        stable_sort(self, |a, b| f(a).lt(&f(b)));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Sorts the slice with a key extraction function.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// During sorting, the key function is called at most once per element, by using
 | 
					 | 
				
			||||||
    /// temporary storage to remember the results of key evaluation.
 | 
					 | 
				
			||||||
    /// The order of calls to the key function is unspecified and may change in future versions
 | 
					 | 
				
			||||||
    /// of the standard library.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* + *n* \* log(*n*))
 | 
					 | 
				
			||||||
    /// worst-case, where the key function is *O*(*m*).
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// For simple key functions (e.g., functions that are property accesses or
 | 
					 | 
				
			||||||
    /// basic operations), [`sort_by_key`](slice::sort_by_key) is likely to be
 | 
					 | 
				
			||||||
    /// faster.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Current implementation
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
 | 
					 | 
				
			||||||
    /// which combines the fast average case of randomized quicksort with the fast worst case of
 | 
					 | 
				
			||||||
    /// heapsort, while achieving linear time on slices with certain patterns. It uses some
 | 
					 | 
				
			||||||
    /// randomization to avoid degenerate cases, but with a fixed seed to always provide
 | 
					 | 
				
			||||||
    /// deterministic behavior.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the
 | 
					 | 
				
			||||||
    /// length of the slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut v = [-5i32, 4, 32, -3, 2];
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// v.sort_by_cached_key(|k| k.to_string());
 | 
					 | 
				
			||||||
    /// assert!(v == [-3, -5, 2, 32, 4]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// [pdqsort]: https://github.com/orlp/pdqsort
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn sort_by_cached_key<K, F>(&mut self, f: F)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        F: FnMut(&T) -> K,
 | 
					 | 
				
			||||||
        K: Ord,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Helper macro for indexing our vector by the smallest possible type, to reduce allocation.
 | 
					 | 
				
			||||||
        macro_rules! sort_by_key {
 | 
					 | 
				
			||||||
            ($t:ty, $slice:ident, $f:ident) => {{
 | 
					 | 
				
			||||||
                let mut indices: Vec<_> =
 | 
					 | 
				
			||||||
                    $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect();
 | 
					 | 
				
			||||||
                // The elements of `indices` are unique, as they are indexed, so any sort will be
 | 
					 | 
				
			||||||
                // stable with respect to the original slice. We use `sort_unstable` here because
 | 
					 | 
				
			||||||
                // it requires less memory allocation.
 | 
					 | 
				
			||||||
                indices.sort_unstable();
 | 
					 | 
				
			||||||
                for i in 0..$slice.len() {
 | 
					 | 
				
			||||||
                    let mut index = indices[i].1;
 | 
					 | 
				
			||||||
                    while (index as usize) < i {
 | 
					 | 
				
			||||||
                        index = indices[index as usize].1;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    indices[i].1 = index;
 | 
					 | 
				
			||||||
                    $slice.swap(i, index as usize);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }};
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let sz_u8 = mem::size_of::<(K, u8)>();
 | 
					 | 
				
			||||||
        let sz_u16 = mem::size_of::<(K, u16)>();
 | 
					 | 
				
			||||||
        let sz_u32 = mem::size_of::<(K, u32)>();
 | 
					 | 
				
			||||||
        let sz_usize = mem::size_of::<(K, usize)>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let len = self.len();
 | 
					 | 
				
			||||||
        if len < 2 {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if sz_u8 < sz_u16 && len <= (u8::MAX as usize) {
 | 
					 | 
				
			||||||
            return sort_by_key!(u8, self, f);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if sz_u16 < sz_u32 && len <= (u16::MAX as usize) {
 | 
					 | 
				
			||||||
            return sort_by_key!(u16, self, f);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if sz_u32 < sz_usize && len <= (u32::MAX as usize) {
 | 
					 | 
				
			||||||
            return sort_by_key!(u32, self, f);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        sort_by_key!(usize, self, f)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Copies `self` into a new `Vec`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let s = [10, 40, 30];
 | 
					 | 
				
			||||||
    /// let x = s.to_vec();
 | 
					 | 
				
			||||||
    /// // Here, `s` and `x` can be modified independently.
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[rustc_conversion_suggestion]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn to_vec(&self) -> Vec<T>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        T: Clone,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        self.to_vec_in(Global)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Copies `self` into a new `Vec` with an allocator.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// #![feature(allocator_api)]
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// use std::alloc::System;
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let s = [10, 40, 30];
 | 
					 | 
				
			||||||
    /// let x = s.to_vec_in(System);
 | 
					 | 
				
			||||||
    /// // Here, `s` and `x` can be modified independently.
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
    pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        T: Clone,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // N.B., see the `hack` module in this file for more details.
 | 
					 | 
				
			||||||
        hack::to_vec(self, alloc)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Converts `self` into a vector without clones or allocation.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// The resulting vector can be converted back into a box via
 | 
					 | 
				
			||||||
    /// `Vec<T>`'s `into_boxed_slice` method.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let s: Box<[i32]> = Box::new([10, 40, 30]);
 | 
					 | 
				
			||||||
    /// let x = s.into_vec();
 | 
					 | 
				
			||||||
    /// // `s` cannot be used anymore because it has been converted into `x`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// assert_eq!(x, vec![10, 40, 30]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
 | 
					 | 
				
			||||||
        // N.B., see the `hack` module in this file for more details.
 | 
					 | 
				
			||||||
        hack::into_vec(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Creates a vector by copying a slice `n` times.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Panics
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This function will panic if the capacity would overflow.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Basic usage:
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// A panic upon overflow:
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```should_panic
 | 
					 | 
				
			||||||
    /// // this will panic at runtime
 | 
					 | 
				
			||||||
    /// b"0123456789abcdef".repeat(usize::MAX);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[stable(feature = "repeat_generic_slice", since = "1.40.0")]
 | 
					 | 
				
			||||||
    pub fn repeat(&self, n: usize) -> Vec<T>
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        T: Copy,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if n == 0 {
 | 
					 | 
				
			||||||
            return Vec::new();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // If `n` is larger than zero, it can be split as
 | 
					 | 
				
			||||||
        // `n = 2^expn + rem (2^expn > rem, expn >= 0, rem >= 0)`.
 | 
					 | 
				
			||||||
        // `2^expn` is the number represented by the leftmost '1' bit of `n`,
 | 
					 | 
				
			||||||
        // and `rem` is the remaining part of `n`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Using `Vec` to access `set_len()`.
 | 
					 | 
				
			||||||
        let capacity = self.len().checked_mul(n).expect("capacity overflow");
 | 
					 | 
				
			||||||
        let mut buf = Vec::with_capacity(capacity);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // `2^expn` repetition is done by doubling `buf` `expn`-times.
 | 
					 | 
				
			||||||
        buf.extend(self);
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            let mut m = n >> 1;
 | 
					 | 
				
			||||||
            // If `m > 0`, there are remaining bits up to the leftmost '1'.
 | 
					 | 
				
			||||||
            while m > 0 {
 | 
					 | 
				
			||||||
                // `buf.extend(buf)`:
 | 
					 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                    ptr::copy_nonoverlapping(
 | 
					 | 
				
			||||||
                        buf.as_ptr(),
 | 
					 | 
				
			||||||
                        (buf.as_mut_ptr() as *mut T).add(buf.len()),
 | 
					 | 
				
			||||||
                        buf.len(),
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                    // `buf` has capacity of `self.len() * n`.
 | 
					 | 
				
			||||||
                    let buf_len = buf.len();
 | 
					 | 
				
			||||||
                    buf.set_len(buf_len * 2);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                m >>= 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // `rem` (`= n - 2^expn`) repetition is done by copying
 | 
					 | 
				
			||||||
        // first `rem` repetitions from `buf` itself.
 | 
					 | 
				
			||||||
        let rem_len = capacity - buf.len(); // `self.len() * rem`
 | 
					 | 
				
			||||||
        if rem_len > 0 {
 | 
					 | 
				
			||||||
            // `buf.extend(buf[0 .. rem_len])`:
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                // This is non-overlapping since `2^expn > rem`.
 | 
					 | 
				
			||||||
                ptr::copy_nonoverlapping(
 | 
					 | 
				
			||||||
                    buf.as_ptr(),
 | 
					 | 
				
			||||||
                    (buf.as_mut_ptr() as *mut T).add(buf.len()),
 | 
					 | 
				
			||||||
                    rem_len,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                // `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`).
 | 
					 | 
				
			||||||
                buf.set_len(capacity);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        buf
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Flattens a slice of `T` into a single value `Self::Output`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// assert_eq!(["hello", "world"].concat(), "helloworld");
 | 
					 | 
				
			||||||
    /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: Concat<Item>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Concat::concat(self)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
 | 
					 | 
				
			||||||
    /// given separator between each.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// assert_eq!(["hello", "world"].join(" "), "hello world");
 | 
					 | 
				
			||||||
    /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
 | 
					 | 
				
			||||||
    /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rename_connect_to_join", since = "1.3.0")]
 | 
					 | 
				
			||||||
    pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: Join<Separator>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Join::join(self, sep)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
 | 
					 | 
				
			||||||
    /// given separator between each.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// # #![allow(deprecated)]
 | 
					 | 
				
			||||||
    /// assert_eq!(["hello", "world"].connect(" "), "hello world");
 | 
					 | 
				
			||||||
    /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
    #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")]
 | 
					 | 
				
			||||||
    pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: Join<Separator>,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Join::join(self, sep)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(test))]
 | 
					 | 
				
			||||||
impl [u8] {
 | 
					 | 
				
			||||||
    /// Returns a vector containing a copy of this slice where each byte
 | 
					 | 
				
			||||||
    /// is mapped to its ASCII upper case equivalent.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
 | 
					 | 
				
			||||||
    /// but non-ASCII letters are unchanged.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// To uppercase the value in-place, use [`make_ascii_uppercase`].
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[must_use = "this returns the uppercase bytes as a new Vec, \
 | 
					 | 
				
			||||||
                  without modifying the original"]
 | 
					 | 
				
			||||||
    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn to_ascii_uppercase(&self) -> Vec<u8> {
 | 
					 | 
				
			||||||
        let mut me = self.to_vec();
 | 
					 | 
				
			||||||
        me.make_ascii_uppercase();
 | 
					 | 
				
			||||||
        me
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns a vector containing a copy of this slice where each byte
 | 
					 | 
				
			||||||
    /// is mapped to its ASCII lower case equivalent.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
 | 
					 | 
				
			||||||
    /// but non-ASCII letters are unchanged.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// To lowercase the value in-place, use [`make_ascii_lowercase`].
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[rustc_allow_incoherent_impl]
 | 
					 | 
				
			||||||
    #[must_use = "this returns the lowercase bytes as a new Vec, \
 | 
					 | 
				
			||||||
                  without modifying the original"]
 | 
					 | 
				
			||||||
    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn to_ascii_lowercase(&self) -> Vec<u8> {
 | 
					 | 
				
			||||||
        let mut me = self.to_vec();
 | 
					 | 
				
			||||||
        me.make_ascii_lowercase();
 | 
					 | 
				
			||||||
        me
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
// Extension traits for slices over specific kinds of data
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Helper trait for [`[T]::concat`](slice::concat).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Note: the `Item` type parameter is not used in this trait,
 | 
					 | 
				
			||||||
/// but it allows impls to be more generic.
 | 
					 | 
				
			||||||
/// Without it, we get this error:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```error
 | 
					 | 
				
			||||||
/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica
 | 
					 | 
				
			||||||
///    --> library/alloc/src/slice.rs:608:6
 | 
					 | 
				
			||||||
///     |
 | 
					 | 
				
			||||||
/// 608 | impl<T: Clone, V: Borrow<[T]>> Concat for [V] {
 | 
					 | 
				
			||||||
///     |      ^ unconstrained type parameter
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls,
 | 
					 | 
				
			||||||
/// such that multiple `T` types would apply:
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// # #[allow(dead_code)]
 | 
					 | 
				
			||||||
/// pub struct Foo(Vec<u32>, Vec<String>);
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// impl std::borrow::Borrow<[u32]> for Foo {
 | 
					 | 
				
			||||||
///     fn borrow(&self) -> &[u32] { &self.0 }
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// impl std::borrow::Borrow<[String]> for Foo {
 | 
					 | 
				
			||||||
///     fn borrow(&self) -> &[String] { &self.1 }
 | 
					 | 
				
			||||||
/// }
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
pub trait Concat<Item: ?Sized> {
 | 
					 | 
				
			||||||
    #[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
    /// The resulting type after concatenation
 | 
					 | 
				
			||||||
    type Output;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Implementation of [`[T]::concat`](slice::concat)
 | 
					 | 
				
			||||||
    #[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
    fn concat(slice: &Self) -> Self::Output;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Helper trait for [`[T]::join`](slice::join)
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
pub trait Join<Separator> {
 | 
					 | 
				
			||||||
    #[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
    /// The resulting type after concatenation
 | 
					 | 
				
			||||||
    type Output;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Implementation of [`[T]::join`](slice::join)
 | 
					 | 
				
			||||||
    #[unstable(feature = "slice_concat_trait", issue = "27747")]
 | 
					 | 
				
			||||||
    fn join(slice: &Self, sep: Separator) -> Self::Output;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_concat_ext", issue = "27747")]
 | 
					 | 
				
			||||||
impl<T: Clone, V: Borrow<[T]>> Concat<T> for [V] {
 | 
					 | 
				
			||||||
    type Output = Vec<T>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn concat(slice: &Self) -> Vec<T> {
 | 
					 | 
				
			||||||
        let size = slice.iter().map(|slice| slice.borrow().len()).sum();
 | 
					 | 
				
			||||||
        let mut result = Vec::with_capacity(size);
 | 
					 | 
				
			||||||
        for v in slice {
 | 
					 | 
				
			||||||
            result.extend_from_slice(v.borrow())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_concat_ext", issue = "27747")]
 | 
					 | 
				
			||||||
impl<T: Clone, V: Borrow<[T]>> Join<&T> for [V] {
 | 
					 | 
				
			||||||
    type Output = Vec<T>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn join(slice: &Self, sep: &T) -> Vec<T> {
 | 
					 | 
				
			||||||
        let mut iter = slice.iter();
 | 
					 | 
				
			||||||
        let first = match iter.next() {
 | 
					 | 
				
			||||||
            Some(first) => first,
 | 
					 | 
				
			||||||
            None => return vec![],
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() + slice.len() - 1;
 | 
					 | 
				
			||||||
        let mut result = Vec::with_capacity(size);
 | 
					 | 
				
			||||||
        result.extend_from_slice(first.borrow());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for v in iter {
 | 
					 | 
				
			||||||
            result.push(sep.clone());
 | 
					 | 
				
			||||||
            result.extend_from_slice(v.borrow())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[unstable(feature = "slice_concat_ext", issue = "27747")]
 | 
					 | 
				
			||||||
impl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] {
 | 
					 | 
				
			||||||
    type Output = Vec<T>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn join(slice: &Self, sep: &[T]) -> Vec<T> {
 | 
					 | 
				
			||||||
        let mut iter = slice.iter();
 | 
					 | 
				
			||||||
        let first = match iter.next() {
 | 
					 | 
				
			||||||
            Some(first) => first,
 | 
					 | 
				
			||||||
            None => return vec![],
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        let size =
 | 
					 | 
				
			||||||
            slice.iter().map(|v| v.borrow().len()).sum::<usize>() + sep.len() * (slice.len() - 1);
 | 
					 | 
				
			||||||
        let mut result = Vec::with_capacity(size);
 | 
					 | 
				
			||||||
        result.extend_from_slice(first.borrow());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for v in iter {
 | 
					 | 
				
			||||||
            result.extend_from_slice(sep);
 | 
					 | 
				
			||||||
            result.extend_from_slice(v.borrow())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
// Standard trait implementations for slices
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> Borrow<[T]> for Vec<T, A> {
 | 
					 | 
				
			||||||
    fn borrow(&self) -> &[T] {
 | 
					 | 
				
			||||||
        &self[..]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> BorrowMut<[T]> for Vec<T, A> {
 | 
					 | 
				
			||||||
    fn borrow_mut(&mut self) -> &mut [T] {
 | 
					 | 
				
			||||||
        &mut self[..]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Specializable trait for implementing ToOwned::clone_into. This is
 | 
					 | 
				
			||||||
// public in the crate and has the Allocator parameter so that
 | 
					 | 
				
			||||||
// vec::clone_from use it too.
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
pub(crate) trait SpecCloneIntoVec<T, A: Allocator> {
 | 
					 | 
				
			||||||
    fn clone_into(&self, target: &mut Vec<T, A>);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T: Clone, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
 | 
					 | 
				
			||||||
    default fn clone_into(&self, target: &mut Vec<T, A>) {
 | 
					 | 
				
			||||||
        // drop anything in target that will not be overwritten
 | 
					 | 
				
			||||||
        target.truncate(self.len());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // target.len <= self.len due to the truncate above, so the
 | 
					 | 
				
			||||||
        // slices here are always in-bounds.
 | 
					 | 
				
			||||||
        let (init, tail) = self.split_at(target.len());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // reuse the contained values' allocations/resources.
 | 
					 | 
				
			||||||
        target.clone_from_slice(init);
 | 
					 | 
				
			||||||
        target.extend_from_slice(tail);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
 | 
					 | 
				
			||||||
    fn clone_into(&self, target: &mut Vec<T, A>) {
 | 
					 | 
				
			||||||
        target.clear();
 | 
					 | 
				
			||||||
        target.extend_from_slice(self);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T: Clone> ToOwned for [T] {
 | 
					 | 
				
			||||||
    type Owned = Vec<T>;
 | 
					 | 
				
			||||||
    #[cfg(not(test))]
 | 
					 | 
				
			||||||
    fn to_owned(&self) -> Vec<T> {
 | 
					 | 
				
			||||||
        self.to_vec()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(test)]
 | 
					 | 
				
			||||||
    fn to_owned(&self) -> Vec<T> {
 | 
					 | 
				
			||||||
        hack::to_vec(self, Global)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn clone_into(&self, target: &mut Vec<T>) {
 | 
					 | 
				
			||||||
        SpecCloneIntoVec::clone_into(self, target);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
// Sorting
 | 
					 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[inline]
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
fn stable_sort<T, F>(v: &mut [T], mut is_less: F)
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    F: FnMut(&T, &T) -> bool,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if T::IS_ZST {
 | 
					 | 
				
			||||||
        // Sorting has no meaningful behavior on zero-sized types. Do nothing.
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let elem_alloc_fn = |len: usize| -> *mut T {
 | 
					 | 
				
			||||||
        // SAFETY: Creating the layout is safe as long as merge_sort never calls this with len >
 | 
					 | 
				
			||||||
        // v.len(). Alloc in general will only be used as 'shadow-region' to store temporary swap
 | 
					 | 
				
			||||||
        // elements.
 | 
					 | 
				
			||||||
        unsafe { alloc::alloc(alloc::Layout::array::<T>(len).unwrap_unchecked()) as *mut T }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let elem_dealloc_fn = |buf_ptr: *mut T, len: usize| {
 | 
					 | 
				
			||||||
        // SAFETY: Creating the layout is safe as long as merge_sort never calls this with len >
 | 
					 | 
				
			||||||
        // v.len(). The caller must ensure that buf_ptr was created by elem_alloc_fn with the same
 | 
					 | 
				
			||||||
        // len.
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            alloc::dealloc(buf_ptr as *mut u8, alloc::Layout::array::<T>(len).unwrap_unchecked());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let run_alloc_fn = |len: usize| -> *mut sort::TimSortRun {
 | 
					 | 
				
			||||||
        // SAFETY: Creating the layout is safe as long as merge_sort never calls this with an
 | 
					 | 
				
			||||||
        // obscene length or 0.
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            alloc::alloc(alloc::Layout::array::<sort::TimSortRun>(len).unwrap_unchecked())
 | 
					 | 
				
			||||||
                as *mut sort::TimSortRun
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let run_dealloc_fn = |buf_ptr: *mut sort::TimSortRun, len: usize| {
 | 
					 | 
				
			||||||
        // SAFETY: The caller must ensure that buf_ptr was created by elem_alloc_fn with the same
 | 
					 | 
				
			||||||
        // len.
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            alloc::dealloc(
 | 
					 | 
				
			||||||
                buf_ptr as *mut u8,
 | 
					 | 
				
			||||||
                alloc::Layout::array::<sort::TimSortRun>(len).unwrap_unchecked(),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sort::merge_sort(v, &mut is_less, elem_alloc_fn, elem_dealloc_fn, run_alloc_fn, run_dealloc_fn);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,255 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::{Allocator, Global};
 | 
					 | 
				
			||||||
use core::fmt;
 | 
					 | 
				
			||||||
use core::iter::{FusedIterator, TrustedLen};
 | 
					 | 
				
			||||||
use core::mem::{self, ManuallyDrop, SizedTypeProperties};
 | 
					 | 
				
			||||||
use core::ptr::{self, NonNull};
 | 
					 | 
				
			||||||
use core::slice::{self};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use super::Vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// A draining iterator for `Vec<T>`.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This `struct` is created by [`Vec::drain`].
 | 
					 | 
				
			||||||
/// See its documentation for more.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Example
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// let mut v = vec![0, 1, 2];
 | 
					 | 
				
			||||||
/// let iter: std::vec::Drain<'_, _> = v.drain(..);
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
pub struct Drain<
 | 
					 | 
				
			||||||
    'a,
 | 
					 | 
				
			||||||
    T: 'a,
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
 | 
					 | 
				
			||||||
> {
 | 
					 | 
				
			||||||
    /// Index of tail to preserve
 | 
					 | 
				
			||||||
    pub(super) tail_start: usize,
 | 
					 | 
				
			||||||
    /// Length of tail
 | 
					 | 
				
			||||||
    pub(super) tail_len: usize,
 | 
					 | 
				
			||||||
    /// Current remaining range to remove
 | 
					 | 
				
			||||||
    pub(super) iter: slice::Iter<'a, T>,
 | 
					 | 
				
			||||||
    pub(super) vec: NonNull<Vec<T, A>>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "collection_debug", since = "1.17.0")]
 | 
					 | 
				
			||||||
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
					 | 
				
			||||||
        f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a, T, A: Allocator> Drain<'a, T, A> {
 | 
					 | 
				
			||||||
    /// Returns the remaining items of this iterator as a slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let mut vec = vec!['a', 'b', 'c'];
 | 
					 | 
				
			||||||
    /// let mut drain = vec.drain(..);
 | 
					 | 
				
			||||||
    /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
 | 
					 | 
				
			||||||
    /// let _ = drain.next().unwrap();
 | 
					 | 
				
			||||||
    /// assert_eq!(drain.as_slice(), &['b', 'c']);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
 | 
					 | 
				
			||||||
    pub fn as_slice(&self) -> &[T] {
 | 
					 | 
				
			||||||
        self.iter.as_slice()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns a reference to the underlying allocator.
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
    #[must_use]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn allocator(&self) -> &A {
 | 
					 | 
				
			||||||
        unsafe { self.vec.as_ref().allocator() }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Keep unyielded elements in the source `Vec`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// #![feature(drain_keep_rest)]
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// let mut vec = vec!['a', 'b', 'c'];
 | 
					 | 
				
			||||||
    /// let mut drain = vec.drain(..);
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// assert_eq!(drain.next().unwrap(), 'a');
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// // This call keeps 'b' and 'c' in the vec.
 | 
					 | 
				
			||||||
    /// drain.keep_rest();
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// // If we wouldn't call `keep_rest()`,
 | 
					 | 
				
			||||||
    /// // `vec` would be empty.
 | 
					 | 
				
			||||||
    /// assert_eq!(vec, ['b', 'c']);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[unstable(feature = "drain_keep_rest", issue = "101122")]
 | 
					 | 
				
			||||||
    pub fn keep_rest(self) {
 | 
					 | 
				
			||||||
        // At this moment layout looks like this:
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // [head] [yielded by next] [unyielded] [yielded by next_back] [tail]
 | 
					 | 
				
			||||||
        //        ^-- start         \_________/-- unyielded_len        \____/-- self.tail_len
 | 
					 | 
				
			||||||
        //                          ^-- unyielded_ptr                  ^-- tail
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // Normally `Drop` impl would drop [unyielded] and then move [tail] to the `start`.
 | 
					 | 
				
			||||||
        // Here we want to
 | 
					 | 
				
			||||||
        // 1. Move [unyielded] to `start`
 | 
					 | 
				
			||||||
        // 2. Move [tail] to a new start at `start + len(unyielded)`
 | 
					 | 
				
			||||||
        // 3. Update length of the original vec to `len(head) + len(unyielded) + len(tail)`
 | 
					 | 
				
			||||||
        //    a. In case of ZST, this is the only thing we want to do
 | 
					 | 
				
			||||||
        // 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
 | 
					 | 
				
			||||||
        let mut this = ManuallyDrop::new(self);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let source_vec = this.vec.as_mut();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let start = source_vec.len();
 | 
					 | 
				
			||||||
            let tail = this.tail_start;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let unyielded_len = this.iter.len();
 | 
					 | 
				
			||||||
            let unyielded_ptr = this.iter.as_slice().as_ptr();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // ZSTs have no identity, so we don't need to move them around.
 | 
					 | 
				
			||||||
            if !T::IS_ZST {
 | 
					 | 
				
			||||||
                let start_ptr = source_vec.as_mut_ptr().add(start);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // memmove back unyielded elements
 | 
					 | 
				
			||||||
                if unyielded_ptr != start_ptr {
 | 
					 | 
				
			||||||
                    let src = unyielded_ptr;
 | 
					 | 
				
			||||||
                    let dst = start_ptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    ptr::copy(src, dst, unyielded_len);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // memmove back untouched tail
 | 
					 | 
				
			||||||
                if tail != (start + unyielded_len) {
 | 
					 | 
				
			||||||
                    let src = source_vec.as_ptr().add(tail);
 | 
					 | 
				
			||||||
                    let dst = start_ptr.add(unyielded_len);
 | 
					 | 
				
			||||||
                    ptr::copy(src, dst, this.tail_len);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            source_vec.set_len(start + unyielded_len + this.tail_len);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
 | 
					 | 
				
			||||||
impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> {
 | 
					 | 
				
			||||||
    fn as_ref(&self) -> &[T] {
 | 
					 | 
				
			||||||
        self.as_slice()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {}
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
 | 
					 | 
				
			||||||
    type Item = T;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<T> {
 | 
					 | 
				
			||||||
        self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn size_hint(&self) -> (usize, Option<usize>) {
 | 
					 | 
				
			||||||
        self.iter.size_hint()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next_back(&mut self) -> Option<T> {
 | 
					 | 
				
			||||||
        self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> Drop for Drain<'_, T, A> {
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        /// Moves back the un-`Drain`ed elements to restore the original `Vec`.
 | 
					 | 
				
			||||||
        struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
 | 
					 | 
				
			||||||
            fn drop(&mut self) {
 | 
					 | 
				
			||||||
                if self.0.tail_len > 0 {
 | 
					 | 
				
			||||||
                    unsafe {
 | 
					 | 
				
			||||||
                        let source_vec = self.0.vec.as_mut();
 | 
					 | 
				
			||||||
                        // memmove back untouched tail, update to new length
 | 
					 | 
				
			||||||
                        let start = source_vec.len();
 | 
					 | 
				
			||||||
                        let tail = self.0.tail_start;
 | 
					 | 
				
			||||||
                        if tail != start {
 | 
					 | 
				
			||||||
                            let src = source_vec.as_ptr().add(tail);
 | 
					 | 
				
			||||||
                            let dst = source_vec.as_mut_ptr().add(start);
 | 
					 | 
				
			||||||
                            ptr::copy(src, dst, self.0.tail_len);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        source_vec.set_len(start + self.0.tail_len);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let iter = mem::take(&mut self.iter);
 | 
					 | 
				
			||||||
        let drop_len = iter.len();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut vec = self.vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            // ZSTs have no identity, so we don't need to move them around, we only need to drop the correct amount.
 | 
					 | 
				
			||||||
            // this can be achieved by manipulating the Vec length instead of moving values out from `iter`.
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                let vec = vec.as_mut();
 | 
					 | 
				
			||||||
                let old_len = vec.len();
 | 
					 | 
				
			||||||
                vec.set_len(old_len + drop_len + self.tail_len);
 | 
					 | 
				
			||||||
                vec.truncate(old_len + self.tail_len);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // ensure elements are moved back into their appropriate places, even when drop_in_place panics
 | 
					 | 
				
			||||||
        let _guard = DropGuard(self);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if drop_len == 0 {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // as_slice() must only be called when iter.len() is > 0 because
 | 
					 | 
				
			||||||
        // it also gets touched by vec::Splice which may turn it into a dangling pointer
 | 
					 | 
				
			||||||
        // which would make it and the vec pointer point to different allocations which would
 | 
					 | 
				
			||||||
        // lead to invalid pointer arithmetic below.
 | 
					 | 
				
			||||||
        let drop_ptr = iter.as_slice().as_ptr();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place
 | 
					 | 
				
			||||||
            // a pointer with mutable provenance is necessary. Therefore we must reconstruct
 | 
					 | 
				
			||||||
            // it from the original vec but also avoid creating a &mut to the front since that could
 | 
					 | 
				
			||||||
            // invalidate raw pointers to it which some unsafe code might rely on.
 | 
					 | 
				
			||||||
            let vec_ptr = vec.as_mut().as_mut_ptr();
 | 
					 | 
				
			||||||
            let drop_offset = drop_ptr.sub_ptr(vec_ptr);
 | 
					 | 
				
			||||||
            let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
 | 
					 | 
				
			||||||
            ptr::drop_in_place(to_drop);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "drain", since = "1.6.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
 | 
					 | 
				
			||||||
    fn is_empty(&self) -> bool {
 | 
					 | 
				
			||||||
        self.iter.is_empty()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "trusted_len", issue = "37572")]
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "fused", since = "1.26.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,115 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::{Allocator, Global};
 | 
					 | 
				
			||||||
use core::ptr;
 | 
					 | 
				
			||||||
use core::slice;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use super::Vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// An iterator which uses a closure to determine if an element should be removed.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This struct is created by [`Vec::extract_if`].
 | 
					 | 
				
			||||||
/// See its documentation for more.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Example
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// #![feature(extract_if)]
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// let mut v = vec![0, 1, 2];
 | 
					 | 
				
			||||||
/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0);
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					 | 
				
			||||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
 | 
					 | 
				
			||||||
pub struct ExtractIf<
 | 
					 | 
				
			||||||
    'a,
 | 
					 | 
				
			||||||
    T,
 | 
					 | 
				
			||||||
    F,
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
 | 
					 | 
				
			||||||
> where
 | 
					 | 
				
			||||||
    F: FnMut(&mut T) -> bool,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    pub(super) vec: &'a mut Vec<T, A>,
 | 
					 | 
				
			||||||
    /// The index of the item that will be inspected by the next call to `next`.
 | 
					 | 
				
			||||||
    pub(super) idx: usize,
 | 
					 | 
				
			||||||
    /// The number of items that have been drained (removed) thus far.
 | 
					 | 
				
			||||||
    pub(super) del: usize,
 | 
					 | 
				
			||||||
    /// The original length of `vec` prior to draining.
 | 
					 | 
				
			||||||
    pub(super) old_len: usize,
 | 
					 | 
				
			||||||
    /// The filter test predicate.
 | 
					 | 
				
			||||||
    pub(super) pred: F,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, F, A: Allocator> ExtractIf<'_, T, F, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    F: FnMut(&mut T) -> bool,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Returns a reference to the underlying allocator.
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn allocator(&self) -> &A {
 | 
					 | 
				
			||||||
        self.vec.allocator()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
 | 
					 | 
				
			||||||
impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    F: FnMut(&mut T) -> bool,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    type Item = T;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<T> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            while self.idx < self.old_len {
 | 
					 | 
				
			||||||
                let i = self.idx;
 | 
					 | 
				
			||||||
                let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);
 | 
					 | 
				
			||||||
                let drained = (self.pred)(&mut v[i]);
 | 
					 | 
				
			||||||
                // Update the index *after* the predicate is called. If the index
 | 
					 | 
				
			||||||
                // is updated prior and the predicate panics, the element at this
 | 
					 | 
				
			||||||
                // index would be leaked.
 | 
					 | 
				
			||||||
                self.idx += 1;
 | 
					 | 
				
			||||||
                if drained {
 | 
					 | 
				
			||||||
                    self.del += 1;
 | 
					 | 
				
			||||||
                    return Some(ptr::read(&v[i]));
 | 
					 | 
				
			||||||
                } else if self.del > 0 {
 | 
					 | 
				
			||||||
                    let del = self.del;
 | 
					 | 
				
			||||||
                    let src: *const T = &v[i];
 | 
					 | 
				
			||||||
                    let dst: *mut T = &mut v[i - del];
 | 
					 | 
				
			||||||
                    ptr::copy_nonoverlapping(src, dst, 1);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            None
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn size_hint(&self) -> (usize, Option<usize>) {
 | 
					 | 
				
			||||||
        (0, Some(self.old_len - self.idx))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
 | 
					 | 
				
			||||||
impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    F: FnMut(&mut T) -> bool,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            if self.idx < self.old_len && self.del > 0 {
 | 
					 | 
				
			||||||
                // This is a pretty messed up state, and there isn't really an
 | 
					 | 
				
			||||||
                // obviously right thing to do. We don't want to keep trying
 | 
					 | 
				
			||||||
                // to execute `pred`, so we just backshift all the unprocessed
 | 
					 | 
				
			||||||
                // elements and tell the vec that they still exist. The backshift
 | 
					 | 
				
			||||||
                // is required to prevent a double-drop of the last successfully
 | 
					 | 
				
			||||||
                // drained item prior to a panic in the predicate.
 | 
					 | 
				
			||||||
                let ptr = self.vec.as_mut_ptr();
 | 
					 | 
				
			||||||
                let src = ptr.add(self.idx);
 | 
					 | 
				
			||||||
                let dst = src.sub(self.del);
 | 
					 | 
				
			||||||
                let tail_len = self.old_len - self.idx;
 | 
					 | 
				
			||||||
                src.copy_to(dst, tail_len);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            self.vec.set_len(self.old_len - self.del);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,484 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use super::AsVecIntoIter;
 | 
					 | 
				
			||||||
use crate::alloc::{Allocator, Global};
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use crate::collections::VecDeque;
 | 
					 | 
				
			||||||
use crate::raw_vec::RawVec;
 | 
					 | 
				
			||||||
use core::array;
 | 
					 | 
				
			||||||
use core::fmt;
 | 
					 | 
				
			||||||
use core::iter::{
 | 
					 | 
				
			||||||
    FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen,
 | 
					 | 
				
			||||||
    TrustedRandomAccessNoCoerce,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
use core::marker::PhantomData;
 | 
					 | 
				
			||||||
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
 | 
					 | 
				
			||||||
use core::num::NonZeroUsize;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use core::ops::Deref;
 | 
					 | 
				
			||||||
use core::ptr::{self, NonNull};
 | 
					 | 
				
			||||||
use core::slice::{self};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro non_null {
 | 
					 | 
				
			||||||
    (mut $place:expr, $t:ident) => {{
 | 
					 | 
				
			||||||
        #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
 | 
					 | 
				
			||||||
        unsafe { &mut *(ptr::addr_of_mut!($place) as *mut NonNull<$t>) }
 | 
					 | 
				
			||||||
    }},
 | 
					 | 
				
			||||||
    ($place:expr, $t:ident) => {{
 | 
					 | 
				
			||||||
        #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
 | 
					 | 
				
			||||||
        unsafe { *(ptr::addr_of!($place) as *const NonNull<$t>) }
 | 
					 | 
				
			||||||
    }},
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// An iterator that moves out of a vector.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec)
 | 
					 | 
				
			||||||
/// (provided by the [`IntoIterator`] trait).
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Example
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
/// let v = vec![0, 1, 2];
 | 
					 | 
				
			||||||
/// let iter: std::vec::IntoIter<_> = v.into_iter();
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
#[rustc_insignificant_dtor]
 | 
					 | 
				
			||||||
pub struct IntoIter<
 | 
					 | 
				
			||||||
    T,
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
 | 
					 | 
				
			||||||
> {
 | 
					 | 
				
			||||||
    pub(super) buf: NonNull<T>,
 | 
					 | 
				
			||||||
    pub(super) phantom: PhantomData<T>,
 | 
					 | 
				
			||||||
    pub(super) cap: usize,
 | 
					 | 
				
			||||||
    // the drop impl reconstructs a RawVec from buf, cap and alloc
 | 
					 | 
				
			||||||
    // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop
 | 
					 | 
				
			||||||
    pub(super) alloc: ManuallyDrop<A>,
 | 
					 | 
				
			||||||
    pub(super) ptr: NonNull<T>,
 | 
					 | 
				
			||||||
    /// If T is a ZST, this is actually ptr+len. This encoding is picked so that
 | 
					 | 
				
			||||||
    /// ptr == end is a quick test for the Iterator being empty, that works
 | 
					 | 
				
			||||||
    /// for both ZST and non-ZST.
 | 
					 | 
				
			||||||
    /// For non-ZSTs the pointer is treated as `NonNull<T>`
 | 
					 | 
				
			||||||
    pub(super) end: *const T,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "vec_intoiter_debug", since = "1.13.0")]
 | 
					 | 
				
			||||||
impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
					 | 
				
			||||||
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, A: Allocator> IntoIter<T, A> {
 | 
					 | 
				
			||||||
    /// Returns the remaining items of this iterator as a slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let vec = vec!['a', 'b', 'c'];
 | 
					 | 
				
			||||||
    /// let mut into_iter = vec.into_iter();
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
 | 
					 | 
				
			||||||
    /// let _ = into_iter.next().unwrap();
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
 | 
					 | 
				
			||||||
    pub fn as_slice(&self) -> &[T] {
 | 
					 | 
				
			||||||
        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len()) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns the remaining items of this iterator as a mutable slice.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// # Examples
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// let vec = vec!['a', 'b', 'c'];
 | 
					 | 
				
			||||||
    /// let mut into_iter = vec.into_iter();
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
 | 
					 | 
				
			||||||
    /// into_iter.as_mut_slice()[2] = 'z';
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.next().unwrap(), 'a');
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.next().unwrap(), 'b');
 | 
					 | 
				
			||||||
    /// assert_eq!(into_iter.next().unwrap(), 'z');
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
 | 
					 | 
				
			||||||
    pub fn as_mut_slice(&mut self) -> &mut [T] {
 | 
					 | 
				
			||||||
        unsafe { &mut *self.as_raw_mut_slice() }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Returns a reference to the underlying allocator.
 | 
					 | 
				
			||||||
    #[unstable(feature = "allocator_api", issue = "32838")]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub fn allocator(&self) -> &A {
 | 
					 | 
				
			||||||
        &self.alloc
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn as_raw_mut_slice(&mut self) -> *mut [T] {
 | 
					 | 
				
			||||||
        ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Drops remaining elements and relinquishes the backing allocation.
 | 
					 | 
				
			||||||
    /// This method guarantees it won't panic before relinquishing
 | 
					 | 
				
			||||||
    /// the backing allocation.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This is roughly equivalent to the following, but more efficient
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
 | 
					 | 
				
			||||||
    /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter());
 | 
					 | 
				
			||||||
    /// (&mut into_iter).for_each(drop);
 | 
					 | 
				
			||||||
    /// std::mem::forget(into_iter);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// This method is used by in-place iteration, refer to the vec::in_place_collect
 | 
					 | 
				
			||||||
    /// documentation for an overview.
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    pub(super) fn forget_allocation_drop_remaining(&mut self) {
 | 
					 | 
				
			||||||
        let remaining = self.as_raw_mut_slice();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // overwrite the individual fields instead of creating a new
 | 
					 | 
				
			||||||
        // struct and then overwriting &mut self.
 | 
					 | 
				
			||||||
        // this creates less assembly
 | 
					 | 
				
			||||||
        self.cap = 0;
 | 
					 | 
				
			||||||
        self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
 | 
					 | 
				
			||||||
        self.ptr = self.buf;
 | 
					 | 
				
			||||||
        self.end = self.buf.as_ptr();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Dropping the remaining elements can panic, so this needs to be
 | 
					 | 
				
			||||||
        // done only after updating the other fields.
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            ptr::drop_in_place(remaining);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
 | 
					 | 
				
			||||||
    pub(crate) fn forget_remaining_elements(&mut self) {
 | 
					 | 
				
			||||||
        // For the ZST case, it is crucial that we mutate `end` here, not `ptr`.
 | 
					 | 
				
			||||||
        // `ptr` must stay aligned, while `end` may be unaligned.
 | 
					 | 
				
			||||||
        self.end = self.ptr.as_ptr();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> {
 | 
					 | 
				
			||||||
        // Keep our `Drop` impl from dropping the elements and the allocator
 | 
					 | 
				
			||||||
        let mut this = ManuallyDrop::new(self);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // SAFETY: This allocation originally came from a `Vec`, so it passes
 | 
					 | 
				
			||||||
        // all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`,
 | 
					 | 
				
			||||||
        // so the `sub_ptr`s below cannot wrap, and will produce a well-formed
 | 
					 | 
				
			||||||
        // range. `end` ≤ `buf + cap`, so the range will be in-bounds.
 | 
					 | 
				
			||||||
        // Taking `alloc` is ok because nothing else is going to look at it,
 | 
					 | 
				
			||||||
        // since our `Drop` impl isn't going to run so there's no more code.
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            let buf = this.buf.as_ptr();
 | 
					 | 
				
			||||||
            let initialized = if T::IS_ZST {
 | 
					 | 
				
			||||||
                // All the pointers are the same for ZSTs, so it's fine to
 | 
					 | 
				
			||||||
                // say that they're all at the beginning of the "allocation".
 | 
					 | 
				
			||||||
                0..this.len()
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf)
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            let cap = this.cap;
 | 
					 | 
				
			||||||
            let alloc = ManuallyDrop::take(&mut this.alloc);
 | 
					 | 
				
			||||||
            VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    fn as_ref(&self) -> &[T] {
 | 
					 | 
				
			||||||
        self.as_slice()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
unsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {}
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
unsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> Iterator for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    type Item = T;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next(&mut self) -> Option<T> {
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            if self.ptr.as_ptr() == self.end as *mut _ {
 | 
					 | 
				
			||||||
                None
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by
 | 
					 | 
				
			||||||
                // reducing the `end`.
 | 
					 | 
				
			||||||
                self.end = self.end.wrapping_byte_sub(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Make up a value of this ZST.
 | 
					 | 
				
			||||||
                Some(unsafe { mem::zeroed() })
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            if self.ptr == non_null!(self.end, T) {
 | 
					 | 
				
			||||||
                None
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                let old = self.ptr;
 | 
					 | 
				
			||||||
                self.ptr = unsafe { old.add(1) };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Some(unsafe { ptr::read(old.as_ptr()) })
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn size_hint(&self) -> (usize, Option<usize>) {
 | 
					 | 
				
			||||||
        let exact = if T::IS_ZST {
 | 
					 | 
				
			||||||
            self.end.addr().wrapping_sub(self.ptr.as_ptr().addr())
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            unsafe { non_null!(self.end, T).sub_ptr(self.ptr) }
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        (exact, Some(exact))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
 | 
					 | 
				
			||||||
        let step_size = self.len().min(n);
 | 
					 | 
				
			||||||
        let to_drop = ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), step_size);
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            // See `next` for why we sub `end` here.
 | 
					 | 
				
			||||||
            self.end = self.end.wrapping_byte_sub(step_size);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // SAFETY: the min() above ensures that step_size is in bounds
 | 
					 | 
				
			||||||
            self.ptr = unsafe { self.ptr.add(step_size) };
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // SAFETY: the min() above ensures that step_size is in bounds
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            ptr::drop_in_place(to_drop);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn count(self) -> usize {
 | 
					 | 
				
			||||||
        self.len()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
 | 
					 | 
				
			||||||
        let mut raw_ary = MaybeUninit::uninit_array();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let len = self.len();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            if len < N {
 | 
					 | 
				
			||||||
                self.forget_remaining_elements();
 | 
					 | 
				
			||||||
                // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct
 | 
					 | 
				
			||||||
                return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.end = self.end.wrapping_byte_sub(N);
 | 
					 | 
				
			||||||
            // Safety: ditto
 | 
					 | 
				
			||||||
            return Ok(unsafe { raw_ary.transpose().assume_init() });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if len < N {
 | 
					 | 
				
			||||||
            // Safety: `len` indicates that this many elements are available and we just checked that
 | 
					 | 
				
			||||||
            // it fits into the array.
 | 
					 | 
				
			||||||
            unsafe {
 | 
					 | 
				
			||||||
                ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len);
 | 
					 | 
				
			||||||
                self.forget_remaining_elements();
 | 
					 | 
				
			||||||
                return Err(array::IntoIter::new_unchecked(raw_ary, 0..len));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize
 | 
					 | 
				
			||||||
        // the array.
 | 
					 | 
				
			||||||
        return unsafe {
 | 
					 | 
				
			||||||
            ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, N);
 | 
					 | 
				
			||||||
            self.ptr = self.ptr.add(N);
 | 
					 | 
				
			||||||
            Ok(raw_ary.transpose().assume_init())
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: TrustedRandomAccessNoCoerce,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // SAFETY: the caller must guarantee that `i` is in bounds of the
 | 
					 | 
				
			||||||
        // `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)`
 | 
					 | 
				
			||||||
        // is guaranteed to pointer to an element of the `Vec<T>` and
 | 
					 | 
				
			||||||
        // thus guaranteed to be valid to dereference.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // Also note the implementation of `Self: TrustedRandomAccess` requires
 | 
					 | 
				
			||||||
        // that `T: Copy` so reading elements from the buffer doesn't invalidate
 | 
					 | 
				
			||||||
        // them for `Drop`.
 | 
					 | 
				
			||||||
        unsafe { if T::IS_ZST { mem::zeroed() } else { self.ptr.add(i).read() } }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn next_back(&mut self) -> Option<T> {
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            if self.end as *mut _ == self.ptr.as_ptr() {
 | 
					 | 
				
			||||||
                None
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // See above for why 'ptr.offset' isn't used
 | 
					 | 
				
			||||||
                self.end = self.end.wrapping_byte_sub(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Make up a value of this ZST.
 | 
					 | 
				
			||||||
                Some(unsafe { mem::zeroed() })
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            if non_null!(self.end, T) == self.ptr {
 | 
					 | 
				
			||||||
                None
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                let new_end = unsafe { non_null!(self.end, T).sub(1) };
 | 
					 | 
				
			||||||
                *non_null!(mut self.end, T) = new_end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Some(unsafe { ptr::read(new_end.as_ptr()) })
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
 | 
					 | 
				
			||||||
        let step_size = self.len().min(n);
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            // SAFETY: same as for advance_by()
 | 
					 | 
				
			||||||
            self.end = self.end.wrapping_byte_sub(step_size);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // SAFETY: same as for advance_by()
 | 
					 | 
				
			||||||
            self.end = unsafe { self.end.sub(step_size) };
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
 | 
					 | 
				
			||||||
        // SAFETY: same as for advance_by()
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            ptr::drop_in_place(to_drop);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    fn is_empty(&self) -> bool {
 | 
					 | 
				
			||||||
        if T::IS_ZST {
 | 
					 | 
				
			||||||
            self.ptr.as_ptr() == self.end as *mut _
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            self.ptr == non_null!(self.end, T)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "fused", since = "1.26.0")]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "trusted_fused")]
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> TrustedFused for IntoIter<T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(feature = "trusted_len", issue = "37572")]
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "default_iters", since = "1.70.0")]
 | 
					 | 
				
			||||||
impl<T, A> Default for IntoIter<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    A: Allocator + Default,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// Creates an empty `vec::IntoIter`.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    /// # use std::vec;
 | 
					 | 
				
			||||||
    /// let iter: vec::IntoIter<u8> = Default::default();
 | 
					 | 
				
			||||||
    /// assert_eq!(iter.len(), 0);
 | 
					 | 
				
			||||||
    /// assert_eq!(iter.as_slice(), &[]);
 | 
					 | 
				
			||||||
    /// ```
 | 
					 | 
				
			||||||
    fn default() -> Self {
 | 
					 | 
				
			||||||
        super::Vec::new_in(Default::default()).into_iter()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "std_internals")]
 | 
					 | 
				
			||||||
#[rustc_unsafe_specialization_marker]
 | 
					 | 
				
			||||||
pub trait NonDrop {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
 | 
					 | 
				
			||||||
// and thus we can't implement drop-handling
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "std_internals")]
 | 
					 | 
				
			||||||
impl<T: Copy> NonDrop for T {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "std_internals")]
 | 
					 | 
				
			||||||
// TrustedRandomAccess (without NoCoerce) must not be implemented because
 | 
					 | 
				
			||||||
// subtypes/supertypes of `T` might not be `NonDrop`
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    T: NonDrop,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    const MAY_HAVE_SIDE_EFFECT: bool = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
 | 
					 | 
				
			||||||
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    #[cfg(not(test))]
 | 
					 | 
				
			||||||
    fn clone(&self) -> Self {
 | 
					 | 
				
			||||||
        self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #[cfg(test)]
 | 
					 | 
				
			||||||
    fn clone(&self) -> Self {
 | 
					 | 
				
			||||||
        crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[stable(feature = "rust1", since = "1.0.0")]
 | 
					 | 
				
			||||||
unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
 | 
					 | 
				
			||||||
            fn drop(&mut self) {
 | 
					 | 
				
			||||||
                unsafe {
 | 
					 | 
				
			||||||
                    // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec
 | 
					 | 
				
			||||||
                    let alloc = ManuallyDrop::take(&mut self.0.alloc);
 | 
					 | 
				
			||||||
                    // RawVec handles deallocation
 | 
					 | 
				
			||||||
                    let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let guard = DropGuard(self);
 | 
					 | 
				
			||||||
        // destroy the remaining elements
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            ptr::drop_in_place(guard.0.as_raw_mut_slice());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // now `guard` will be dropped and do the rest
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// In addition to the SAFETY invariants of the following three unsafe traits
 | 
					 | 
				
			||||||
// also refer to the vec::in_place_collect module documentation to get an overview
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "inplace_iteration")]
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    const EXPAND_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
 | 
					 | 
				
			||||||
    const MERGE_BY: Option<NonZeroUsize> = NonZeroUsize::new(1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[unstable(issue = "none", feature = "inplace_iteration")]
 | 
					 | 
				
			||||||
#[doc(hidden)]
 | 
					 | 
				
			||||||
unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
 | 
					 | 
				
			||||||
    type Source = Self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    unsafe fn as_inner(&mut self) -> &mut Self::Source {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
unsafe impl<T> AsVecIntoIter for IntoIter<T> {
 | 
					 | 
				
			||||||
    type Item = T;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn as_into_iter(&mut self) -> &mut IntoIter<Self::Item> {
 | 
					 | 
				
			||||||
        self
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,204 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use core::num::{Saturating, Wrapping};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::boxed::Box;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[rustc_specialization_trait]
 | 
					 | 
				
			||||||
pub(super) unsafe trait IsZero {
 | 
					 | 
				
			||||||
    /// Whether this value's representation is all zeros,
 | 
					 | 
				
			||||||
    /// or can be represented with all zeroes.
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro_rules! impl_is_zero {
 | 
					 | 
				
			||||||
    ($t:ty, $is_zero:expr) => {
 | 
					 | 
				
			||||||
        unsafe impl IsZero for $t {
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
                $is_zero(*self)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero!(i8, |x| x == 0); // It is needed to impl for arrays and tuples of i8.
 | 
					 | 
				
			||||||
impl_is_zero!(i16, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(i32, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(i64, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(i128, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(isize, |x| x == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero!(u8, |x| x == 0); // It is needed to impl for arrays and tuples of u8.
 | 
					 | 
				
			||||||
impl_is_zero!(u16, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(u32, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(u64, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(u128, |x| x == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(usize, |x| x == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero!(bool, |x| x == false);
 | 
					 | 
				
			||||||
impl_is_zero!(char, |x| x == '\0');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
 | 
					 | 
				
			||||||
impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T> IsZero for *const T {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        (*self).is_null()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T> IsZero for *mut T {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        (*self).is_null()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T: IsZero, const N: usize> IsZero for [T; N] {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        // Because this is generated as a runtime check, it's not obvious that
 | 
					 | 
				
			||||||
        // it's worth doing if the array is really long. The threshold here
 | 
					 | 
				
			||||||
        // is largely arbitrary, but was picked because as of 2022-07-01 LLVM
 | 
					 | 
				
			||||||
        // fails to const-fold the check in `vec![[1; 32]; n]`
 | 
					 | 
				
			||||||
        // See https://github.com/rust-lang/rust/pull/97581#issuecomment-1166628022
 | 
					 | 
				
			||||||
        // Feel free to tweak if you have better evidence.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        N <= 16 && self.iter().all(IsZero::is_zero)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This is recursive macro.
 | 
					 | 
				
			||||||
macro_rules! impl_for_tuples {
 | 
					 | 
				
			||||||
    // Stopper
 | 
					 | 
				
			||||||
    () => {
 | 
					 | 
				
			||||||
        // No use for implementing for empty tuple because it is ZST.
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    ($first_arg:ident $(,$rest:ident)*) => {
 | 
					 | 
				
			||||||
        unsafe impl <$first_arg: IsZero, $($rest: IsZero,)*> IsZero for ($first_arg, $($rest,)*){
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn is_zero(&self) -> bool{
 | 
					 | 
				
			||||||
                // Destructure tuple to N references
 | 
					 | 
				
			||||||
                // Rust allows to hide generic params by local variable names.
 | 
					 | 
				
			||||||
                #[allow(non_snake_case)]
 | 
					 | 
				
			||||||
                let ($first_arg, $($rest,)*) = self;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                $first_arg.is_zero()
 | 
					 | 
				
			||||||
                    $( && $rest.is_zero() )*
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        impl_for_tuples!($($rest),*);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_for_tuples!(A, B, C, D, E, F, G, H);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// `Option<&T>` and `Option<Box<T>>` are guaranteed to represent `None` as null.
 | 
					 | 
				
			||||||
// For fat pointers, the bytes that would be the pointer metadata in the `Some`
 | 
					 | 
				
			||||||
// variant are padding in the `None` variant, so ignoring them and
 | 
					 | 
				
			||||||
// zero-initializing instead is ok.
 | 
					 | 
				
			||||||
// `Option<&mut T>` never implements `Clone`, so there's no need for an impl of
 | 
					 | 
				
			||||||
// `SpecFromElem`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T: ?Sized> IsZero for Option<&T> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        self.is_none()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        self.is_none()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// `Option<num::NonZeroU32>` and similar have a representation guarantee that
 | 
					 | 
				
			||||||
// they're the same size as the corresponding `u32` type, as well as a guarantee
 | 
					 | 
				
			||||||
// that transmuting between `NonZeroU32` and `Option<num::NonZeroU32>` works.
 | 
					 | 
				
			||||||
// While the documentation officially makes it UB to transmute from `None`,
 | 
					 | 
				
			||||||
// we're the standard library so we can make extra inferences, and we know that
 | 
					 | 
				
			||||||
// the only niche available to represent `None` is the one that's all zeros.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro_rules! impl_is_zero_option_of_nonzero {
 | 
					 | 
				
			||||||
    ($($t:ident,)+) => {$(
 | 
					 | 
				
			||||||
        unsafe impl IsZero for Option<core::num::$t> {
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
                self.is_none()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    )+};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero_option_of_nonzero!(
 | 
					 | 
				
			||||||
    NonZeroU8,
 | 
					 | 
				
			||||||
    NonZeroU16,
 | 
					 | 
				
			||||||
    NonZeroU32,
 | 
					 | 
				
			||||||
    NonZeroU64,
 | 
					 | 
				
			||||||
    NonZeroU128,
 | 
					 | 
				
			||||||
    NonZeroI8,
 | 
					 | 
				
			||||||
    NonZeroI16,
 | 
					 | 
				
			||||||
    NonZeroI32,
 | 
					 | 
				
			||||||
    NonZeroI64,
 | 
					 | 
				
			||||||
    NonZeroI128,
 | 
					 | 
				
			||||||
    NonZeroUsize,
 | 
					 | 
				
			||||||
    NonZeroIsize,
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro_rules! impl_is_zero_option_of_num {
 | 
					 | 
				
			||||||
    ($($t:ty,)+) => {$(
 | 
					 | 
				
			||||||
        unsafe impl IsZero for Option<$t> {
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
                const {
 | 
					 | 
				
			||||||
                    let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
 | 
					 | 
				
			||||||
                    assert!(none.is_none());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                self.is_none()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    )+};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl_is_zero_option_of_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize,);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T: IsZero> IsZero for Wrapping<T> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        self.0.is_zero()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsafe impl<T: IsZero> IsZero for Saturating<T> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
        self.0.is_zero()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro_rules! impl_for_optional_bool {
 | 
					 | 
				
			||||||
    ($($t:ty,)+) => {$(
 | 
					 | 
				
			||||||
        unsafe impl IsZero for $t {
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn is_zero(&self) -> bool {
 | 
					 | 
				
			||||||
                // SAFETY: This is *not* a stable layout guarantee, but
 | 
					 | 
				
			||||||
                // inside `core` we're allowed to rely on the current rustc
 | 
					 | 
				
			||||||
                // behaviour that options of bools will be one byte with
 | 
					 | 
				
			||||||
                // no padding, so long as they're nested less than 254 deep.
 | 
					 | 
				
			||||||
                let raw: u8 = unsafe { core::mem::transmute(*self) };
 | 
					 | 
				
			||||||
                raw == 0
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    )+};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
impl_for_optional_bool! {
 | 
					 | 
				
			||||||
    Option<bool>,
 | 
					 | 
				
			||||||
    Option<Option<bool>>,
 | 
					 | 
				
			||||||
    Option<Option<Option<bool>>>,
 | 
					 | 
				
			||||||
    // Could go further, but not worth the metadata overhead
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,49 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::Allocator;
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
use crate::borrow::Cow;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use super::Vec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
macro_rules! __impl_slice_eq1 {
 | 
					 | 
				
			||||||
    ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?, #[$stability:meta]) => {
 | 
					 | 
				
			||||||
        #[$stability]
 | 
					 | 
				
			||||||
        impl<T, U, $($vars)*> PartialEq<$rhs> for $lhs
 | 
					 | 
				
			||||||
        where
 | 
					 | 
				
			||||||
            T: PartialEq<U>,
 | 
					 | 
				
			||||||
            $($ty: $bound)?
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2>, #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &[U], #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &mut [U], #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] &[T], Vec<U, A>, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] &mut [T], Vec<U, A>, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, [U], #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")]  }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] [T], Vec<U, A>, #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")]  }
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator] Cow<'_, [T]>, Vec<U, A> where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [] Cow<'_, [T]>, &[U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [] Cow<'_, [T]>, &mut [U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, [U; N], #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, &[U; N], #[stable(feature = "rust1", since = "1.0.0")] }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NOTE: some less important impls are omitted to reduce code bloat
 | 
					 | 
				
			||||||
// FIXME(Centril): Reconsider this?
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] Vec<A>, &mut [B; N], }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] [A; N], Vec<B>, }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] &[A; N], Vec<B>, }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] &mut [A; N], Vec<B>, }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], }
 | 
					 | 
				
			||||||
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], }
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,35 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The idea is: The length field in SetLenOnDrop is a local variable
 | 
					 | 
				
			||||||
// that the optimizer will see does not alias with any stores through the Vec's data
 | 
					 | 
				
			||||||
// pointer. This is a workaround for alias analysis issue #32155
 | 
					 | 
				
			||||||
pub(super) struct SetLenOnDrop<'a> {
 | 
					 | 
				
			||||||
    len: &'a mut usize,
 | 
					 | 
				
			||||||
    local_len: usize,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> SetLenOnDrop<'a> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(super) fn new(len: &'a mut usize) -> Self {
 | 
					 | 
				
			||||||
        SetLenOnDrop { local_len: *len, len }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(super) fn increment_len(&mut self, increment: usize) {
 | 
					 | 
				
			||||||
        self.local_len += increment;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    pub(super) fn current_len(&self) -> usize {
 | 
					 | 
				
			||||||
        self.local_len
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Drop for SetLenOnDrop<'_> {
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn drop(&mut self) {
 | 
					 | 
				
			||||||
        *self.len = self.local_len;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,119 +0,0 @@
 | 
				
			||||||
// SPDX-License-Identifier: Apache-2.0 OR MIT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use crate::alloc::Allocator;
 | 
					 | 
				
			||||||
use crate::collections::TryReserveError;
 | 
					 | 
				
			||||||
use core::iter::TrustedLen;
 | 
					 | 
				
			||||||
use core::slice::{self};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use super::{IntoIter, Vec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Specialization trait used for Vec::extend
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
pub(super) trait SpecExtend<T, I> {
 | 
					 | 
				
			||||||
    fn spec_extend(&mut self, iter: I);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Specialization trait used for Vec::try_extend
 | 
					 | 
				
			||||||
pub(super) trait TrySpecExtend<T, I> {
 | 
					 | 
				
			||||||
    fn try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: Iterator<Item = T>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn spec_extend(&mut self, iter: I) {
 | 
					 | 
				
			||||||
        self.extend_desugared(iter)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: Iterator<Item = T>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        self.try_extend_desugared(iter)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: TrustedLen<Item = T>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn spec_extend(&mut self, iterator: I) {
 | 
					 | 
				
			||||||
        self.extend_trusted(iterator)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: TrustedLen<Item = T>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        self.try_extend_trusted(iterator)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> {
 | 
					 | 
				
			||||||
    fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            self.append_elements(iterator.as_slice() as _);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        iterator.forget_remaining_elements();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<T, A: Allocator> TrySpecExtend<T, IntoIter<T>> for Vec<T, A> {
 | 
					 | 
				
			||||||
    fn try_spec_extend(&mut self, mut iterator: IntoIter<T>) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        unsafe {
 | 
					 | 
				
			||||||
            self.try_append_elements(iterator.as_slice() as _)?;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        iterator.forget_remaining_elements();
 | 
					 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: Iterator<Item = &'a T>,
 | 
					 | 
				
			||||||
    T: Clone,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn spec_extend(&mut self, iterator: I) {
 | 
					 | 
				
			||||||
        self.spec_extend(iterator.cloned())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a, T: 'a, I, A: Allocator> TrySpecExtend<&'a T, I> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    I: Iterator<Item = &'a T>,
 | 
					 | 
				
			||||||
    T: Clone,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    default fn try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        self.try_spec_extend(iterator.cloned())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(not(no_global_oom_handling))]
 | 
					 | 
				
			||||||
impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    T: Copy,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
 | 
					 | 
				
			||||||
        let slice = iterator.as_slice();
 | 
					 | 
				
			||||||
        unsafe { self.append_elements(slice) };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a, T: 'a, A: Allocator> TrySpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
 | 
					 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    T: Copy,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fn try_spec_extend(&mut self, iterator: slice::Iter<'a, T>) -> Result<(), TryReserveError> {
 | 
					 | 
				
			||||||
        let slice = iterator.as_slice();
 | 
					 | 
				
			||||||
        unsafe { self.try_append_elements(slice) }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in a new issue