Crate owning_ref [−] [src]
An owning reference.
This crate provides the owning reference type OwningRef
that enables it
to bundle a reference together with the owner of the data it points to.
This allows moving and dropping of a OwningRef
without needing to recreate the reference.
It works by requiring owner types to dereference to stable memory locations and preventing mutable access, which in practice requires an heap allocation as
provided by Box<T>
, Rc<T>
, etc.
Also provided are typedefs for common owner type combinations,
which allows for less verbose type signatures. For example, BoxRef<T>
instead of OwningRef<Box<T>, T>
.
Examples
Caching a reference to a struct field
extern crate owning_ref; use owning_ref::BoxRef; fn main() { struct Foo { tag: u32, x: u16, y: u16, z: u16, } let foo = Foo { tag: 1, x: 100, y: 200, z: 300 }; let or = BoxRef::new(Box::new(foo)).map(|foo| { match foo.tag { 0 => &foo.x, 1 => &foo.y, 2 => &foo.z, _ => panic!(), } }); assert_eq!(*or, 200); }
Caching a reference to an entry in a vector
extern crate owning_ref; use owning_ref::VecRef; fn main() { let v = VecRef::new(vec![1, 2, 3, 4, 5]).map(|v| &v[3]); assert_eq!(*v, 4); }
Caching a subslice of a String
extern crate owning_ref; use owning_ref::StringRef; fn main() { let s = StringRef::new("hello world".to_owned()) .map(|s| s.split(' ').nth(1).unwrap()); assert_eq!(&*s, "world"); }
Reference counted slices that share ownership of the backing storage
extern crate owning_ref; use owning_ref::RcRef; fn main() { let rc: RcRef<[i32]> = RcRef::new(Rc::new([1, 2, 3, 4]) as Rc<[i32]>); assert_eq!(&*rc, &[1, 2, 3, 4]); let rc_a: RcRef<[i32]> = rc.clone().map(|s| &s[0..2]); let rc_b = rc.clone().map(|s| &s[1..3]); let rc_c = rc.clone().map(|s| &s[2..4]); assert_eq!(&*rc_a, &[1, 2]); assert_eq!(&*rc_b, &[2, 3]); assert_eq!(&*rc_c, &[3, 4]); let rc_c_a = rc_c.clone().map(|s| &s[1]); assert_eq!(&*rc_c_a, &4); }
Atomic reference counted slices that share ownership of the backing storage
extern crate owning_ref; use owning_ref::ArcRef; fn main() { use std::thread; fn par_sum(rc: ArcRef<[i32]>) -> i32 { if rc.len() == 0 { return 0; } else if rc.len() == 1 { return rc[0]; } let mid = rc.len() / 2; let left = rc.clone().map(|s| &s[..mid]); let right = rc.map(|s| &s[mid..]); let left = thread::spawn(move || par_sum(left)); let right = thread::spawn(move || par_sum(right)); left.join().unwrap() + right.join().unwrap() } let rc: Arc<[i32]> = Arc::new([1, 2, 3, 4]); let rc: ArcRef<[i32]> = rc.into(); assert_eq!(par_sum(rc), 10); }
Structs
OwningRef |
An owning reference. |
Traits
CloneStableAddress |
Marker trait for expressing that the memory address of the value
reachable via a dereference remains identical even if |
Erased |
Helper trait for an erased concrete type an owner dereferences to. This is used in form of a trait object for keeping something around to (virtually) call the destructor. |
IntoErased |
Helper trait for erasing the concrete type of what an owner derferences to,
for example |
StableAddress |
Marker trait for expressing that the memory address of the value
reachable via a dereference remains identical even if |
Type Definitions
ArcRef |
Typedef of a owning reference that uses a |
BoxRef |
Typedef of a owning reference that uses a |
ErasedBoxRef |
Typedef of a owning reference that uses an erased |
RcRef |
Typedef of a owning reference that uses a |
StringRef |
Typedef of a owning reference that uses a |
VecRef |
Typedef of a owning reference that uses a |