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]

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);

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!");

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! ( Use parent() 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);

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!");

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!")