use base::borrow;
use base::cmp::Ordering;
use base::convert::{From, AsMut};
use base::fmt;
use base::hash::{Hash, Hasher};
use base::marker::{PhantomData, Unpin};
use base::mem;
use base::ops::{Deref, DerefMut};
use base::ptr::{self, NonNull};
use base::sync::atomic;
use base::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use base::borrow::BorrowMut;
use base::prelude::v1::*;
use smart_pointer::{SmartPointer, IntoMut, SmartPointerMut};
use crate::ReferenceCounted;
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
macro_rules! acquire {
($x:expr) => {
atomic::fence(Acquire)
};
}
pub struct Arc<T: ?Sized> {
ptr: NonNull<ArcInner<T>>,
phantom: PhantomData<ArcInner<T>>,
}
unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
impl<T: ?Sized> Arc<T> {
fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
Self { ptr, phantom: PhantomData }
}
}
struct ArcInner<T: ?Sized> {
strong: atomic::AtomicUsize,
data: T,
}
impl<T: ?Sized> Arc<T> {
#[inline]
fn inner(&self) -> &ArcInner<T> {
unsafe { self.ptr.as_ref() }
}
unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
unsafe { &mut (*this.ptr.as_ptr()).data }
}
#[inline(never)]
unsafe fn drop_slow(&mut self) {
unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) };
}
fn ptr(&self) -> *mut ArcInner<T> {
self.ptr.as_ptr()
}
fn ref_count(&self) -> usize {
self.inner().strong.load(SeqCst)
}
}
impl<T: ?Sized> Clone for Arc<T> {
#[inline]
fn clone(&self) -> Arc<T> {
let old_size = self.inner().strong.fetch_add(1, Relaxed);
if old_size > MAX_REFCOUNT {
panic!();
}
Self::from_inner(self.ptr)
}
}
impl<T: ?Sized> Drop for Arc<T> {
#[inline]
fn drop(&mut self) {
if self.inner().strong.fetch_sub(1, Release) != 1 {
return;
}
acquire!(self.inner().strong);
unsafe {
self.drop_slow();
}
}
}
impl<T: ?Sized> Deref for Arc<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
&self.inner().data
}
}
impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
fn borrow(&self) -> &T {
&**self
}
}
impl<T: ?Sized> AsRef<T> for Arc<T> {
fn as_ref(&self) -> &T {
&**self
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for Arc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T: ?Sized> fmt::Pointer for Arc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&(&**self as *const T), f)
}
}
impl<T: ?Sized> SmartPointer<T> for Arc<T> {
fn new(data: T) -> Arc<T> where T: Sized {
let x: Box<_> = Box::new(ArcInner {
strong: atomic::AtomicUsize::new(1),
data,
});
Self::from_inner(Box::leak(x).into())
}
fn try_unwrap(this: Self) -> Result<T, Self> where T: Sized {
if this.inner().strong.compare_exchange(1, 0, Relaxed, Relaxed).is_err() {
return Err(this);
}
acquire!(this.inner().strong);
unsafe {
let elem = ptr::read(&this.ptr.as_ref().data);
mem::forget(this);
Ok(elem)
}
}
}
pub struct UniqueArc<T: ?Sized>(Arc<T>);
unsafe impl<T: ?Sized + Sync + Send> Send for UniqueArc<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for UniqueArc<T> {}
impl<T: ?Sized> Deref for UniqueArc<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.0.deref()
}
}
impl<T: ?Sized> borrow::Borrow<T> for UniqueArc<T> {
fn borrow(&self) -> &T {
self.0.borrow()
}
}
impl<T: ?Sized> AsRef<T> for UniqueArc<T> {
fn as_ref(&self) -> &T {
self.0.as_ref()
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for UniqueArc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for UniqueArc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: ?Sized> fmt::Pointer for UniqueArc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: ?Sized> SmartPointer<T> for UniqueArc<T> {
fn new(data: T) -> Self where T: Sized {
UniqueArc(Arc::new(data))
}
fn try_unwrap(this: Self) -> Result<T, Self> where T: Sized {
let this = this.0;
acquire!(this.inner().strong);
unsafe {
let elem = ptr::read(&this.ptr.as_ref().data);
mem::forget(this);
Ok(elem)
}
}
}
impl<T: ?Sized> DerefMut for UniqueArc<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut (*self.0.ptr()).data }
}
}
impl<T: ?Sized> BorrowMut<T> for UniqueArc<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: ?Sized> AsMut<T> for UniqueArc<T> {
fn as_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T: ?Sized> SmartPointerMut<T> for UniqueArc<T> {}
impl<T: ?Sized> Into<Arc<T>> for UniqueArc<T> {
fn into(self) -> Arc<T> {
self.0
}
}
impl<T: ?Sized> IntoMut<T> for Arc<T> {
type MutablePointer = UniqueArc<T>;
fn can_make_mut(this: &Self) -> bool {
this.ref_count() == 1
}
unsafe fn into_mut_unchecked(this: Self) -> Self::MutablePointer {
UniqueArc(this)
}
unsafe fn get_mut_unchecked(this: &Self) -> &mut T {
unsafe { &mut (*this.ptr.as_ptr()).data }
}
}
impl<T: ?Sized> ReferenceCounted<T> for Arc<T> {
fn reference_count(this: &Self) -> usize {
this.inner().strong.load(SeqCst)
}
}
impl<T: Default> Default for Arc<T> {
fn default() -> Arc<T> {
Arc::new(Default::default())
}
}
impl<T: Default> Default for UniqueArc<T> {
fn default() -> UniqueArc<T> {
UniqueArc::new(Default::default())
}
}
impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
#[inline]
fn eq(&self, other: &Arc<T>) -> bool {
(**self).eq(&**other)
}
#[inline]
fn ne(&self, other: &Arc<T>) -> bool {
(**self).ne(&**other)
}
}
impl<T: ?Sized + Eq> Eq for Arc<T> {}
impl<T: ?Sized + PartialEq> PartialEq for UniqueArc<T> {
#[inline]
fn eq(&self, other: &UniqueArc<T>) -> bool {
(**self).eq(&**other)
}
#[inline]
fn ne(&self, other: &UniqueArc<T>) -> bool {
(**self).ne(&**other)
}
}
impl<T: ?Sized + Eq> Eq for UniqueArc<T> {}
impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other)
}
fn lt(&self, other: &Arc<T>) -> bool {
*(*self) < *(*other)
}
fn le(&self, other: &Arc<T>) -> bool {
*(*self) <= *(*other)
}
fn gt(&self, other: &Arc<T>) -> bool {
*(*self) > *(*other)
}
fn ge(&self, other: &Arc<T>) -> bool {
*(*self) >= *(*other)
}
}
impl<T: ?Sized + PartialOrd> PartialOrd for UniqueArc<T> {
fn partial_cmp(&self, other: &UniqueArc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other)
}
fn lt(&self, other: &UniqueArc<T>) -> bool {
*(*self) < *(*other)
}
fn le(&self, other: &UniqueArc<T>) -> bool {
*(*self) <= *(*other)
}
fn gt(&self, other: &UniqueArc<T>) -> bool {
*(*self) > *(*other)
}
fn ge(&self, other: &UniqueArc<T>) -> bool {
*(*self) >= *(*other)
}
}
impl<T: ?Sized + Ord> Ord for Arc<T> {
fn cmp(&self, other: &Arc<T>) -> Ordering {
(**self).cmp(&**other)
}
}
impl<T: ?Sized + Ord> Ord for UniqueArc<T> {
fn cmp(&self, other: &UniqueArc<T>) -> Ordering {
(**self).cmp(&**other)
}
}
impl<T> From<T> for Arc<T> {
fn from(t: T) -> Self {
Arc::new(t)
}
}
impl<T> From<T> for UniqueArc<T> {
fn from(t: T) -> Self {
UniqueArc::new(t)
}
}
impl<T: ?Sized + Hash> Hash for Arc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state)
}
}
impl<T: ?Sized + Hash> Hash for UniqueArc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state)
}
}
impl<T: ?Sized> Unpin for Arc<T> {}
impl<T: ?Sized> Unpin for UniqueArc<T> {}