mod raw;
pub use self::raw::*;
use crate::buffer::{AllocatedBuffer, Buffer, UnmanagedBuffer};
use alloc::alloc::Global;
use core::{
mem,
ops::{CoerceUnsized, Deref, DerefMut},
ptr,
};
use mem::ManuallyDrop;
pub struct Box<T, B = AllocatedBuffer<T>, D = <B as Buffer<T>>::ExternalData>
where
T: ?Sized,
B: Buffer<T, ExternalData = D>,
{
raw: RawBox<T, B>,
data: D,
}
#[allow(clippy::use_self)]
impl<T> Box<T> {
#[inline]
pub fn new(value: T) -> Self {
Self {
raw: RawBox::new(value),
data: Global,
}
}
#[inline]
pub fn new_uninit() -> Box<mem::MaybeUninit<T>, AllocatedBuffer<T>> {
Box {
raw: RawBox::new_uninit(),
data: Global,
}
}
#[inline]
pub fn new_zeroed() -> Box<mem::MaybeUninit<T>, AllocatedBuffer<T>> {
Box {
raw: RawBox::new_zeroed(),
data: Global,
}
}
}
#[allow(clippy::use_self)]
impl<T> Box<[T]> {
#[inline]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>], AllocatedBuffer<[T]>> {
Box {
raw: RawBox::new_uninit_slice(len),
data: Global,
}
}
#[inline]
pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>], AllocatedBuffer<[T]>> {
Box {
raw: RawBox::new_zeroed_slice(len),
data: Global,
}
}
}
#[allow(clippy::use_self)]
impl<T, B, D> Box<T, B, D>
where
B: Buffer<T, ExternalData = D>,
{
#[inline]
pub fn new_in(value: T, buffer: B, data: D) -> Self {
Self {
raw: RawBox::new_in(value, buffer, &data),
data,
}
}
#[inline]
pub fn new_uninit_in(buffer: B, data: D) -> Box<mem::MaybeUninit<T>, B, D>
where
B: Buffer<mem::MaybeUninit<T>, ExternalData = D>,
{
Box {
raw: RawBox::new_uninit_in(buffer),
data,
}
}
}
impl<T: ?Sized, B, D> Box<T, B, D>
where
B: Buffer<T, ExternalData = D>,
{
pub unsafe fn from_buffer(buffer: B, data: D) -> Self {
Self {
raw: RawBox::from_buffer(buffer),
data,
}
}
}
#[allow(clippy::use_self)]
impl<T, B, D> Box<[T], B, D>
where
B: Buffer<[T], ExternalData = D>,
{
#[inline]
pub fn new_uninit_slice_in(buffer: B, data: D) -> Box<[mem::MaybeUninit<T>], B, D>
where
B: Buffer<[mem::MaybeUninit<T>], ExternalData = D>,
{
Box {
raw: RawBox::new_uninit_slice_in(buffer),
data,
}
}
}
#[allow(clippy::use_self)]
impl<T, B, D> Box<mem::MaybeUninit<T>, B, D>
where
B: Buffer<T, ExternalData = D> + Buffer<mem::MaybeUninit<T>, ExternalData = D>,
{
#[inline]
pub unsafe fn assume_init(self) -> Box<T, B, D> {
let this = ManuallyDrop::new(self);
Box {
raw: ptr::read(&this.raw).assume_init(),
data: ptr::read(&this.data),
}
}
}
#[allow(clippy::use_self)]
impl<T, B, D> Box<[mem::MaybeUninit<T>], B, D>
where
B: Buffer<[T], ExternalData = D> + Buffer<[mem::MaybeUninit<T>], ExternalData = D>,
{
#[inline]
pub unsafe fn assume_init(self) -> Box<[T], B, D> {
let this = ManuallyDrop::new(self);
Box {
raw: ptr::read(&this.raw).assume_init(),
data: ptr::read(&this.data),
}
}
}
#[doc(hidden)]
impl<T: ?Sized, S: Buffer<T, ExternalData = D>, D> Drop for Box<T, S, D> {
default fn drop(&mut self) {
}
}
impl<T, S, D> Drop for Box<T, S, D>
where
T: ?Sized,
S: UnmanagedBuffer<T, ExternalData = D>,
{
fn drop(&mut self) {
unsafe { self.raw.buffer_mut().free_unchecked(&self.data) }
}
}
impl<T, B, D> Deref for Box<T, B, D>
where
T: ?Sized,
B: Buffer<T, ExternalData = D>,
{
type Target = T;
fn deref(&self) -> &Self::Target {
self.raw.as_ref(&self.data)
}
}
impl<T, B, D> DerefMut for Box<T, B, D>
where
T: ?Sized,
B: Buffer<T, ExternalData = D>,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.raw.as_mut(&self.data)
}
}
impl<T, U, D, BT, BU> CoerceUnsized<Box<U, BU, D>> for Box<T, BT, D>
where
T: ?Sized,
U: ?Sized,
BT: Buffer<T, ExternalData = D> + CoerceUnsized<BU>,
BU: Buffer<U, ExternalData = D>,
{
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new() {
let five = Box::new(5);
assert_eq!(*five, 5);
}
}