[][src]Module reffers::rc

An alternative to Rc<RefCell<T>>, with less memory overhead and poisoning support.

  • Configurable overhead (compared to a fixed 24 or 12 for Rc<RefCell<T>>)

  • E g, 4 bytes gives you max 1024 immutable references, 1024 strong references and 1024 weak references, but this can easily be tweaked with the rc_bit_mask macro.

  • Poisoning support - after a panic with an active mutable reference, trying to get mutable or immutable references will return an error. This can be reverted by calling unpoison().

  • Supports reference counted str and [T]. It's represented as a single pointer (unlike e g Box<str>, which is a fat pointer).

  • Lacks CoerceUnsized optimisation support (because it is still unstable in libstd).

  • Last but not least, just writing .get_ref() is less characters than .upgrade().unwrap().borrow() that you would do with a Weak<RefCell<T>>.

Four structs

  • Strong - A strong reference to the inner value, keeping it from being dropped. To access the inner value, use .get_ref() or .get_refmut() to create Ref and RefMut structs.

  • Ref - A strong reference to the inner value, with immutable access to the inner value.

  • RefMut - A strong reference to the inner value, with mutable access to the inner value. There can only be one RefMut reference; and when Ref references exist, there can be no RefMut references.

  • Weak - A weak reference, the inner value will be dropped when no other types of references exist. This can be helpful w r t breaking up cycles of Strong references. There is no need to "upgrade" a weak reference to a strong reference just to access the inner value - just call .get_ref() or .get_refmut() on the weak reference directly.

Where applicable, there are .get_strong() and .get_weak() functions that create new Strong and Weak references. There are also .try_get_ref(), .try_get_refmut() etc functions that return an error instead of panicking in case the reference is in an incorrect state.

Using only as Rc or only as RefCell

If you want to do this like Rc and never want to mutate the interior, just use Ref like an ordinary rc pointer. Combine with Weak for weak pointers, if you wish.

If you want to use the RefCell part (e g, for the poisoning) but without reference counting, you can use RCell for that.

Example

use reffers::rc::State;
use reffers::rc4::Strong;

// Create a strong reference
let strong = Strong::new(5i32);

// And a weak one
let weak = strong.get_weak();

// Change the inner value
*weak.get_refmut() = 7i32;

// Inspect the change
{
    let r = strong.get_ref();
    assert_eq!(*r, 7i32);

    // We cannot change the value from the other reference
    // now. It is still borrowed...
    assert_eq!(weak.try_get_refmut().unwrap_err(), State::Borrowed);
}

// But now we can.
assert_eq!(strong.state(), State::Available);
*strong.get_refmut() = 9i32;

// Drop the strong reference, this drops the inner value as well
drop(strong);

// We can't access the inner value, it has been dropped.
assert_eq!(weak.try_get_ref().unwrap_err(), State::Dropped);

Structs

RCell

This is the "Cell" part of the Rc, which can be used separately if you just need a Cell without the reference counting part.

RCellRef

Immutable borrow of an RCell.

RCellRefMut

Mutable borrow of an RCell.

Ref

An Rc reference which has immutable access to the inner value.

RefMut

An Rc which has mutable access to the inner value. Only one RefMut can exist, and cannot coexist with any Ref.

Strong

A strong reference without access to the inner value.

Weak

A weak reference without access to the inner value.

Enums

State

Current state of the Rc.

Traits

BitMask

The BitMask trait configures the memory overhead and the number of bits for Ref, Strong and Weak references.

Repr

This is an implementation detail. Please don't mess with it.