[][src]Struct arbalest::sync::Strong

pub struct Strong<T: ?Sized> { /* fields omitted */ }

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 upgraded 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]

pub fn new(data: T) -> Self
[src]

Constructs a new Strong<T>.

Examples

use arbalest::sync::Strong;

let five = Strong::new(5);

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]

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 Strongs 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: ?Sized + Eq> Eq for Strong<T>
[src]

impl<T: ?Sized> Drop for Strong<T>
[src]

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 + PartialOrd> PartialOrd<Strong<T>> for Strong<T>
[src]

fn partial_cmp(&self, other: &Self) -> Option<Ordering>
[src]

Partial comparison for two Strongs.

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 Strongs.

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 Strongs.

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 Strongs.

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 Strongs.

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: Default> Default for Strong<T>
[src]

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]

fn eq(&self, other: &Self) -> bool
[src]

Equality for two Strongs.

Two Strongs 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 Strongs.

Two Strongs 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> Clone for Strong<T>
[src]

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]

fn cmp(&self, other: &Self) -> Ordering
[src]

Comparison for two Strongs.

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 + Display> Display for Strong<T>
[src]

impl<T: ?Sized> Pointer for Strong<T>
[src]

impl<T: ?Sized> Deref for Strong<T>
[src]

type Target = T

The resulting type after dereferencing.

impl<T: ?Sized + Hash> Hash for Strong<T>
[src]

fn hash_slice<H>(data: &[Self], state: &mut H) where
    H: Hasher
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: RefUnwindSafe + ?Sized> UnwindSafe for Strong<T>
[src]

Blanket Implementations

impl<T> From for T
[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom for T where
    T: From<U>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]