#![feature(allocator_api)]
pub use fallacy_clone::{AllocError, TryClone};
pub use std::alloc::{Allocator, Global, Layout};
use std::boxed::Box as StdBox;
use std::fmt;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use std::result::Result;
#[derive(Ord, PartialOrd, Eq, PartialEq, Hash)]
#[repr(transparent)]
pub struct Box<T: ?Sized, A: Allocator = Global>(StdBox<T, A>);
impl<T> Box<T> {
#[inline]
pub fn try_new(x: T) -> Result<Self, AllocError> {
Ok(Box(StdBox::try_new(x).map_err(|_| AllocError::new(Layout::new::<T>()))?))
}
}
impl<T: ?Sized> Box<T> {
#[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self {
Box(StdBox::from_raw(raw))
}
}
impl<T, A: Allocator> Box<T, A> {
#[inline]
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
Ok(Box(
StdBox::try_new_in(x, alloc).map_err(|_| AllocError::new(Layout::new::<T>()))?
))
}
}
impl<T: ?Sized, A: Allocator> Box<T, A> {
#[inline]
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
Box(StdBox::from_raw_in(raw, alloc))
}
#[inline]
pub fn into_raw(b: Self) -> *mut T {
StdBox::into_raw(b.0)
}
#[inline]
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
StdBox::into_raw_with_allocator(b.0)
}
#[inline]
pub fn allocator(b: &Self) -> &A {
StdBox::allocator(&b.0)
}
#[inline]
pub fn leak<'a>(b: Self) -> &'a mut T
where
A: 'a,
{
StdBox::leak(b.0)
}
#[inline]
pub fn into_std(self) -> StdBox<T, A> {
self.0
}
#[inline]
pub fn from_std(b: StdBox<T, A>) -> Self {
Box(b)
}
}
impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.0.deref()
}
}
impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.0.deref_mut()
}
}
impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> {
#[inline]
fn as_ref(&self) -> &T {
self.0.as_ref()
}
}
impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
#[inline]
fn as_mut(&mut self) -> &mut T {
self.0.as_mut()
}
}
impl<T: fmt::Display + ?Sized, A: Allocator> fmt::Display for Box<T, A> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl<T: fmt::Debug + ?Sized, A: Allocator> fmt::Debug for Box<T, A> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&self.0, f)
}
}
impl<T: TryClone, A: Allocator + TryClone> TryClone for Box<T, A> {
#[inline]
fn try_clone(&self) -> Result<Self, AllocError> {
let clone = self.0.try_clone()?;
Ok(Box::from_std(clone))
}
#[inline]
fn try_clone_from(&mut self, source: &Self) -> Result<(), AllocError> {
self.as_mut().try_clone_from(source)
}
}
#[cfg(feature = "serde")]
mod serde {
use crate::Box;
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
impl<T> Serialize for Box<T>
where
T: ?Sized + Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<'de, T> Deserialize<'de> for Box<T>
where
T: Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let val = Deserialize::deserialize(deserializer)?;
Box::try_new(val).map_err(D::Error::custom)
}
}
}