@@ -185,6 +185,54 @@ pub unsafe trait ErasablePtr {
185185 ///
186186 /// The erased pointer must have been created by `erase`.
187187 unsafe fn unerase ( this : ErasedPtr ) -> Self ;
188+
189+ /// Run a closure on a borrow of the real pointer. Unlike the `Thin<T>` wrapper this does
190+ /// not carry the original type around. Thus it is required to specify the original impl
191+ /// type when calling this function.
192+ ///
193+ /// ```
194+ /// # use {erasable::*, std::rc::Rc};
195+ /// let rc: Rc<i32> = Rc::new(123);
196+ ///
197+ /// let erased: ErasedPtr = ErasablePtr::erase(rc);
198+ ///
199+ /// let cloned = unsafe {
200+ /// <Rc<i32> as ErasablePtr>::with(&erased, |rc| rc.clone())
201+ /// };
202+ ///
203+ /// assert_eq!(*cloned, 123);
204+ /// ```
205+ ///
206+ /// The main purpose of this function is to be able implement recursive types that would
207+ /// be otherwise not representable in rust.
208+ ///
209+ /// # Safety
210+ ///
211+ /// * The erased pointer must have been created by `erase`.
212+ /// * The specified impl type must be the original type.
213+ unsafe fn with < F , T > ( this : & ErasedPtr , f : F ) -> T
214+ where
215+ Self : Sized ,
216+ F : FnOnce ( & Self ) -> T ,
217+ {
218+ f ( & ManuallyDrop :: new ( & Self :: unerase ( * this) ) )
219+ }
220+
221+ /// Run a closure on a mutable borrow of the real pointer. Unlike the `Thin<T>` wrapper
222+ /// this does not carry the original type around. Thus it is required to specify the
223+ /// original impl type when calling this function.
224+ ///
225+ /// # Safety
226+ ///
227+ /// * The erased pointer must have been created by `erase`.
228+ /// * The specified impl type must be the original type.
229+ unsafe fn with_mut < F , T > ( this : & mut ErasedPtr , f : F ) -> T
230+ where
231+ Self : Sized ,
232+ F : FnOnce ( & mut Self ) -> T ,
233+ {
234+ f ( & mut ManuallyDrop :: new ( & mut Self :: unerase ( * this) ) )
235+ }
188236}
189237
190238/// A pointee type that supports type-erased pointers (thin pointers).
0 commit comments