pub struct Asc<T: ?Sized, A = System>where
A: GlobalAlloc,{ /* private fields */ }
Expand description
A thread-safe strong reference-counting pointer. ‘Asc’ stands for ‘Atomic Strong Counted.’
It behaves like std::Sync::Arc
except for that this treats only strong pointer; i.e. Asc
gives up weak pointer for the performance.
The inherent methods of Asc
are all associated funcitons, which means that you have to call
them as e.g., Asc::get_mut(&mut value)
instead of value.get_mut()
. This avoids conflicts
with methods of the inner type T
.
§Thread Safety
Unlike to Sc
, Asc
uses atomic operations for its reference counting. This means that it
is thread-safe. The disadvangate is that atomic operations are more expensive than ordinary
memory access.
Implementations§
Source§impl<T, A> Asc<T, A>where
A: GlobalAlloc,
impl<T, A> Asc<T, A>where
A: GlobalAlloc,
Source§impl<A> Asc<dyn Any, A>where
A: GlobalAlloc,
impl<A> Asc<dyn Any, A>where
A: GlobalAlloc,
Source§impl<T, A> Asc<T, A>where
A: GlobalAlloc,
impl<T, A> Asc<T, A>where
A: GlobalAlloc,
Source§impl<T: ?Sized, A> Asc<T, A>where
A: GlobalAlloc,
impl<T: ?Sized, A> Asc<T, A>where
A: GlobalAlloc,
Sourcepub fn as_ptr(this: &Self) -> *const T
pub fn as_ptr(this: &Self) -> *const T
Provides a raw pointer to the data.
The counts are not affected in any way and the Asc
is not consumed. The pointer is valid
for as long as another Asc
instance is pointing to the address.
§Examples
use counting_pointer::Asc;
let x: Asc<String> = Asc::from(String::from("Hello"));
let x_ptr = Asc::as_ptr(&x);
assert_eq!("Hello", unsafe { &*x_ptr });
Sourcepub fn count(this: &Self) -> usize
pub fn count(this: &Self) -> usize
Returns the number of Asc
pointers pointing to the same address.
§Examples
use counting_pointer::Asc;
let five: Asc<i32> = Asc::from(5);
assert_eq!(1, Asc::count(&five));
let _also_five = five.clone();
assert_eq!(2, Asc::count(&five));
assert_eq!(2, Asc::count(&_also_five));
drop(five);
assert_eq!(1, Asc::count(&_also_five));
Sourcepub fn get_mut(this: &mut Self) -> Option<&mut T>
pub fn get_mut(this: &mut Self) -> Option<&mut T>
Returns a mutable reference into the given Asc
, if no other Asc
instance is pointing to
the same address; otherwise returns None
.
See also make_mut
, which will clone
the inner value when some other Asc
instances
are.
§Examples
use counting_pointer::Asc;
let mut x: Asc<i32> = Asc::from(3);
assert_eq!(3, *x);
*Asc::get_mut(&mut x).unwrap() = 4;
assert_eq!(4, *x);
let _y = x.clone();
let n = Asc::get_mut(&mut x);
assert!(n.is_none());
Sourcepub fn ptr_eq(this: &Self, other: &Self) -> bool
pub fn ptr_eq(this: &Self, other: &Self) -> bool
Returns true
if the two Asc
instances point to the same address, or false
.
§Examples
use counting_pointer::Asc;
let five: Asc<i32> = Asc::from(5);
let same_five = five.clone();
let other_five: Asc<i32> = Asc::from(5);
assert_eq!(true, Asc::ptr_eq(&five, &same_five));
assert_eq!(false, Asc::ptr_eq(&five, &other_five));
Sourcepub fn into_raw_alloc(this: Self) -> (*const T, A)
pub fn into_raw_alloc(this: Self) -> (*const T, A)
Consumes this
, returning the wrapped pointer and the allocator.
To avoid memory leak, the returned pointer must be converted back to an Asc
using
from_raw_alloc
.
Using this function and from_raw_alloc
, user can create an Asc<T: ?Sized>
instance.
§Examples
use counting_pointer::Asc;
let asc: Asc<String> = Asc::from("Foo".to_string());
let (ptr, alloc) = Asc::into_raw_alloc(asc);
let _asc: Asc<dyn AsRef<str>> = unsafe { Asc::from_raw_alloc(ptr, alloc) };
Sourcepub unsafe fn from_raw_alloc(ptr: *const T, alloc: A) -> Self
pub unsafe fn from_raw_alloc(ptr: *const T, alloc: A) -> Self
Constructs a new instance from a raw pointer and allocator.
The raw pointer must have been previously returned by a call to into_raw_alloc
.
Using this function and into_raw_alloc
, user can create an Asc<T: ?Sized>
instance.
§Safety
It may lead to memory unsafety to use improperly, even if the returned value will never be accessed.
§Examples
use counting_pointer::Asc;
let asc: Asc<String> = Asc::from("Foo".to_string());
let (ptr, alloc) = Asc::into_raw_alloc(asc);
let _asc: Asc<dyn AsRef<str>> = unsafe { Asc::from_raw_alloc(ptr, alloc) };
Source§impl<T: Clone, A> Asc<T, A>where
A: GlobalAlloc + Clone,
impl<T: Clone, A> Asc<T, A>where
A: GlobalAlloc + Clone,
Sourcepub fn make_mut(this: &mut Self) -> &mut T
pub fn make_mut(this: &mut Self) -> &mut T
Makes a mutable reference into the given Asc
.
If another Asc
instance is pointing to the same address, make_mut
will clone
the inner
value to a new allocation to ensure unique ownership.
See also get_mut
, which will fail rather than cloning.
§Examples
use counting_pointer::Asc;
let mut data: Asc<i32> = Asc::from(5);
assert_eq!(5, *data);
*Asc::make_mut(&mut data) += 1; // Won't clone anything.
assert_eq!(6, *data);
let mut data2 = data.clone(); // Won't clone the inner data.
*Asc::make_mut(&mut data) += 1; // Clones inner data.
assert_eq!(7, *data);
assert_eq!(6, *data2);
Source§impl<A> Asc<dyn Any, A>where
A: GlobalAlloc,
impl<A> Asc<dyn Any, A>where
A: GlobalAlloc,
Sourcepub fn downcast<T: Any>(self) -> Result<Asc<T, A>, Self>
pub fn downcast<T: Any>(self) -> Result<Asc<T, A>, Self>
Attempts to downcast the Asc<dyn Any, A>
to a concrete type.
§Examples
use std::alloc::System;
use std::any::Any;
use counting_pointer::Asc;
let sc = Asc::new_any(8 as i32, System);
let success = Asc::downcast::<i32>(sc.clone()).unwrap();
assert_eq!(8, *success);
let fail = Asc::downcast::<String>(sc.clone());
assert_eq!(true, fail.is_err());