use core::cmp::Ordering;
use core::fmt::{self, Debug, Display, Pointer, Formatter};
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::mem;
use core::ops::{Deref, DerefMut, Index, IndexMut, Add, AddAssign};
use core::ptr::NonNull;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use crate::block::{Block, Layout};
use crate::alloc::{AllocTag, Hold, Holder, HoldError};
use crate::lease::{arc, ArcHeader, ArcError, Lease, DynamicLease, Ref, Hard, Soft};
use crate::resident::{Resident, ResidentFromValue, ResidentFromClone,
ResidentFromCloneUnchecked, ResidentFromCopy,
ResidentFromCopyUnchecked, ResidentFromEmpty,
ResidentWithCapacity, ResidentUnwrap, ResidentDeref,
ResidentDerefMut, ResidentAsRef, ResidentAsMut,
ResidentIndex, ResidentIndexMut, ResidentAdd,
ResidentAddAssign, ResidentIntoIterator,
ResidentIntoRefIterator, ResidentIntoMutIterator,
ResidentPartialEq, ResidentEq, ResidentPartialOrd,
ResidentOrd, ResidentHash, ResidentDisplay, ResidentDebug};
pub struct Mut<'a, R: Resident> {
data: NonNull<R::Data>,
data_lifetime: PhantomData<R::Data>,
meta_lifetime: PhantomData<ArcHeader<R::Meta>>,
hold_lifetime: PhantomData<&'a ()>,
}
unsafe impl<'a, R: Resident> Send for Mut<'a, R> where R::Data: Send, R::Meta: Send {
}
unsafe impl<'a, R: Resident> Sync for Mut<'a, R> where R::Data: Sync, R::Meta: Sync {
}
impl<'a, R: Resident> Mut<'a, R> {
#[inline]
pub fn try_hold_new_meta<T, M>(hold: &dyn Hold<'a>, data: T, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromValue<Mut<'a, R>, T, M>
{
unsafe {
let resident = arc::alloc_new::<R, Mut<'a, R>, T, M>(hold, &data, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, data, meta);
Ok(lease)
}
}
#[inline]
pub fn try_hold_clone_meta<T: ?Sized, M>(hold: &dyn Hold<'a>, data: &T, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromClone<Mut<'a, R>, T, M>
{
unsafe {
let resident = arc::alloc_clone::<R, Mut<'a, R>, T, M>(hold, &data, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, data, meta);
Ok(lease)
}
}
#[inline]
pub unsafe fn try_hold_clone_unchecked_meta<T: ?Sized, M>(hold: &dyn Hold<'a>, data: &T, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCloneUnchecked<Mut<'a, R>, T, M>
{
let resident = arc::alloc_clone_unchecked::<R, Mut<'a, R>, T, M>(hold, &data, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, data, meta);
Ok(lease)
}
#[inline]
pub fn try_hold_copy_meta<T: ?Sized, M>(hold: &dyn Hold<'a>, data: &T, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCopy<Mut<'a, R>, T, M>
{
unsafe {
let resident = arc::alloc_copy::<R, Mut<'a, R>, T, M>(hold, &data, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, data, meta);
Ok(lease)
}
}
#[inline]
pub unsafe fn try_hold_copy_unchecked_meta<T: ?Sized, M>(hold: &dyn Hold<'a>, data: &T, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCopyUnchecked<Mut<'a, R>, T, M>
{
let resident = arc::alloc_copy_unchecked::<R, Mut<'a, R>, T, M>(hold, &data, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, data, meta);
Ok(lease)
}
#[inline]
pub fn try_hold_empty_meta<M>(hold: &dyn Hold<'a>, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentFromEmpty<Mut<'a, R>, M>
{
unsafe {
let resident = arc::alloc_empty::<R, Mut<'a, R>, M>(hold, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, meta);
Ok(lease)
}
}
#[inline]
pub fn try_hold_cap_meta<M>(hold: &dyn Hold<'a>, cap: usize, meta: M)
-> Result<Mut<'a, R>, HoldError>
where R: ResidentWithCapacity<Mut<'a, R>, M>
{
unsafe {
let resident = arc::alloc_cap::<R, Mut<'a, R>, M>(hold, cap, &meta, arc::MUT_STATUS_INIT)?;
let mut lease = Mut::from_raw(resident);
R::new_resident(&mut lease, cap, meta);
Ok(lease)
}
}
#[inline]
pub fn try_hold_new<T>(hold: &dyn Hold<'a>, data: T) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromValue<Mut<'a, R>, T>
{
Mut::try_hold_new_meta(hold, data, ())
}
#[inline]
pub fn try_hold_clone<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromClone<Mut<'a, R>, T>
{
Mut::try_hold_clone_meta(hold, data, ())
}
#[inline]
pub unsafe fn try_hold_clone_unchecked<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCloneUnchecked<Mut<'a, R>, T>
{
Mut::try_hold_clone_unchecked_meta(hold, data, ())
}
#[inline]
pub fn try_hold_copy<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCopy<Mut<'a, R>, T>
{
Mut::try_hold_copy_meta(hold, data, ())
}
#[inline]
pub unsafe fn try_hold_copy_unchecked<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromCopyUnchecked<Mut<'a, R>, T>
{
Mut::try_hold_copy_unchecked_meta(hold, data, ())
}
#[inline]
pub fn try_hold_empty(hold: &dyn Hold<'a>) -> Result<Mut<'a, R>, HoldError>
where R: ResidentFromEmpty<Mut<'a, R>>
{
Mut::try_hold_empty_meta(hold, ())
}
#[inline]
pub fn try_hold_cap(hold: &dyn Hold<'a>, cap: usize) -> Result<Mut<'a, R>, HoldError>
where R: ResidentWithCapacity<Mut<'a, R>>
{
Mut::try_hold_cap_meta(hold, cap, ())
}
#[inline]
pub fn hold_new<T>(hold: &dyn Hold<'a>, data: T) -> Mut<'a, R>
where R: ResidentFromValue<Mut<'a, R>, T>
{
Mut::try_hold_new(hold, data).unwrap()
}
#[inline]
pub fn hold_clone<T: ?Sized>(hold: &Hold<'a>, data: &T) -> Mut<'a, R>
where R: ResidentFromClone<Mut<'a, R>, T>
{
Mut::try_hold_clone(hold, data).unwrap()
}
#[inline]
pub unsafe fn hold_clone_unchecked<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Mut<'a, R>
where R: ResidentFromCloneUnchecked<Mut<'a, R>, T>
{
Mut::try_hold_clone_unchecked(hold, data).unwrap()
}
#[inline]
pub fn hold_copy<T: ?Sized>(hold: &Hold<'a>, data: &T) -> Mut<'a, R>
where R: ResidentFromCopy<Mut<'a, R>, T>
{
Mut::try_hold_copy(hold, data).unwrap()
}
#[inline]
pub unsafe fn hold_copy_unchecked<T: ?Sized>(hold: &dyn Hold<'a>, data: &T) -> Mut<'a, R>
where R: ResidentFromCopyUnchecked<Mut<'a, R>, T>
{
Mut::try_hold_copy_unchecked(hold, data).unwrap()
}
#[inline]
pub fn hold_empty(hold: &Hold<'a>) -> Mut<'a, R>
where R: ResidentFromEmpty<Mut<'a, R>>
{
Mut::try_hold_empty(hold).unwrap()
}
#[inline]
pub fn hold_cap(hold: &Hold<'a>, cap: usize) -> Mut<'a, R>
where R: ResidentWithCapacity<Mut<'a, R>>
{
Mut::try_hold_cap(hold, cap).unwrap()
}
#[inline]
pub fn new<T>(data: T) -> Mut<'a, R>
where R: ResidentFromValue<Mut<'a, R>, T>
{
Mut::hold_new(Hold::global(), data)
}
#[inline]
pub fn from_clone<T: ?Sized>(data: &T) -> Mut<'a, R>
where R: ResidentFromClone<Mut<'a, R>, T>
{
Mut::hold_clone(Hold::global(), data)
}
#[inline]
pub unsafe fn from_clone_unchecked<T: ?Sized>(data: &T) -> Mut<'a, R>
where R: ResidentFromCloneUnchecked<Mut<'a, R>, T>
{
Mut::hold_clone_unchecked(Hold::global(), data)
}
#[inline]
pub fn from_copy<T: ?Sized>(data: &T) -> Mut<'a, R>
where R: ResidentFromCopy<Mut<'a, R>, T>
{
Mut::hold_copy(Hold::global(), data)
}
#[inline]
pub unsafe fn from_copy_unchecked<T: ?Sized>(data: &T) -> Mut<'a, R>
where R: ResidentFromCopyUnchecked<Mut<'a, R>, T>
{
Mut::hold_copy_unchecked(Hold::global(), data)
}
#[inline]
pub fn empty() -> Mut<'a, R>
where R: ResidentFromEmpty<Mut<'a, R>>
{
Mut::hold_empty(Hold::global())
}
#[inline]
pub fn with_cap(cap: usize) -> Mut<'a, R>
where R: ResidentWithCapacity<Mut<'a, R>>
{
Mut::hold_cap(Hold::global(), cap)
}
#[inline]
pub unsafe fn from_raw(data: *mut R::Data) -> Mut<'a, R> {
Mut {
data: NonNull::new_unchecked(data),
data_lifetime: PhantomData,
meta_lifetime: PhantomData,
hold_lifetime: PhantomData,
}
}
#[inline]
fn header(this: &Mut<'a, R>) -> *mut ArcHeader<R::Meta> {
arc::header::<R>(this.data.as_ptr())
}
#[inline]
pub fn hard_count(this: &Mut<'a, R>) -> usize {
unsafe { (*Mut::header(this)).hard_count() }
}
#[inline]
pub fn soft_count(this: &Mut<'a, R>) -> usize {
unsafe { (*Mut::header(this)).soft_count() }
}
#[inline]
pub fn ref_count(this: &Mut<'a, R>) -> usize {
unsafe { (*Mut::header(this)).ref_count() }
}
#[inline]
pub fn metadata<'b>(this: &'b Mut<'a, R>) -> &'b R::Meta {
unsafe { &(*Mut::header(this)).meta }
}
#[inline]
pub fn metadata_mut<'b>(this: &'b mut Mut<'a, R>) -> &'b mut R::Meta {
unsafe { &mut (*Mut::header(this)).meta }
}
pub fn try_into_ref(this: Mut<'a, R>) -> Result<Ref<'a, R>, ArcError> {
unsafe {
let data = this.data.as_ptr();
let header = arc::header::<R>(data);
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_ref_count = (old_status & arc::REF_COUNT_MASK) >> arc::REF_COUNT_SHIFT;
let new_ref_count = old_ref_count.wrapping_add(1);
if new_ref_count > arc::REF_COUNT_MAX {
return Err(ArcError::RefCountOverflow);
}
let new_status = old_status & !(arc::REF_COUNT_MASK | arc::MUT_FLAG);
let new_status = new_status | new_ref_count << arc::REF_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, SeqCst, Relaxed) {
Ok(_) => {
mem::forget(this);
return Ok(Ref::from_raw(data));
},
Err(status) => old_status = status,
}
}
}
}
pub fn into_ref(this: Mut<'a, R>) -> Ref<'a, R> {
Mut::try_into_ref(this).unwrap()
}
pub unsafe fn try_to_hard(this: &Mut<'a, R>) -> Result<Hard<'a, R>, ArcError> {
let data = this.data.as_ptr();
let header = arc::header::<R>(data);
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_hard_count = old_status & arc::HARD_COUNT_MASK;
let new_hard_count = old_hard_count.wrapping_add(1);
if new_hard_count > arc::HARD_COUNT_MAX {
return Err(ArcError::HardCountOverflow);
}
let new_status = old_status & !arc::HARD_COUNT_MASK;
let new_status = new_status | new_hard_count;
match (*header).status.compare_exchange_weak(old_status, new_status, Acquire, Relaxed) {
Ok(_) => return Ok(Hard::from_raw(data)),
Err(status) => old_status = status,
}
}
}
pub unsafe fn to_hard(this: &Mut<'a, R>) -> Hard<'a, R> {
Mut::try_to_hard(this).unwrap()
}
pub fn into_hard(this: Mut<'a, R>) -> Hard<'a, R> {
unsafe {
let data = this.data.as_ptr();
let header = arc::header::<R>(data);
let mut old_status = (*header).status.load(Relaxed);
loop {
let new_status = old_status & !arc::MUT_FLAG;
match (*header).status.compare_exchange_weak(old_status, new_status, Release, Relaxed) {
Ok(_) => {
mem::forget(this);
return Hard::from_raw(data);
},
Err(status) => old_status = status,
}
}
}
}
pub unsafe fn try_to_soft(this: &Mut<'a, R>) -> Result<Soft<'a, R>, ArcError> {
let data = this.data.as_ptr();
let header = arc::header::<R>(data);
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
let new_soft_count = old_soft_count.wrapping_add(1);
if new_soft_count > arc::SOFT_COUNT_MAX {
return Err(ArcError::SoftCountOverflow);
}
let new_status = old_status & !arc::SOFT_COUNT_MASK;
let new_status = new_status | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, Acquire, Relaxed) {
Ok(_) => return Ok(Soft::from_raw(data)),
Err(status) => old_status = status,
}
}
}
pub unsafe fn to_soft(this: &Mut<'a, R>) -> Soft<'a, R> {
Mut::try_to_soft(this).unwrap()
}
pub fn try_into_soft(this: Mut<'a, R>) -> Result<Soft<'a, R>, ArcError> {
unsafe {
let data = this.data.as_ptr();
let header = arc::header::<R>(data);
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_hard_count = old_status & arc::HARD_COUNT_MASK;
let new_hard_count = match old_hard_count.checked_sub(1) {
Some(hard_count) => hard_count,
None => panic!("hard count underflow"),
};
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
let new_soft_count = old_soft_count.wrapping_add(1);
if new_soft_count > arc::SOFT_COUNT_MAX {
return Err(ArcError::SoftCountOverflow);
}
let new_status = old_status & !(arc::HARD_COUNT_MASK | arc::SOFT_COUNT_MASK | arc::MUT_FLAG);
let new_status = new_status | new_hard_count | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, SeqCst, Relaxed) {
Ok(_) => {
if new_hard_count == 0 {
R::resident_drop(data, &mut (*header).meta);
}
mem::forget(this);
return Ok(Soft::from_raw(data));
},
Err(status) => old_status = status,
}
}
}
}
pub fn into_soft(this: Mut<'a, R>) -> Soft<'a, R> {
Mut::try_into_soft(this).unwrap()
}
#[inline]
pub unsafe fn into_raw(this: Mut<'a, R>) -> *mut R::Data {
let data = this.data.as_ptr();
mem::forget(this);
data
}
#[inline]
pub unsafe fn as_ptr_unchecked(this: &Mut<'a, R>) -> *mut R::Data {
this.data.as_ptr()
}
pub fn try_unwrap(this: Mut<'a, R>) -> Result<R::Target, Mut<'a, R>> where R: ResidentUnwrap<Mut<'a, R>> {
unsafe {
let data = this.data.as_ptr();
let align = mem::align_of_val(&*data);
let offset = mem::size_of::<ArcHeader<R::Meta>>()
.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
let header = (data as *mut u8).wrapping_sub(offset) as *mut ArcHeader<R::Meta>;
let size = offset.wrapping_add(R::resident_size(data, &mut (*header).meta));
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_hard_count = old_status & arc::HARD_COUNT_MASK;
if old_hard_count != 1 {
return Err(this);
}
let new_status = old_status & !(arc::HARD_COUNT_MASK | arc::MUT_FLAG);
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
if old_soft_count == 0 {
(*header).status.store(new_status, Relaxed);
let resident = R::resident_unwrap(&this);
(*header).drop::<R>(data);
let block = Block::from_raw_parts(header as *mut u8, size);
AllocTag::from_ptr(header as *mut u8).dealloc(block);
mem::forget(this);
return Ok(resident);
} else {
let new_soft_count = old_soft_count.wrapping_add(1);
if new_soft_count > arc::SOFT_COUNT_MAX {
return Err(this);
}
let new_status = new_status & !arc::SOFT_COUNT_MASK;
let new_status = new_status | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, Acquire, Relaxed) {
Ok(_) => {
let resident = R::resident_unwrap(&this);
old_status = new_status;
loop {
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
let new_soft_count = match old_soft_count.checked_sub(1) {
Some(soft_count) => soft_count,
None => panic!("soft count underflow"),
};
let new_status = old_status & !arc::SOFT_COUNT_MASK;
let new_status = new_status | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, Release, Relaxed) {
Ok(_) => {
if new_soft_count == 0 {
(*header).drop::<R>(data);
let block = Block::from_raw_parts(header as *mut u8, size);
AllocTag::from_ptr(header as *mut u8).dealloc(block);
}
return Ok(resident);
},
Err(status) => old_status = status,
}
}
},
Err(status) => old_status = status,
}
}
}
}
}
pub fn unwrap(this: Mut<'a, R>) -> R::Target where R: ResidentUnwrap<Mut<'a, R>> {
match Mut::try_unwrap(this) {
Ok(resident) => resident,
Err(_) => panic!("aliased resident"),
}
}
}
impl<'a, R: Resident> Holder<'a> for Mut<'a, R> {
#[inline]
fn holder(&self) -> &'a dyn Hold<'a> {
AllocTag::from_ptr(Mut::header(self) as *mut u8).holder()
}
}
impl<'a, R: Resident> Lease for Mut<'a, R> {
type Data = R::Data;
type Meta = R::Meta;
#[inline]
fn data(&self) -> *mut R::Data {
self.data.as_ptr()
}
#[inline]
fn meta(&self) -> *mut R::Meta {
unsafe { &mut (*Mut::header(self)).meta }
}
}
impl<'a, R: Resident> DynamicLease<'a> for Mut<'a, R> {
unsafe fn realloc(&mut self, new_layout: Layout) -> Result<(), HoldError> {
let new_data = arc::realloc::<R>(self.data.as_ptr(), new_layout)?;
self.data = NonNull::new_unchecked(new_data);
Ok(())
}
unsafe fn resize(&mut self, new_layout: Layout) -> Result<(), HoldError> {
let new_data = arc::resize::<R>(self.data.as_ptr(), new_layout)?;
self.data = NonNull::new_unchecked(new_data);
Ok(())
}
}
impl<'a, R: ResidentDeref<Mut<'a, R>>> Deref for Mut<'a, R> {
type Target = R::Target;
#[inline]
fn deref(&self) -> &R::Target {
R::resident_deref(self)
}
}
impl<'a, R: ResidentDerefMut<Mut<'a, R>>> DerefMut for Mut<'a, R> {
#[inline]
fn deref_mut(&mut self) -> &mut R::Target {
R::resident_deref_mut(self)
}
}
impl<'a, R: ResidentAsRef<Mut<'a, R>, T>, T: ?Sized> AsRef<T> for Mut<'a, R> {
#[inline]
fn as_ref(&self) -> &T {
R::resident_as_ref(self)
}
}
impl<'a, R: ResidentAsMut<Mut<'a, R>, T>, T: ?Sized> AsMut<T> for Mut<'a, R> {
#[inline]
fn as_mut(&mut self) -> &mut T {
R::resident_as_mut(self)
}
}
impl<'a, R: ResidentIndex<Mut<'a, R>, Idx>, Idx> Index<Idx> for Mut<'a, R> {
type Output = R::Output;
#[inline]
fn index(&self, index: Idx) -> &R::Output {
R::resident_index(self, index)
}
}
impl<'a, R: ResidentIndexMut<Mut<'a, R>, Idx>, Idx> IndexMut<Idx> for Mut<'a, R> {
#[inline]
fn index_mut(&mut self, index: Idx) -> &mut R::Output {
R::resident_index_mut(self, index)
}
}
impl<'a, R: ResidentAdd<Mut<'a, R>, Rhs>, Rhs> Add<Rhs> for Mut<'a, R> {
type Output = R::Output;
#[inline]
fn add(self, rhs: Rhs) -> R::Output {
R::resident_add(self, rhs)
}
}
impl<'a, R: ResidentAddAssign<Mut<'a, R>, Rhs>, Rhs> AddAssign<Rhs> for Mut<'a, R> {
#[inline]
fn add_assign(&mut self, rhs: Rhs) {
R::resident_add_assign(self, rhs);
}
}
impl<'a, R: ResidentIntoIterator<Mut<'a, R>>> IntoIterator for Mut<'a, R> {
type Item = R::Item;
type IntoIter = R::IntoIter;
#[inline]
fn into_iter(self) -> R::IntoIter {
R::resident_into_iter(self)
}
}
impl<'a, R: ResidentIntoRefIterator<'a, Mut<'a, R>>> IntoIterator for &'a Mut<'a, R> {
type Item = R::Item;
type IntoIter = R::IntoIter;
#[inline]
fn into_iter(self) -> R::IntoIter {
R::resident_into_iter(self)
}
}
impl<'a, R: ResidentIntoMutIterator<'a, Mut<'a, R>>> IntoIterator for &'a mut Mut<'a, R> {
type Item = R::Item;
type IntoIter = R::IntoIter;
#[inline]
fn into_iter(self) -> R::IntoIter {
R::resident_into_iter(self)
}
}
impl<'a, R: ResidentPartialEq<Mut<'a, R>, T>, T: ?Sized> PartialEq<T> for Mut<'a, R> {
#[inline]
fn eq(&self, other: &T) -> bool {
R::resident_eq(self, other)
}
#[inline]
fn ne(&self, other: &T) -> bool {
R::resident_ne(self, other)
}
}
impl<'a, R: ResidentEq<Mut<'a, R>>> Eq for Mut<'a, R> {
}
impl<'a, R: ResidentPartialOrd<Mut<'a, R>, T>, T: ?Sized> PartialOrd<T> for Mut<'a, R> {
#[inline]
fn partial_cmp(&self, other: &T) -> Option<Ordering> {
R::resident_partial_cmp(self, other)
}
#[inline]
fn lt(&self, other: &T) -> bool {
R::resident_lt(self, other)
}
#[inline]
fn le(&self, other: &T) -> bool {
R::resident_le(self, other)
}
#[inline]
fn ge(&self, other: &T) -> bool {
R::resident_ge(self, other)
}
#[inline]
fn gt(&self, other: &T) -> bool {
R::resident_gt(self, other)
}
}
impl<'a, R: ResidentOrd<Mut<'a, R>>> Ord for Mut<'a, R> {
#[inline]
fn cmp(&self, other: &Mut<'a, R>) -> Ordering {
R::resident_cmp(self, other)
}
}
impl<'a, R: ResidentHash<Mut<'a, R>>> Hash for Mut<'a, R> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
R::resident_hash(self, state);
}
}
impl<'a, R: ResidentDisplay<Mut<'a, R>>> Display for Mut<'a, R> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
R::resident_fmt(self, f)
}
}
impl<'a, R: ResidentDebug<Mut<'a, R>>> Debug for Mut<'a, R> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
R::resident_fmt(self, f)
}
}
impl<'a, R: Resident> Pointer for Mut<'a, R> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Pointer::fmt(&self.data.as_ptr(), f)
}
}
unsafe impl<'a, #[may_dangle] R: Resident> Drop for Mut<'a, R> {
fn drop(&mut self) {
unsafe {
let data = self.data.as_ptr();
let align = mem::align_of_val(&*data);
let offset = mem::size_of::<ArcHeader<R::Meta>>()
.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
let header = (data as *mut u8).wrapping_sub(offset) as *mut ArcHeader<R::Meta>;
let size = offset.wrapping_add(R::resident_size(data, &mut (*header).meta));
let mut old_status = (*header).status.load(Relaxed);
loop {
let old_hard_count = old_status & arc::HARD_COUNT_MASK;
let new_hard_count = match old_hard_count.checked_sub(1) {
Some(hard_count) => hard_count,
None => panic!("hard count underflow"),
};
let new_status = old_status & !(arc::HARD_COUNT_MASK | arc::MUT_FLAG);
let new_status = new_status | new_hard_count;
if new_hard_count != 0 {
match (*header).status.compare_exchange_weak(old_status, new_status, Release, Relaxed) {
Ok(_) => return,
Err(status) => old_status = status,
}
} else {
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
if old_soft_count == 0 {
(*header).status.store(new_status, Relaxed);
R::resident_drop(data, &mut (*header).meta);
(*header).drop::<R>(data);
let block = Block::from_raw_parts(header as *mut u8, size);
AllocTag::from_ptr(header as *mut u8).dealloc(block);
return;
} else {
let new_soft_count = old_soft_count.wrapping_add(1);
if new_soft_count > arc::SOFT_COUNT_MAX {
panic!("soft count overflow");
}
let new_status = new_status & !arc::SOFT_COUNT_MASK;
let new_status = new_status | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, SeqCst, Relaxed) {
Ok(_) => {
R::resident_drop(data, &mut (*header).meta);
old_status = new_status;
loop {
let old_soft_count = (old_status & arc::SOFT_COUNT_MASK) >> arc::SOFT_COUNT_SHIFT;
let new_soft_count = match old_soft_count.checked_sub(1) {
Some(soft_count) => soft_count,
None => panic!("soft count underflow"),
};
let new_status = old_status & !arc::SOFT_COUNT_MASK;
let new_status = new_status | new_soft_count << arc::SOFT_COUNT_SHIFT;
match (*header).status.compare_exchange_weak(old_status, new_status, Release, Relaxed) {
Ok(_) => {
if new_soft_count == 0 {
(*header).drop::<R>(data);
let block = Block::from_raw_parts(header as *mut u8, size);
AllocTag::from_ptr(header as *mut u8).dealloc(block);
}
return;
},
Err(status) => old_status = status,
}
}
},
Err(status) => old_status = status,
}
}
}
}
}
}
}