From: Ian Jackson Date: Thu, 14 Nov 2024 23:30:44 +0000 (+0000) Subject: docs and box X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=079119d79b6716c0517ca7b3edcf0fc4e6572cfc;p=manually-boxed docs and box --- diff --git a/src/lib.rs b/src/lib.rs index f13d929..a859008 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,8 +115,8 @@ pub struct Ptr { ptr: NonNull, } -unsafe impl Sync for Ptr {} -unsafe impl Send for Ptr {} +unsafe impl Sync for Ptr {} +unsafe impl Send for Ptr {} /// Singleton, used for compile-time alias checking #[derive(Debug)] // Not Clone or Copy @@ -249,19 +249,14 @@ impl Sealed for &mut T {} //---------- principal API for borrowing etc. ---------- -impl Clone for Ptr { fn clone(&self) -> Self { *self } } -impl Copy for Ptr {} +impl Clone for Ptr { fn clone(&self) -> Self { *self } } +impl Copy for Ptr {} -impl Ptr { - pub fn new_heap(t: T) -> Self { - let b = Box::new(t); - let ptr = Box::into_raw(b); - let ptr = unsafe { - // SAFETY - // Box.into_raw() guarantees it's not null - NonNull::new_unchecked(ptr) - }; - Ptr { ptr } +impl Ptr { + pub fn new_heap(t: T) -> Self + where T: Sized + { + Box::new(t).into() } #[inline] @@ -299,7 +294,9 @@ impl Ptr { /// /// # SAFETY /// - /// `self` must have come from `new_heap`. + /// `self` must have come from `new_heap`, + /// and be the only remaining copy of this `Ptr` + /// (or the only one which will be used). /// /// All copies of `self` will be invalidated. /// @@ -311,7 +308,30 @@ impl Ptr { /// /// (The compiler will check that no borrows are live.) #[inline] - pub unsafe fn free_heap<'a>(self, tok: impl IsMutToken<'a>) -> T { + pub unsafe fn free_heap<'a>(self, tok: impl IsMutToken<'a>) { + let _t: Box = unsafe { self.into_box(tok) }; + } + + /// Frees a `Ptr` that was made with `new_heap` and returns the `T` + /// + /// # SAFETY + /// + /// The same rules as [`free_heap`](Ptr::free_heap) apply. + #[inline] + pub unsafe fn from_heap<'a>(self, tok: impl IsMutToken<'a>) -> T + where T: Sized + { + let t: Box = unsafe { self.into_box(tok) }; + *t + } + + /// Converts a `Ptr` that was made with `new_heap` into a `Box` + /// + /// # SAFETY + /// + /// The same rules as [`free_heap`](Ptr::free_heap) apply. + #[inline] + pub unsafe fn into_box<'a>(self, tok: impl IsMutToken<'a>) -> Box { let _ = tok; let t: Box = unsafe { // SAFETY @@ -324,7 +344,7 @@ impl Ptr { // is going to do this. Box::from_raw(self.ptr.as_ptr()) }; - *t + t } /* @@ -362,16 +382,28 @@ impl NoAliasSingleton { //---------- helpful impls ---------- -pub trait OptionPtrExt { +impl From> for Ptr { + fn from(b: Box) -> Ptr { + let ptr = Box::into_raw(b); + let ptr = unsafe { + // SAFETY + // Box.into_raw() guarantees it's not null + NonNull::new_unchecked(ptr) + }; + Ptr { ptr } + } +} + +pub trait OptionPtrExt { fn as_ptr(self) -> Option<*mut T>; } -impl OptionPtrExt for Option> { +impl OptionPtrExt for Option> { fn as_ptr(self) -> Option<*mut T> { self.map(|p| p.ptr.as_ptr()) } } -impl Debug for Ptr { +impl Debug for Ptr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Ptr").field(&self.ptr).finish() }