[−][src]Struct arbalest::sync::Strong
A thread-safe reference-counting pointer.
The type Strong<T>
provides shared ownership of a value of type T
,
allocated in the heap. It behaves mostly like Arc<T>
, except that it
provides a way to mutably borrow the T
that doesn't take into account
any frail references to it. Instead, frail references fail to upgrade
when the Strong<T>
is mutably borrowed.
Thread Safety
Strong<T>
will implement Send
and Sync
as long as the T
implements
Send
and Sync
, just like Arc<T>
.
Breaking cycles with Frail
The downgrade
method can be used to create a non-owning
Frail
pointer. A Frail
pointer can be
upgrade
d to an Strong
, but this will return None
if the
value has already been dropped, or panic if the T
is mutably borrowed
by another Strong
.
A cycle between Strong
pointers will never be deallocated. For this
reason, Frail
is used to break cycles. For example, a tree
could have strong Strong
pointers from parent nodes to children, and
Frail
pointers from children back to their parents.
Cloning references
Creating a new reference from an existing reference-counted pointer is done
using the Clone
trait implemented for Strong<T>
and
Frail<T>
.
use arbalest::sync::Strong; let foo = Strong::new(vec![1.0, 2.0, 3.0]); // The two syntaxes below are equivalent. let a = foo.clone(); let b = Strong::clone(&foo); // a, b, and foo are all Arcs that point to the same memory location.
The Strong::clone(&from)
syntax is the most idiomatic because it
conveys more explicitly the meaning of the code. In the example above, this
syntax makes it easier to see that this code is creating a new reference
rather than copying the whole content of foo
.
Deref
behavior
Strong<T>
automatically dereferences to T
(via the Deref
trait),
so you can call T
's methods on a value of type Strong<T>
. To avoid
name clashes with T
's methods, the methods of Strong<T>
itself are
associated functions, called using function-like syntax:
use arbalest::sync::Strong; let my_Arbalest = Strong::new(()); Strong::downgrade(&my_Arbalest);
Frail<T>
does not auto-dereference to T
, because the value
may currently be mutably borrowed or have already been destroyed.
Methods
impl<T> Strong<T>
[src]
impl<T> Strong<T>
pub fn new(data: T) -> Self | [src] |
pub fn try_unwrap(this: Self) -> Result<T, Self> | [src] |
Returns the contained value, if the Strong
has exactly one strong
reference.
Otherwise, an error is returned with the same value that was passed in.
All existing Frail
references to that value are invalidated if the
operation succeeds.
Examples
use arbalest::sync::Strong; let x = Strong::new(3); assert_eq!(Strong::try_unwrap(x), Ok(3)); let x = Strong::new(4); let y = Strong::clone(&x); assert_eq!(*Strong::try_unwrap(x).unwrap_err(), 4);
impl<T: ?Sized> Strong<T>
[src]
impl<T: ?Sized> Strong<T>
pub fn borrow_mut(this: &mut Self) -> RefMut<T> | [src] |
Mutably borrows the wrapped value.
The borrow lasts until the returned RefMut
exits scope. Frail
references to that Strong
cannot be upgraded while this borrow
is active.
Panics
Panics if the value is currently shared. For a non-panicking variant,
use try_borrow_mut
.
Examples
use arbalest::sync::Strong; let mut c = Strong::new(5); *Strong::borrow_mut(&mut c) = 7; assert_eq!(*c, 7);
An example of panic:
use arbalest::sync::Strong; use std::thread; let mut five = Strong::new(5); let same_five = Strong::clone(&five); let result = thread::spawn(move || { let b = Strong::borrow_mut(&mut five); // this causes a panic }).join(); assert!(result.is_err());
pub fn try_borrow_mut(this: &mut Self) -> Result<RefMut<T>, BorrowMutError> | [src] |
Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
The borrow lasts until the returned RefMut
exits scope. Frail
references to that Strong
cannot be upgraded while this borrow
is active.
This is the non-panicking variant of borrow_mut
.
Examples
use arbalest::sync::Strong; let mut five = Strong::new(5); { let same_five = Strong::clone(&five); assert!(Strong::try_borrow_mut(&mut five).is_err()); } assert!(Strong::try_borrow_mut(&mut five).is_ok());
pub fn into_raw(this: Self) -> *const T | [src] |
Consumes the Strong
, returning the wrapped pointer.
To avoid a memory leak the pointer must be converted back to an
Strong
using Strong::from_raw
.
Examples
use arbalest::sync::Strong; let x = Strong::new(10); let x_ptr = Strong::into_raw(x); assert_eq!(unsafe { *x_ptr }, 10);
pub unsafe fn from_raw(ptr: *const T) -> Self | [src] |
Constructs an Strong
from a raw pointer.
The raw pointer must have been previously returned by a call to a
Strong::into_raw
.
This function is unsafe because improper use may lead to memory problems. For example, a double-free may occur if the function is called twice on the same raw pointer.
Examples
use arbalest::sync::Strong; let x = Strong::new(10); let x_ptr = Strong::into_raw(x); unsafe { // Convert back to an `Arc` to prevent leak. let x = Strong::from_raw(x_ptr); assert_eq!(*x, 10); // Further calls to `Strong::from_raw(x_ptr)` would be memory-unsafe. } // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
pub fn downgrade(this: &Self) -> Frail<T> | [src] |
Creates a new Frail
pointer to this value.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); let frail_five = Strong::downgrade(&five);
pub fn frail_count(this: &Self) -> usize | [src] |
Gets the number of Frail
pointers to this value.
Safety
This method by itself is safe, but using it correctly requires extra care. Another thread can change the frail count at any time, including potentially between calling this method and acting on the result.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); let frail_five = Strong::downgrade(&five); // This assertion is deterministic because we haven't shared // the `Strong` or `Frail` between threads. assert_eq!(1, Strong::frail_count(&five));
pub fn strong_count(this: &Self) -> usize | [src] |
Gets the number of strong (Strong
) pointers to this value.
Safety
This method by itself is safe, but using it correctly requires extra care. Another thread can change the strong count at any time, including potentially between calling this method and acting on the result.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); let also_five = Strong::clone(&five); // This assertion is deterministic because we haven't shared // the `Strong` between threads. assert_eq!(2, Strong::strong_count(&five));
pub fn ptr_eq(this: &Self, other: &Self) -> bool | [src] |
Returns true if the two Strong
s point to the same value (not
just values that compare as equal).
Examples
use arbalest::sync::Strong; let five = Strong::new(5); let same_five = Strong::clone(&five); let other_five = Strong::new(5); assert!(Strong::ptr_eq(&five, &same_five)); assert!(!Strong::ptr_eq(&five, &other_five));
Trait Implementations
impl<T> From<T> for Strong<T>
[src]
impl<T> From<T> for Strong<T>
impl<T: ?Sized + Eq> Eq for Strong<T>
[src]
impl<T: ?Sized + Eq> Eq for Strong<T>
impl<T: ?Sized> Drop for Strong<T>
[src]
impl<T: ?Sized> Drop for Strong<T>
fn drop(&mut self) | [src] |
Drops the Strong
.
This will decrement the strong reference count. If the strong reference
count reaches zero then the only other references (if any) are
Frail
, so we drop
the inner value.
Examples
use arbalest::sync::Strong; struct Foo; impl Drop for Foo { fn drop(&mut self) { println!("dropped!"); } } let foo = Strong::new(Foo); let foo2 = Strong::clone(&foo); drop(foo); // Doesn't print anything drop(foo2); // Prints "dropped!"
impl<T: ?Sized + Sync + Send> Send for Strong<T>
[src]
impl<T: ?Sized + Sync + Send> Send for Strong<T>
impl<T: ?Sized + PartialOrd> PartialOrd<Strong<T>> for Strong<T>
[src]
impl<T: ?Sized + PartialOrd> PartialOrd<Strong<T>> for Strong<T>
fn partial_cmp(&self, other: &Self) -> Option<Ordering> | [src] |
Partial comparison for two Strong
s.
The two are compared by calling partial_cmp()
on their inner values.
Examples
use arbalest::sync::Strong; use std::cmp::Ordering; let five = Strong::new(5); assert_eq!(Some(Ordering::Less), five.partial_cmp(&Strong::new(6)));
fn lt(&self, other: &Self) -> bool | [src] |
Less-than comparison for two Strong
s.
The two are compared by calling <
on their inner values.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five < Strong::new(6));
fn le(&self, other: &Self) -> bool | [src] |
“Less than or equal to” comparison for two Strong
s.
The two are compared by calling <=
on their inner values.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five <= Strong::new(5));
fn gt(&self, other: &Self) -> bool | [src] |
Greater-than comparison for two Strong
s.
The two are compared by calling >
on their inner values.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five > Strong::new(4));
fn ge(&self, other: &Self) -> bool | [src] |
“Greater than or equal to” comparison for two Strong
s.
The two are compared by calling >=
on their inner values.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five >= Strong::new(5));
impl<T: ?Sized + Sync + Send> Sync for Strong<T>
[src]
impl<T: ?Sized + Sync + Send> Sync for Strong<T>
impl<T: Default> Default for Strong<T>
[src]
impl<T: Default> Default for Strong<T>
fn default() -> Self | [src] |
Creates a new Strong<T>
, with the Default
value for T
.
Examples
use arbalest::sync::Strong; let x: Strong<i32> = Default::default(); assert_eq!(*x, 0);
impl<T: ?Sized + PartialEq> PartialEq<Strong<T>> for Strong<T>
[src]
impl<T: ?Sized + PartialEq> PartialEq<Strong<T>> for Strong<T>
fn eq(&self, other: &Self) -> bool | [src] |
Equality for two Strong
s.
Two Strong
s are equal if their inner values are equal.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five == Strong::new(5));
fn ne(&self, other: &Self) -> bool | [src] |
Inequality for two Strong
s.
Two Strong
s are unequal if their inner values are unequal.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); assert!(five != Strong::new(6));
impl<T: ?Sized> AsRef<T> for Strong<T>
[src]
impl<T: ?Sized> AsRef<T> for Strong<T>
impl<T: ?Sized> Clone for Strong<T>
[src]
impl<T: ?Sized> Clone for Strong<T>
fn clone(&self) -> Self | [src] |
Makes a clone of the Strong
pointer.
This creates another pointer to the same inner value, increasing the strong reference count.
Examples
use arbalest::sync::Strong; let five = Strong::new(5); let _ = Strong::clone(&five);
fn clone_from(&mut self, source: &Self) | 1.0.0 [src] |
Performs copy-assignment from source
. Read more
impl<T: ?Sized + Ord> Ord for Strong<T>
[src]
impl<T: ?Sized + Ord> Ord for Strong<T>
fn cmp(&self, other: &Self) -> Ordering | [src] |
Comparison for two Strong
s.
The two are compared by calling cmp()
on their inner values.
Examples
use arbalest::sync::Strong; use std::cmp::Ordering; let five = Strong::new(5); assert_eq!(Ordering::Less, five.cmp(&Strong::new(6)));
fn max(self, other: Self) -> Self | 1.21.0 [src] |
Compares and returns the maximum of two values. Read more
fn min(self, other: Self) -> Self | 1.21.0 [src] |
Compares and returns the minimum of two values. Read more
impl<T: ?Sized + Debug> Debug for Strong<T>
[src]
impl<T: ?Sized + Debug> Debug for Strong<T>
impl<T: ?Sized + Display> Display for Strong<T>
[src]
impl<T: ?Sized + Display> Display for Strong<T>
impl<T: ?Sized> Pointer for Strong<T>
[src]
impl<T: ?Sized> Pointer for Strong<T>
impl<T: ?Sized> Deref for Strong<T>
[src]
impl<T: ?Sized> Deref for Strong<T>
impl<T: ?Sized + Hash> Hash for Strong<T>
[src]
impl<T: ?Sized + Hash> Hash for Strong<T>
fn hash<H: Hasher>(&self, state: &mut H) | [src] |
fn hash_slice<H>(data: &[Self], state: &mut H) where | 1.3.0 [src] |
Feeds a slice of this type into the given [Hasher
]. Read more
impl<T: ?Sized> Borrow<T> for Strong<T>
[src]
impl<T: ?Sized> Borrow<T> for Strong<T>
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Strong<T>
[src]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Strong<T>
Blanket Implementations
impl<T> From for T
[src]
impl<T> From for T
impl<T, U> Into for T where
U: From<T>,
[src]
impl<T, U> Into for T where
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
impl<T> ToOwned for T where
T: Clone,
impl<T> ToString for T where
T: Display + ?Sized,
[src]
impl<T> ToString for T where
T: Display + ?Sized,
impl<T, U> TryFrom for T where
T: From<U>,
[src]
impl<T, U> TryFrom for T where
T: From<U>,
type Error = !
try_from
)The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> | [src] |
impl<T> Borrow for T where
T: ?Sized,
[src]
impl<T> Borrow for T where
T: ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
impl<T> BorrowMut for T where
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T | [src] |
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
try_from
)The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error> | [src] |
impl<T> Any for T where
T: 'static + ?Sized,
[src]
impl<T> Any for T where
T: 'static + ?Sized,
fn get_type_id(&self) -> TypeId | [src] |