#[cfg(feature = "nightly")]
pub use core::alloc::AllocError;
#[cfg(feature = "alloc")]
use std::boxed::Box;
#[cfg(not(feature = "nightly"))]
pub struct AllocError;
#[cfg(any(doc, feature = "nightly"))]
mod array;
#[cfg(any(doc, feature = "alloc"))]
mod heap;
mod slice;
mod zero_sized;
#[cfg(any(doc, feature = "nightly"))]
pub use array::{Array, UninitArray};
#[cfg(any(doc, feature = "alloc"))]
pub use heap::Heap;
pub use slice::{Slice, UninitSlice};
pub use zero_sized::ZeroSized;
#[repr(transparent)]
pub struct Init<T: ?Sized>(pub T);
#[repr(transparent)]
pub struct Uninit<T: ?Sized>(pub(crate) T);
#[cold]
#[inline(never)]
#[cfg(feature = "nightly")]
const fn capacity_calculation_overflow() -> ! { panic!("Tried to calculate the current capacity, but overflowed") }
#[cold]
#[inline(never)]
fn fixed_capacity_reserve_error(capacity: usize, new_capacity: usize) -> ! {
panic!(
"Tried to reserve {}, but used a fixed capacity buffer of {}",
new_capacity, capacity
)
}
#[cfg(not(any(
target_pointer_width = "8",
target_pointer_width = "16",
target_pointer_width = "32",
target_pointer_width = "64"
)))]
compile_error!("Cannot correctly calculate capacity on an 128-bit or larger architecture");
const fn capacity(old_capacity: usize, size_self: usize, size_other: usize) -> usize {
#[cfg(target_pointer_width = "8")]
type PointerNext = u16;
#[cfg(target_pointer_width = "16")]
type PointerNext = u32;
#[cfg(target_pointer_width = "32")]
type PointerNext = u64;
#[cfg(target_pointer_width = "64")]
type PointerNext = u128;
let size = (old_capacity as PointerNext) * (size_self as PointerNext) / (size_other as PointerNext);
#[cfg(not(feature = "nightly"))]
{
[size as usize][(size > usize::MAX as PointerNext) as usize]
}
#[cfg(feature = "nightly")]
{
if size > usize::MAX as PointerNext {
capacity_calculation_overflow()
}
size as usize
}
}
impl<T> Uninit<T> {
pub fn new(value: T) -> Self { Self(value) }
pub unsafe fn into_inner(self) -> T { self.0 }
}
pub unsafe trait StorageInit<T>: Storage<T> {}
pub const fn is_compatible<T, U>() -> bool {
use core::mem::{align_of, size_of};
size_of::<T>() >= size_of::<U>() && align_of::<T>() >= align_of::<U>()
}
pub const fn is_identical<T, U>() -> bool {
use core::mem::{align_of, size_of};
size_of::<T>() == size_of::<U>() && align_of::<T>() == align_of::<U>()
}
pub unsafe trait Storage<T> {
#[doc(hidden)]
const CONST_CAPACITY: Option<usize> = None;
fn is_valid_storage() -> bool;
fn capacity(&self) -> usize;
fn as_ptr(&self) -> *const T;
fn as_mut_ptr(&mut self) -> *mut T;
fn reserve(&mut self, new_capacity: usize);
fn try_reserve(&mut self, new_capacity: usize) -> Result<(), AllocError>;
}
pub trait StorageWithCapacity<T>: Storage<T> + Default {
fn with_capacity(capacity: usize) -> Self;
#[doc(hidden)]
#[inline(always)]
#[allow(non_snake_case)]
fn __with_capacity__const_capacity_checked(capacity: usize, _old_capacity: Option<usize>) -> Self {
Self::with_capacity(capacity)
}
}
unsafe impl<T, S: ?Sized + StorageInit<T>> StorageInit<T> for &mut S {}
unsafe impl<T, S: ?Sized + Storage<T>> Storage<T> for &mut S {
#[doc(hidden)]
const CONST_CAPACITY: Option<usize> = S::CONST_CAPACITY;
fn is_valid_storage() -> bool { S::is_valid_storage() }
fn capacity(&self) -> usize { S::capacity(self) }
fn as_ptr(&self) -> *const T { S::as_ptr(self) }
fn as_mut_ptr(&mut self) -> *mut T { S::as_mut_ptr(self) }
fn reserve(&mut self, new_capacity: usize) { S::reserve(self, new_capacity) }
fn try_reserve(&mut self, new_capacity: usize) -> Result<(), AllocError> { S::try_reserve(self, new_capacity) }
}
#[cfg(feature = "alloc")]
unsafe impl<T, S: ?Sized + StorageInit<T>> StorageInit<T> for Box<S> {}
#[cfg(feature = "alloc")]
unsafe impl<T, S: ?Sized + Storage<T>> Storage<T> for Box<S> {
#[doc(hidden)]
const CONST_CAPACITY: Option<usize> = S::CONST_CAPACITY;
fn is_valid_storage() -> bool { S::is_valid_storage() }
fn capacity(&self) -> usize { S::capacity(self) }
fn as_ptr(&self) -> *const T { S::as_ptr(self) }
fn as_mut_ptr(&mut self) -> *mut T { S::as_mut_ptr(self) }
fn reserve(&mut self, new_capacity: usize) { S::reserve(self, new_capacity) }
fn try_reserve(&mut self, new_capacity: usize) -> Result<(), AllocError> { S::try_reserve(self, new_capacity) }
}
#[cfg(feature = "alloc")]
impl<T, S: ?Sized + StorageWithCapacity<T>> StorageWithCapacity<T> for Box<S> {
fn with_capacity(capacity: usize) -> Self { Box::new(S::with_capacity(capacity)) }
#[doc(hidden)]
#[inline(always)]
#[allow(non_snake_case)]
fn __with_capacity__const_capacity_checked(capacity: usize, _old_capacity: Option<usize>) -> Self {
Box::new(S::__with_capacity__const_capacity_checked(capacity, _old_capacity))
}
}