Struct crow_util::self_ref::SelfRefHolder
[−]
[src]
pub struct SelfRefHolder<T, U> { /* fields omitted */ }
A struct consisting of both a Holder<T>
and a parent
which can be referenced by the holder.
There are still many problems with the struct, those will be fixed in case they end up being relevant
during the development of the crow_engine
.
To prevent undefined behavior the parent
must not be mutated during the lifetime of this struct!
insert()
uses a raw pointer to parent
to circumvent problems with lifetimes. Do not cast this pointer into a mutable reference
or create a reference which is both lasting longer than the closure and is not the return value of said closure, this is causing undefined behavior!
struct Foo { field: String } impl Foo { fn boo(&self,start: usize) -> Boo { Boo { field: &self.field[start..], } } } struct Boo<'a> { field: &'a str, }
Examples
use crow_util::self_ref; let self_ref_holder = self_ref::SelfRefHolder::new(Foo { field: "Hi, I am Foo!".to_string()}); self_ref_holder.insert("a", |foo| unsafe { &*foo }.boo(4)); assert_eq!(self_ref_holder.get("a").unwrap().field,"I am Foo!");
Methods
impl<T, U> SelfRefHolder<T, U>
[src]
fn new(parent: T) -> Self
Constructs a new SelfRefHolder<T,U>
with an empty Holder<T>
child
.
After this calling this method it is not possible to mutate parent
!
Examples
use crow_util::self_ref; let foo = Foo { field: "Hi, I am Foo!".to_string()}; let self_ref_holder = self_ref::SelfRefHolder::new(foo);
fn get(&self, key: &str) -> Option<&U>
Returns a reference to the element of child
corresponding to the key.
Examples
use crow_util::self_ref; let foo = Foo { field: "Hi, I am Foo!".to_string()}; let self_ref_holder = self_ref::SelfRefHolder::new(foo); self_ref_holder.insert("a", |foo| unsafe { &*foo }.boo(4)); let val = self_ref_holder.get("a").unwrap().field; assert_eq!(val, "I am Foo!");
fn insert<F>(&self, key: &str, element: F) -> Option<&U> where
F: Fn(*const T) -> U,
F: Fn(*const T) -> U,
Inserts an element
accessible by key
, returning a usable reference element
corresponding to this key
.
In case the key
was already present, the old element
is returned and the new one is ignored.
This method does not need SelfRefHolder
to be mutable.
There are 2 limitations to guarantee that this function is safe:
- Never cast
*const T
to&mut T
, always use|p| unsafe {&*p}
! - Never create a reference to
parent
which outlives this closure, when using this function! ( Useparent()
instead)
Examples
use crow_util::self_ref; let foo = Foo { field: "Hi, I am Foo!".to_string()}; let self_ref_holder = self_ref::SelfRefHolder::new(foo); let a = self_ref_holder.insert("a", |foo| unsafe { &*foo }.boo(4)).unwrap(); assert_eq!(a.field, self_ref_holder.insert("a", |foo| unsafe { &*foo }.boo(7)).unwrap().field);
fn parent(&self) -> &T
Returns a immutable reference to the parent
field.
Examples
use crow_util::self_ref; let foo = Foo { field: "Hi, I am Foo!".to_string()}; let self_ref_holder = self_ref::SelfRefHolder::new(foo); assert_eq!(self_ref_holder.parent().field,"Hi, I am Foo!");
fn free(self) -> T
Consumes self
and returns the parent
.
Examples
use crow_util::self_ref; let foo = Foo { field: "Hi, I am Foo!".to_string()}; let self_ref_holder = self_ref::SelfRefHolder::new(foo); self_ref_holder.insert("a", |foo| unsafe { &*foo }.boo(4)).unwrap(); self_ref_holder.insert("b", |foo| unsafe { &*foo }.boo(7)).unwrap(); let foo = self_ref_holder.free(); assert_eq!(foo.field, "Hi, I am Foo!")