use crate::*;
use super::Arc;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct ArcBox<T: ?Sized>(pub(crate) Arc<T>);
impl<T> ArcBox<T> {
#[inline]
pub fn new(data: T) -> Self {
ArcBox(Arc::new(data))
}
}
impl<T: Clone> Clone for ArcBox<T> {
#[inline]
fn clone(&self) -> ArcBox<T> {
ArcBox(Arc::new(self.0.deref().clone()))
}
}
impl<T: ?Sized> ArcBox<T> {
#[inline]
pub fn shareable(self) -> Arc<T> {
self.0
}
}
impl<T: ?Sized> Deref for ArcBox<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&*self.0
}
}
impl<T: ?Sized> DerefMut for ArcBox<T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0.ptr.as_ptr() }
}
}
impl<T: ?Sized> Borrow<T> for ArcBox<T> {
#[inline]
fn borrow(&self) -> &T {
&**self
}
}
impl<T: ?Sized> AsRef<T> for ArcBox<T> {
#[inline]
fn as_ref(&self) -> &T {
&**self
}
}
impl<T: ?Sized> BorrowMut<T> for ArcBox<T> {
#[inline]
fn borrow_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: ?Sized> AsMut<T> for ArcBox<T> {
#[inline]
fn as_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: ?Sized> AsRef<*const T> for ArcBox<T> {
#[inline]
fn as_ref(&self) -> &*const T {
unsafe { &*(self as *const ArcBox<T> as *const *const T) }
}
}
impl<T: ?Sized> AsRef<*mut T> for ArcBox<T> {
#[inline]
fn as_ref(&self) -> &*mut T {
unsafe { &*(self as *const ArcBox<T> as *const *mut T) }
}
}
impl<T: ?Sized> AsRef<ptr::NonNull<T>> for ArcBox<T> {
#[inline]
fn as_ref(&self) -> &ptr::NonNull<T> {
unsafe { &*(self as *const ArcBox<T> as *const ptr::NonNull<T>) }
}
}
impl<T: Default> Default for ArcBox<T> {
#[inline]
fn default() -> ArcBox<T> {
ArcBox::new(Default::default())
}
}
#[cfg(feature = "stable_deref_trait")]
unsafe impl<T: ?Sized> StableDeref for ArcBox<T> {}
#[cfg(feature = "serde")]
impl<'de, T: Deserialize<'de>> Deserialize<'de> for ArcBox<T> {
fn deserialize<D>(deserializer: D) -> Result<ArcBox<T>, D::Error>
where
D: ::serde::de::Deserializer<'de>,
{
T::deserialize(deserializer).map(ArcBox::new)
}
}
#[cfg(feature = "serde")]
impl<T: ?Sized + Serialize> Serialize for ArcBox<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ::serde::ser::Serializer,
{
(**self).serialize(serializer)
}
}
#[cfg(feature = "erasable")]
unsafe impl<T: ?Sized + Erasable> ErasablePtr for ArcBox<T> {
fn erase(this: Self) -> ErasedPtr {
ErasablePtr::erase(this.0)
}
unsafe fn unerase(this: ErasedPtr) -> Self {
ArcBox(ErasablePtr::unerase(this))
}
}
#[cfg(feature = "slice-dst")]
mod slice_dst_impl {
use super::*;
use slice_dst::{AllocSliceDst, SliceDst, TryAllocSliceDst};
#[cfg(feature = "slice-dst")]
unsafe impl<S: ?Sized + SliceDst> TryAllocSliceDst<S> for ArcBox<S> {
unsafe fn try_new_slice_dst<I, E>(len: usize, init: I) -> Result<Self, E>
where
I: FnOnce(ptr::NonNull<S>) -> Result<(), E>,
{
Arc::try_new_slice_dst(len, init).map(ArcBox)
}
}
unsafe impl<S: ?Sized + SliceDst> AllocSliceDst<S> for ArcBox<S> {
unsafe fn new_slice_dst<I>(len: usize, init: I) -> Self
where
I: FnOnce(ptr::NonNull<S>),
{
ArcBox(Arc::new_slice_dst(len, init))
}
}
}
#[cfg(feature = "arbitrary")]
mod arbitrary_impl {
use super::*;
use arbitrary::{Arbitrary, Result, Unstructured};
impl<T: Arbitrary> Arbitrary for ArcBox<T> {
fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
T::arbitrary(u).map(ArcBox::new)
}
fn arbitrary_take_rest(u: Unstructured<'_>) -> Result<Self> {
T::arbitrary_take_rest(u).map(ArcBox::new)
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
T::size_hint(depth)
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
Box::new(self.deref().shrink().map(ArcBox::new))
}
}
}
#[cfg(feature = "stowaway")]
unsafe impl<T> Stowable for ArcBox<T> {}
#[cfg(feature = "stowaway")]
#[test]
fn basic_stowaway_test() {
use stowaway::Stowaway;
let arc = ArcBox::new(35);
let cloned = arc.clone();
let stowed_arc = Stowaway::new(arc);
let storage = Stowaway::into_raw(stowed_arc);
let new_stowed: Stowaway<ArcBox<u32>> = unsafe { Stowaway::from_raw(storage) };
let unstowed: ArcBox<u32> = Stowaway::into_inner(new_stowed);
assert_eq!(unstowed, cloned);
}