| 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); |
| } |
| } |