summary refs log tree commit diff stats
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 265cd17..ef8d67d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -560,3 +560,139 @@ impl<'k, T> Holder<'k, T> where T: Opaque {
         })
     }
 }
+
+/// Allows working with holders to `UnsafeCell`.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(generic_associated_types)]
+/// #![feature(pin_macro)]
+///
+/// use core::cell::UnsafeCell;
+/// use core::pin::pin;
+/// 
+/// use selfref::Holder;
+/// use selfref::SelfRef;
+/// use selfref::new_with_closure;
+/// use selfref::opaque;
+/// use selfref::operate_in_closure;
+///
+/// #[derive(Default)]
+/// struct Foo<'a> {
+///     foo: Option<&'a UnsafeCell<Foo<'a>>>,
+/// }
+/// impl<'a> SelfRef<'a> for Foo<'a> {}
+///
+/// struct FooKey;
+/// opaque! {
+///     impl Opaque for FooKey {
+///         type Kind<'a> = UnsafeCell<Foo<'a>>;
+///     }
+/// }
+///
+/// fn main() {
+///     let holder = pin!(Holder::<'_, FooKey>::new_with(
+///         new_with_closure::<FooKey, _>(|foo| UnsafeCell::default())
+///     ));
+///     // Actually making our Foo refer to itself.
+///     holder.as_ref().operate_in(
+///         operate_in_closure::<FooKey, _, _>(|foo| {
+///             unsafe {
+///                 (*foo.get()).foo = Some(foo.get_ref());
+///             }
+///         })
+///     );
+/// }
+/// ```
+impl<'a, T: SelfRef<'a>> SelfRef<'a> for core::cell::UnsafeCell<T> {}
+
+/// Allows working with holders to `Cell`.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(generic_associated_types)]
+/// #![feature(pin_macro)]
+///
+/// use core::cell::Cell;
+/// use core::pin::pin;
+/// 
+/// use selfref::Holder;
+/// use selfref::SelfRef;
+/// use selfref::new_with_closure;
+/// use selfref::opaque;
+/// use selfref::operate_in_closure;
+///
+/// #[derive(Default)]
+/// struct Foo<'a> {
+///     foo: Option<&'a Cell<Foo<'a>>>,
+/// }
+/// impl<'a> SelfRef<'a> for Foo<'a> {}
+///
+/// struct FooKey;
+/// opaque! {
+///     impl Opaque for FooKey {
+///         type Kind<'a> = Cell<Foo<'a>>;
+///     }
+/// }
+///
+/// fn main() {
+///     let holder = pin!(Holder::<'_, FooKey>::new_with(
+///         new_with_closure::<FooKey, _>(|foo| Cell::default())
+///     ));
+///     // Actually making our Foo refer to itself.
+///     holder.as_ref().operate_in(
+///         operate_in_closure::<FooKey, _, _>(|foo| {
+///             foo.set(Foo {
+///                 foo: Some(foo.get_ref())
+///             });
+///         })
+///     );
+/// }
+/// ```
+impl<'a, T: SelfRef<'a>> SelfRef<'a> for core::cell::Cell<T> {}
+
+/// Allows working with holders to `RefCell`.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(generic_associated_types)]
+/// #![feature(pin_macro)]
+///
+/// use core::cell::RefCell;
+/// use core::pin::pin;
+/// 
+/// use selfref::Holder;
+/// use selfref::SelfRef;
+/// use selfref::new_with_closure;
+/// use selfref::opaque;
+/// use selfref::operate_in_closure;
+///
+/// #[derive(Default)]
+/// struct Foo<'a> {
+///     foo: Option<&'a RefCell<Foo<'a>>>,
+/// }
+/// impl<'a> SelfRef<'a> for Foo<'a> {}
+///
+/// struct FooKey;
+/// opaque! {
+///     impl Opaque for FooKey {
+///         type Kind<'a> = RefCell<Foo<'a>>;
+///     }
+/// }
+///
+/// fn main() {
+///     let holder = pin!(Holder::<'_, FooKey>::new_with(
+///         new_with_closure::<FooKey, _>(|foo| RefCell::default())
+///     ));
+///     // Actually making our Foo refer to itself.
+///     holder.as_ref().operate_in(
+///         operate_in_closure::<FooKey, _, _>(|foo| {
+///             foo.borrow_mut().foo = Some(foo.get_ref());
+///         })
+///     );
+/// }
+/// ```
+impl<'a, T: SelfRef<'a>> SelfRef<'a> for core::cell::RefCell<T> {}