#![allow(
clippy::type_repetition_in_bounds,
clippy::cast_sign_loss,
reason = "trait-impl `where` clauses are kept uniform across all forwarding impls; numeric casts are bounded by upstream `usize` checks documented at call sites"
)]
use core::borrow::BorrowMut;
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::mem::{self, MaybeUninit};
use core::ops::DerefMut;
use core::pin::Pin;
use core::ptr::{self, NonNull};
use allocator_api2::alloc::{Allocator, Global};
use ptr_meta::Pointee;
use crate::internal::chunk_ref::ChunkRef;
use crate::thin_smart_ptr_common::impl_thin_smart_ptr_common;
use crate::vec::Vec;
pub struct Box<T: ?Sized + Pointee, A: Allocator + Clone = Global> {
ptr: NonNull<u8>,
_phantom: PhantomData<(*const T, A)>,
}
unsafe impl<T: ?Sized + Pointee + Send, A: Allocator + Clone + Send + Sync> Send for Box<T, A> {}
unsafe impl<T: ?Sized + Pointee + Sync, A: Allocator + Clone + Sync> Sync for Box<T, A> {}
impl<T: ?Sized + Pointee, A: Allocator + Clone> Box<T, A> {
#[inline]
pub(crate) unsafe fn from_raw(thin: NonNull<u8>) -> Self {
Self {
ptr: thin,
_phantom: PhantomData,
}
}
#[inline]
pub(crate) fn thin_ptr(&self) -> NonNull<u8> {
self.ptr
}
#[allow(
clippy::needless_pass_by_ref_mut,
reason = "associated-fn convention (like alloc::rc::Rc::as_ptr); &mut self conveys exclusive access"
)]
#[must_use]
#[inline]
pub fn as_mut_ptr(this: &mut Self) -> *mut T {
this.as_fat_ptr().as_ptr()
}
}
impl_thin_smart_ptr_common!(Box);
impl<T: ?Sized + Pointee, A: Allocator + Clone> Drop for Box<T, A> {
#[inline]
fn drop(&mut self) {
unsafe {
let _ref: ChunkRef<A> = ChunkRef::from_value_ptr(self.ptr);
let fat = self.as_fat_ptr();
ptr::drop_in_place(fat.as_ptr());
}
}
}
impl<T, A: Allocator + Clone> Box<MaybeUninit<T>, A> {
#[must_use]
#[inline]
pub unsafe fn assume_init(self) -> Box<T, A> {
let thin = self.ptr;
mem::forget(self);
unsafe { Box::from_raw(thin) }
}
#[must_use]
#[inline]
pub unsafe fn assume_init_pin(this: Pin<Self>) -> Pin<Box<T, A>>
where
A: 'static,
{
unsafe {
let inner: Self = Pin::into_inner_unchecked(this);
Box::into_pin(inner.assume_init())
}
}
}
impl<T, A: Allocator + Clone> Box<[MaybeUninit<T>], A> {
#[must_use]
#[inline]
pub unsafe fn assume_init(self) -> Box<[T], A> {
let thin = self.ptr;
mem::forget(self);
unsafe { Box::from_raw(thin) }
}
#[must_use]
#[inline]
pub unsafe fn assume_init_pin_slice(this: Pin<Self>) -> Pin<Box<[T], A>>
where
A: 'static,
{
unsafe {
let inner: Self = Pin::into_inner_unchecked(this);
Box::into_pin(inner.assume_init())
}
}
}
impl<T: ?Sized + Pointee, A: Allocator + Clone> DerefMut for Box<T, A> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe { self.as_fat_ptr().as_mut() }
}
}
impl<T: ?Sized + Pointee, A: Allocator + Clone> AsMut<T> for Box<T, A> {
#[inline]
fn as_mut(&mut self) -> &mut T {
self
}
}
impl<T: ?Sized + Pointee, A: Allocator + Clone> BorrowMut<T> for Box<T, A> {
#[inline]
fn borrow_mut(&mut self) -> &mut T {
self
}
}
impl<I: Iterator + ?Sized + Pointee, A: Allocator + Clone> Iterator for Box<I, A> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
(**self).next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
(**self).nth(n)
}
}
impl<I: DoubleEndedIterator + ?Sized + Pointee, A: Allocator + Clone> DoubleEndedIterator for Box<I, A> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
(**self).next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
(**self).nth_back(n)
}
}
impl<I: ExactSizeIterator + ?Sized + Pointee, A: Allocator + Clone> ExactSizeIterator for Box<I, A> {
#[inline]
fn len(&self) -> usize {
(**self).len()
}
}
impl<I: FusedIterator + ?Sized + Pointee, A: Allocator + Clone> FusedIterator for Box<I, A> {}
impl<'a, T, A: Allocator + Clone> From<Vec<'a, T, A>> for Box<[T], A> {
#[inline]
fn from(v: Vec<'a, T, A>) -> Self {
v.into_boxed_slice()
}
}