blob: 615db301744f3b634637a4f7482fbd91403783f8 [file] [log] [blame] [edit]
use core::{borrow, fmt, hash, mem, ptr};
use loom::alloc;
pub struct Box<T: ?Sized> {
ptr: *mut T,
}
impl<T> Box<T> {
pub fn new(value: T) -> Self {
let layout = alloc::Layout::new::<T>();
let ptr = unsafe { alloc::alloc(layout) } as *mut T;
unsafe { ptr::write(ptr, value) };
Self { ptr }
}
}
impl<T: ?Sized> Box<T> {
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
let ptr = b.ptr;
mem::forget(b);
ptr
}
pub const unsafe fn from_raw(ptr: *mut T) -> Box<T> {
Self { ptr }
}
}
impl<T: ?Sized> Drop for Box<T> {
fn drop(&mut self) {
unsafe {
let size = mem::size_of_val(&*self.ptr);
let align = mem::align_of_val(&*self.ptr);
let layout = alloc::Layout::from_size_align(size, align).unwrap();
ptr::drop_in_place(self.ptr);
alloc::dealloc(self.ptr as *mut u8, layout);
}
}
}
unsafe impl<T: Send> Send for Box<T> {}
unsafe impl<T: Sync> Sync for Box<T> {}
impl<T: ?Sized> core::ops::Deref for Box<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.ptr }
}
}
impl<T: ?Sized> core::ops::DerefMut for Box<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.ptr }
}
}
impl<T: ?Sized> borrow::Borrow<T> for Box<T> {
fn borrow(&self) -> &T {
&**self
}
}
impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: ?Sized> AsRef<T> for Box<T> {
fn as_ref(&self) -> &T {
&**self
}
}
impl<T: ?Sized> AsMut<T> for Box<T> {
fn as_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: Clone> Clone for Box<T> {
#[inline]
fn clone(&self) -> Box<T> {
Self::new(self.as_ref().clone())
}
}
impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
#[inline]
fn eq(&self, other: &Box<T>) -> bool {
PartialEq::eq(&**self, &**other)
}
#[allow(clippy::partialeq_ne_impl)]
#[inline]
fn ne(&self, other: &Box<T>) -> bool {
PartialEq::ne(&**self, &**other)
}
}
impl<T: ?Sized + Eq> Eq for Box<T> {}
impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
#[inline]
fn partial_cmp(&self, other: &Box<T>) -> Option<core::cmp::Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
#[inline]
fn lt(&self, other: &Box<T>) -> bool {
PartialOrd::lt(&**self, &**other)
}
#[inline]
fn le(&self, other: &Box<T>) -> bool {
PartialOrd::le(&**self, &**other)
}
#[inline]
fn ge(&self, other: &Box<T>) -> bool {
PartialOrd::ge(&**self, &**other)
}
#[inline]
fn gt(&self, other: &Box<T>) -> bool {
PartialOrd::gt(&**self, &**other)
}
}
impl<T: ?Sized + Ord> Ord for Box<T> {
#[inline]
fn cmp(&self, other: &Box<T>) -> core::cmp::Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<T: ?Sized + hash::Hash> hash::Hash for Box<T> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}