Expand description
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 gBox<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 aWeak<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 createRef
andRefMut
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
This is the “Cell” part of the Rc, which can be used separately if you just need a Cell without the reference counting part.
Immutable borrow of an RCell.
Mutable borrow of an RCell.
An Rc reference which has immutable access to the inner value.
An Rc which has mutable access to the inner value. Only one RefMut can exist, and cannot coexist with any Ref.
A strong reference without access to the inner value.
A weak reference without access to the inner value.
Enums
Current state of the Rc.