pub struct Holder<'k, T> where
T: Opaque + 'k, { /* private fields */ }Expand description
Holds an “opaqueified” T::Kind.
Note the lifetime, 'k. This can be anything, as long as T outlives it.
Examples
#![feature(generic_associated_types)]
use core::cell::Cell;
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;
#[derive(Default)]
struct Foo<'a> {
foo: Cell<Option<&'a Foo<'a>>>,
}
struct FooKey;
opaque! {
impl Opaque for FooKey {
type Kind<'a> = Foo<'a>;
}
}
fn main() {
// We can use a closure here, but we need to give the compiler a hint.
let holder = Holder::<'_, FooKey>::new_with(
new_with_closure::<FooKey, _>(|foo| Foo::default())
);
}Implementations
sourceimpl<'k, T> Holder<'k, T> where
T: Opaque,
impl<'k, T> Holder<'k, T> where
T: Opaque,
sourcepub fn new_with<F>(f: F) -> Self where
F: NewWith<'k, T>,
T::Kind<'k>: Sized,
pub fn new_with<F>(f: F) -> Self where
F: NewWith<'k, T>,
T::Kind<'k>: Sized,
Creates a new holder.
Examples
Simple example:
#![feature(generic_associated_types)]
use core::cell::Cell;
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;
#[derive(Default)]
struct Foo<'a> {
foo: Cell<Option<&'a Foo<'a>>>,
}
struct FooKey;
opaque! {
impl Opaque for FooKey {
type Kind<'a> = Foo<'a>;
}
}
fn main() {
// We can use a closure here, but we need to help the compiler.
let holder = Holder::<'_, FooKey>::new_with(
new_with_closure::<FooKey, _>(|foo| Foo::default())
);
}Lifetime parameters:
#![feature(generic_associated_types)]
use core::cell::Cell;
use core::marker::PhantomData;
use selfref::Holder;
use selfref::NewWith;
use selfref::opaque;
struct Foo<'a, 'b: 'a> {
foo: Cell<Option<&'a Foo<'a, 'b>>>,
t: &'b str,
}
struct FooKey<'b>(PhantomData<&'b str>);
opaque! {
impl['b] Opaque for FooKey<'b> {
type Kind<'a> = Foo<'a, 'b>;
}
}
fn main() {
struct FooBuilder<'b>(&'b str);
impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> {
fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a {
Foo {
foo: Default::default(),
t: self.0,
}
}
}
let stack_array: [u8; 5] = *b"hello";
// a non-'static &str
let stack_str = core::str::from_utf8(&stack_array).unwrap();
let holder = Holder::new_with(FooBuilder(stack_str));
}sourceimpl<'k, T> Holder<'k, T> where
T: Opaque,
impl<'k, T> Holder<'k, T> where
T: Opaque,
sourcepub fn operate_in<'i, F, R>(self: Pin<&'i Self>, f: F) -> R where
F: OperateIn<'k, T, Out = R>,
pub fn operate_in<'i, F, R>(self: Pin<&'i Self>, f: F) -> R where
F: OperateIn<'k, T, Out = R>,
Operates in this (pinned) holder.
This “unwraps” the value in this holder, and binds its lifetime to a new stack frame.
Examples
Simple example:
#![feature(generic_associated_types)]
#![feature(pin_macro)]
use core::cell::Cell;
use core::pin::pin;
use selfref::Holder;
use selfref::new_with_closure;
use selfref::opaque;
use selfref::operate_in_closure;
#[derive(Default)]
struct Foo<'a> {
foo: Cell<Option<&'a Foo<'a>>>,
}
struct FooKey;
opaque! {
impl Opaque for FooKey {
type Kind<'a> = Foo<'a>;
}
}
fn main() {
let holder = pin!(Holder::<'_, FooKey>::new_with(
new_with_closure::<FooKey, _>(|foo| Foo::default())
));
// Actually making our Foo refer to itself.
holder.as_ref().operate_in(
operate_in_closure::<FooKey, _, _>(|foo| {
foo.foo.set(Some(foo.get_ref()));
})
);
}With lifetime parameters:
#![feature(generic_associated_types)]
#![feature(pin_macro)]
use core::cell::Cell;
use core::marker::PhantomData;
use core::pin::Pin;
use core::pin::pin;
use selfref::Holder;
use selfref::NewWith;
use selfref::OperateIn;
use selfref::opaque;
struct Foo<'a, 'b: 'a> {
foo: Cell<Option<&'a Foo<'a, 'b>>>,
t: &'b str,
}
struct FooKey<'b>(PhantomData<&'b str>);
opaque! {
impl['b] Opaque for FooKey<'b> {
type Kind<'a> = Foo<'a, 'b>;
}
}
fn main() {
struct FooBuilder<'b>(&'b str);
impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> {
fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a {
Foo {
foo: Default::default(),
t: self.0,
}
}
}
let stack_array: [u8; 5] = *b"hello";
// a non-'static &str
let stack_str = core::str::from_utf8(&stack_array).unwrap();
let holder = pin!(Holder::new_with(FooBuilder(stack_str)));
// Actually making our Foo refer to itself.
struct SetFooRef;
impl<'k, 'b: 'k> OperateIn<'k, FooKey<'b>> for SetFooRef {
type Out = ();
fn operate_in<'a>(self, foo: Pin<&'a Foo<'a, 'b>>)
where 'k: 'a {
foo.foo.set(Some(foo.get_ref()));
}
}
holder.as_ref().operate_in(SetFooRef);
}Auto Trait Implementations
impl<'k, T> RefUnwindSafe for Holder<'k, T> where
<T as Opaque>::Kind<'k>: RefUnwindSafe,
impl<'k, T> Send for Holder<'k, T> where
<T as Opaque>::Kind<'k>: Send,
impl<'k, T> Sync for Holder<'k, T> where
<T as Opaque>::Kind<'k>: Sync,
impl<'k, T> !Unpin for Holder<'k, T>
impl<'k, T> UnwindSafe for Holder<'k, T> where
<T as Opaque>::Kind<'k>: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more