Crate refbox

Source
Expand description

A Box with weak references.

A RefBox is a smart pointer that owns the data, just like a standard Box. Similarly, a RefBox cannot be cloned cheaply, and when it is dropped, the data it points to is dropped as well. However, a RefBox may have many Weak pointers to the same data. These pointers don’t own the data and are reference counted, comparable to the standard library’s std::rc::Weak. As long as the RefBox is alive, Weak pointers can be used to access the data from multiple places without lifetime parameters.

A RefBox could be seen as a lighter alternative to the standard library’s Rc, std::rc::Weak and RefCell combination, in cases where there is one Rc with many Weak pointers to the same data.

Note: this crate is currently experimental.

§Tradeoffs

A RefBox does not differentiate between strong and weak pointers and immutable and mutable borrows. There is always a single strong pointer, zero, one or many weak pointers, and all borrows are mutable. This means there can only be one borrow active at any given time. In return, RefBox uses less memory, is faster to borrow from, and a Weak does not need to be upgraded to access the data.

§Rc + Refcell vs. RefBox

Rc<RefCell<T>>RefBox<T>
Pointer kindsMany Rc pointers and many Weak pointersOne RefBox pointer and many Weak pointers
ClonableBoth Rc and Weak are cheap to cloneOnly Weak is cheap to clone
Up-/DowngradingRc is downgradable, Weak is upgradableRefBox is downgradable
Data access through strong pointerRefCell::try_borrow_mutRefBox::try_borrow_mut
Data access through weak pointer1. Weak::upgrade
2. RefCell::try_borrow_mut
3. Drop temporary Rc
Weak::try_borrow_mut
Simultaneous borrowsOne mutable OR multiple immutableOne (mutable or immutable)
T::drop happens whenWhen all Rcs are droppedWhen the single RefBox is dropped
Max number of Weak pointersusize::MAXu32::MAX
Heap overhead64-bit: 24 bytes
32-bit: 12 bytes
8 bytes
With cyclic_stable enabled on 64-bit: 24 bytes
With cyclic_stable enabled on 32-bit: 12 bytes
PerformanceCloning is fast, mutating is slowCloning is a tiny bit slower, mutating is much faster

§Examples

use refbox::RefBox;

fn main() {
    // Create a RefBox.
    let ref_box = RefBox::new(100);

    // Create a weak reference.
    let weak = RefBox::downgrade(&ref_box);

    // Access the data.
    let borrow = weak.try_borrow_mut().unwrap();
    assert_eq!(*borrow, 100);
}

§Optional Features

  • cyclic_stable: Enables the RefBox::new_cyclic() method on the stable release channel of Rust. This allows you to create data structures that contain weak references to (parts of) themselves in one go. To make it work, the memory layout of the type T is saved in the heap part of the RefBox. This increases the memory size of the heap part with 2 * usize.
  • cyclic: Enables the RefBox::new_cyclic() method on the nightly release channel without increasing the memory size of the heap part. This allows you to create data structures that contain weak references to (parts of) themselves in one go. Requires the nightly feature layout_for_ptr.

Macros§

coerce
Coerces a RefBox<T> into a RefBox<dyn Trait> on stable Rust.
coerce_weak
Coerces a Weak<T> into a Weak<dyn Trait> on stable Rust.

Structs§

Borrow
A mutable borrow as a RAII-guard of a RefBox or Weak.
RefBox
A smart pointer with many reference-counted weak references.
Weak
A weak reference-counted reference to a RefBox.

Enums§

BorrowError
An error that may occur during borrowing of RefBox or Weak.