unique_pointer/
unique_pointer.rs

1use std::alloc::Layout;
2use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
3use std::convert::{AsMut, AsRef};
4use std::fmt::{Debug, Formatter, Pointer};
5use std::hash::{Hash, Hasher};
6use std::ops::{Deref, DerefMut};
7
8use crate::{RefCounter, UniquePointee};
9
10/// experimental data structure that makes extensive use of unsafe
11/// rust to provide a shared pointer throughout the runtime of a rust
12/// program as transparently as possible.
13///
14/// [`UniquePointer`]'s design's purpose is two-fold:
15///
16/// - Leverage the implementation of circular data structures such as
17/// Lisp cons cells.
18///
19/// - Making easier the task of practicing the implementation of basic
20/// computer science data-structures (e.g.: Binary Trees, Linked Lists
21/// etc) such that the concept of pointer is as close to C as possible
22/// in terms of developer experience and so when a CS teacher speaks
23/// in terms of pointers, students can use [`UniquePointer`] in their
24/// data-structures knowing that cloning their data-structures also
25/// means cloning the pointers transparently.
26///
27/// In fact, the author designed `UniquePointer` while studying the
28/// MIT CourseWare material of professor Erik Demaine in addition to
29/// studying lisp "cons" cells.
30///
31/// To this point the author reiterates: `UniquePointer` is an
32/// **experimental** data-structure designed primarily as a
33/// building-block of other data-structures in rust.
34///
35/// `UniquePointer` provides the methods [`UniquePointer::cast_mut`]
36/// and [`UniquePointer::cast_const`] not unlike those of raw
37/// pointers, and also implements the methods
38/// [`UniquePointer::as_ref`] and [`UniquePointer::as_mut`] with a
39/// signature compatible with that of the [`AsRef`] and [`AsMut`]
40/// traits such that users of raw pointers can migrate to
41/// [`UniquePointer`] without much difficulty.
42///
43/// `UniquePointer` is designed a way such that Enums and Structs
44/// using `UniquePointer` can safely clone `UniquePointer` while the
45/// memory address and provenance of its value is shared.
46///
47/// [`UniquePointer`] is able to extend lifetimes because it maintains
48/// its own reference counting outside of the rust compiler.
49///
50/// Reference Counting is provided by [`RefCounter`] which uses unsafe
51/// rust to ensure that ref counts are shared across cloned objects
52/// memory.
53///
54/// Both [`UniquePointer`] and [`RefCounter`] use relatively obscure
55/// rust techniques under the hood to allow writing in non-mut
56/// references in strategic occasions such as incrementing its
57/// reference count within its [`Clone`] implementation.
58///
59/// UniquePointer only supports [`Sized`] types, that is, [Zero-Sized
60/// Types](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts)
61/// (ZSTs) are not supported.
62///
63/// Example
64///
65/// ```
66/// use unique_pointer::UniquePointer;
67///
68/// fn create_unique_pointer<'a>() -> UniquePointer<&'a str> {
69///     UniquePointer::from("string")
70/// }
71/// let mut value: UniquePointer<&'_ str> = create_unique_pointer();
72///
73/// assert_eq!(value.is_null(), false);
74///
75/// assert_eq!(value.is_allocated(), true);
76/// assert!(value.addr() > 0, "address should not be null");
77/// assert_eq!(value.is_written(), true);
78/// assert_eq!(value.inner_ref(), &"string");
79///
80/// assert_eq!(value.read(), "string");
81/// assert_eq!(value.as_ref(), Some(&"string"));
82/// ```
83///
84/// # Caveats of `UniquePointer`:
85///
86/// - Only supports types that implement [`Debug`]
87/// - Does not support [ZSTs](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) (Zero-Sized Types)
88/// - [`UniquePointer`] **IS NOT THREAD SAFE**
89///
90pub struct UniquePointer<T: UniquePointee> {
91    mut_addr: usize,
92    mut_ptr: *mut T,
93    refs: RefCounter,
94    alloc: bool,
95    is_copy: bool,
96    written: bool,
97}
98
99impl<'c, T: UniquePointee + 'c> UniquePointer<T> {
100    /// creates a NULL `UniquePointer` ready to be written via [`write`].
101    pub fn null() -> UniquePointer<T> {
102        UniquePointer {
103            mut_addr: 0,
104            mut_ptr: std::ptr::null_mut::<T>(),
105            refs: RefCounter::new(),
106            written: false,
107            alloc: false,
108            is_copy: false,
109        }
110    }
111
112    /// creates a new `UniquePointer` by effectively
113    /// reading the value referenced by [`src`]
114    ///
115    pub fn from_ref(src: &T) -> UniquePointer<T> {
116        let mut up = UniquePointer::<T>::null();
117        up.write_ref(src);
118        up
119    }
120
121    /// `from_ref_mut` creates a new `UniquePointer` by effectively
122    /// reading the value referenced by `src`
123    ///
124    pub fn from_ref_mut(src: &mut T) -> UniquePointer<T> {
125        let mut up = UniquePointer::<T>::null();
126        up.write_ref_mut(src);
127        up
128    }
129
130    /// is designed for use within the [`Clone`] implementation
131    /// of `UniquePointer`.
132    ///
133    /// The [`copy`] method creates a NULL `UniquePointer` flagged as
134    /// [`is_copy`] such that a double-free does not happen in
135    /// [`dealloc`].
136    fn copy() -> UniquePointer<T> {
137        let mut up = UniquePointer::<T>::null();
138        up.is_copy = true;
139        up
140    }
141
142    /// produces a copy of a `UniquePointer` which is not a copy in
143    /// the sense that [`UniquePointer::is_copy`] returns true.
144    ///
145    /// Because of that rationale a double-free occurs if there are
146    /// two or more "containers" (e.g.: [`struct`]s and [`enum`]s)
147    /// implementing [`Drop`] and holding the same propagated
148    /// `UniquePointer` instance. For this reason
149    /// [`UniquePointer::propagate`] is unsafe.
150    ///
151    /// [`UniquePointer::propagate`] can be relatively observed as a
152    /// drop-in replacement to [`UniquePointer::clone`] for cases
153    /// when, for instance, swapping `UniquePointer` "instances"
154    /// between instances of `UniquePointer`-containing (structs,
155    /// enums and/or unions) is desired.
156    ///
157    /// Example
158    ///
159    /// ```
160    /// use unique_pointer::UniquePointer;
161    /// use std::fmt::Debug;
162    /// use std::cmp::PartialEq;
163    ///
164    /// #[derive(Clone, Debug)]
165    /// pub struct BinaryTreeNode<T: Debug> {
166    ///     pub item: T,
167    ///     pub parent: UniquePointer<BinaryTreeNode<T>>,
168    ///     pub left: UniquePointer<BinaryTreeNode<T>>,
169    ///     pub right: UniquePointer<BinaryTreeNode<T>>,
170    /// }
171    /// impl<T: Debug> BinaryTreeNode<T> {
172    ///     pub fn new(item: T) -> BinaryTreeNode<T> {
173    ///         BinaryTreeNode {
174    ///             item,
175    ///             parent: UniquePointer::null(),
176    ///             left: UniquePointer::null(),
177    ///             right: UniquePointer::null(),
178    ///         }
179    ///     }
180    ///
181    ///     pub fn rotate_left(&mut self) {
182    ///         if self.parent.is_null() {
183    ///             if self.right.is_not_null() {
184    ///                 self.parent = unsafe { self.right.propagate() };
185    ///                 self.right = UniquePointer::null();
186    ///             }
187    ///         }
188    ///     }
189    ///
190    ///     pub fn set_parent(&mut self, parent: &mut BinaryTreeNode<T>) {
191    ///         self.parent = UniquePointer::read_only(parent);
192    ///     }
193    ///
194    ///     pub fn set_left(&mut self, left: &mut BinaryTreeNode<T>) {
195    ///         left.set_parent(self);
196    ///         self.left = UniquePointer::read_only(left);
197    ///     }
198    ///
199    ///     pub fn set_right(&mut self, right: &mut BinaryTreeNode<T>) {
200    ///         right.set_parent(self);
201    ///         self.right = UniquePointer::read_only(right);
202    ///     }
203    /// }
204    ///
205    /// let mut node_a = BinaryTreeNode::new("A");
206    /// let mut node_b = BinaryTreeNode::new("B");
207    /// let mut node_c = BinaryTreeNode::new("C");
208    /// node_a.set_left(&mut node_b);
209    /// node_a.set_right(&mut node_c);
210    ///
211    /// ```
212    pub unsafe fn propagate(&self) -> UniquePointer<T> {
213        self.incr_ref();
214        let mut back_node = UniquePointer::<T>::null();
215        back_node.set_mut_ptr(self.mut_ptr, false);
216        back_node.refs = self.refs.clone();
217        back_node.alloc = self.alloc;
218        back_node.written = self.written;
219        back_node
220    }
221
222    /// calls [`copy_from_ref`] to create a *read-only* `UniquePointer` from a
223    /// reference of `T`, useful for iterating over self-referential
224    /// data structures.
225    ///
226    /// Example:
227    ///
228    /// ```
229
230    /// ```
231    pub fn read_only(data: &T) -> UniquePointer<T> {
232        UniquePointer::copy_from_ref(data, 1)
233    }
234
235    /// calls [`copy_from_mut_ptr`] to create a *read-only*
236    /// `UniquePointer` from a reference of `T`, useful for
237    /// iterating over self-referential data structures that use
238    /// [`RefCounter`] to count refs.
239    ///
240    /// Note: [`read_only`] might be a better alternative when `T` is
241    /// a data structure that does not use [`RefCounter`].
242    pub fn copy_from_ref(data: &T, refs: usize) -> UniquePointer<T> {
243        let ptr = (data as *const T).cast_mut();
244        UniquePointer::copy_from_mut_ptr(ptr, refs)
245    }
246
247    /// creates a *read-only* `UniquePointer`
248    /// from a reference of `T`, useful for iterating over
249    /// self-referential data structures that use [`RefCounter`] to
250    /// count refs.
251    ///
252    /// Note: [`read_only`] might be a better alternative when `T` is
253    /// a data structure that does not use [`RefCounter`].
254    pub fn copy_from_mut_ptr(ptr: *mut T, refs: usize) -> UniquePointer<T> {
255        let addr = UniquePointer::provenance_of_mut_ptr(ptr);
256        let refs = RefCounter::from(refs);
257        UniquePointer {
258            mut_addr: addr,
259            mut_ptr: ptr,
260            refs: refs,
261            written: true,
262            alloc: true,
263            is_copy: true,
264        }
265    }
266
267    /// returns the value containing both the provenance and
268    /// memory address of a pointer
269    pub fn addr(&self) -> usize {
270        self.mut_addr
271    }
272
273    /// returns the reference count of a `UniquePointer`
274    pub fn refs(&self) -> usize {
275        *self.refs
276    }
277
278    /// returns true if the `UniquePointer` is NULL.
279    pub fn is_null(&self) -> bool {
280        let mut_is_null = self.mut_ptr.is_null();
281        if mut_is_null {
282            assert!(self.mut_addr == 0);
283        } else {
284            assert!(self.mut_addr != 0);
285        }
286        let is_null = mut_is_null;
287        is_null
288    }
289
290    /// returns true if the `UniquePointer` is not
291    /// NULL. [`is_not_null`] is a idiomatic shortcut to negating a call
292    /// to [`is_null`] such that the negation is less likely to be
293    /// clearly visible.
294    pub fn is_not_null(&self) -> bool {
295        !self.is_null()
296    }
297
298    /// returns true if the `UniquePointer` is not a
299    /// copy. [`is_not_copy`] is a idiomatic shortcut to negating a call
300    /// to [`is_copy`] such that the negation is less likely to be
301    /// clearly visible.
302    pub fn is_not_copy(&self) -> bool {
303        !self.is_copy
304    }
305
306    /// returns true if the `UniquePointer` is not NULL
307    /// and is not flagged as a copy, meaning it can be deallocated
308    /// without concern for double-free.
309    pub fn can_dealloc(&self) -> bool {
310        self.alloc && self.is_not_copy() && self.is_not_null()
311    }
312
313    /// returns true if the `UniquePointer` has been
314    /// allocated and therefore is no longer a NULL pointer.
315    pub fn is_allocated(&self) -> bool {
316        let is_allocated = self.is_not_null() && self.alloc;
317        is_allocated
318    }
319
320    /// returns true if the `UniquePointer` has been written to
321    pub fn is_written(&self) -> bool {
322        let is_written = self.is_allocated() && self.written;
323        is_written
324    }
325
326    /// returns true if a `UniquePointer` is a "copy" of
327    /// another `UniquePointer` in the sense that dropping or
328    /// "hard-deallocating" said `UniquePointer` does not incur a
329    /// double-free.
330    pub fn is_copy(&self) -> bool {
331        self.is_copy
332    }
333
334    /// allocates memory in a null `UniquePointer`
335    pub fn alloc(&mut self) {
336        if self.is_allocated() {
337            return;
338        }
339
340        let layout = Layout::new::<T>();
341        let mut_ptr = unsafe {
342            let ptr = std::alloc::alloc_zeroed(layout);
343            if ptr.is_null() {
344                std::alloc::handle_alloc_error(layout);
345            }
346            ptr as *mut T
347        };
348        self.set_mut_ptr(mut_ptr, false);
349        self.alloc = true;
350    }
351
352    /// compatibility API to a raw mut pointer's [`pointer::cast_mut`].
353    pub fn cast_mut(&self) -> *mut T {
354        if self.is_null() {
355            panic!("{:#?}", self);
356        } else {
357            self.mut_ptr
358        }
359    }
360
361    /// compatibility API to a raw const pointer's [`pointer::cast_const`].
362    pub fn cast_const(&self) -> *const T {
363        if self.is_null() {
364            panic!("{:#?}", self);
365        } else {
366            self.mut_ptr.cast_const()
367        }
368    }
369
370    /// allocates memory and writes the given value into the
371    /// newly allocated area.
372    pub fn write(&mut self, data: T) {
373        self.alloc();
374
375        unsafe {
376            self.mut_ptr.write(data);
377        }
378
379        self.written = true;
380    }
381
382    /// takes a mutable reference to a value and
383    /// writes to a `UniquePointer`
384    pub fn write_ref_mut(&mut self, data: &mut T) {
385        self.alloc();
386        unsafe {
387            let ptr = data as *mut T;
388            ptr.copy_to(self.mut_ptr, 1);
389        };
390        self.written = true;
391    }
392
393    /// takes a read-only reference to a value and
394    /// writes to a `UniquePointer`
395    pub fn write_ref(&mut self, data: &T) {
396        self.alloc();
397        unsafe {
398            let ptr = data as *const T;
399            ptr.copy_to(self.mut_ptr, 1);
400        };
401        self.written = true;
402    }
403
404    /// swaps the memory addresses storing `T` with other `UniquePointer`
405    pub fn swap(&mut self, other: &mut Self) {
406        if self.is_null() && other.is_null() {
407            return;
408        }
409        if self.mut_ptr.is_null() {
410            self.alloc();
411        }
412        if other.mut_ptr.is_null() {
413            other.alloc();
414        }
415        unsafe {
416            self.mut_ptr.swap(other.mut_ptr);
417        }
418    }
419
420    /// reads data from memory `UniquePointer`. Panics if
421    /// the pointer is either null or allocated but never written to.
422    pub fn read(&self) -> T {
423        if !self.is_written() {
424            panic!("{:#?} not written", self);
425        }
426        let ptr = self.cast_const();
427        unsafe { ptr.read() }
428    }
429
430    /// reads data from memory `UniquePointer`
431    pub fn try_read(&self) -> Option<T> {
432        if self.is_written() {
433            Some(self.read())
434        } else {
435            None
436        }
437    }
438
439    /// obtains a read-only reference to the value inside
440    /// `UniquePointer` but does not increment references
441    pub fn inner_ref(&self) -> &'c T {
442        if self.mut_ptr.is_null() {
443            panic!("NULL POINTER: {:#?}", self);
444        }
445        unsafe { std::mem::transmute::<&T, &'c T>(&*self.cast_const()) }
446    }
447
448    /// obtains a mutable reference to the value inside
449    /// `UniquePointer` but does not increment references
450    pub fn inner_mut(&mut self) -> &'c mut T {
451        if self.mut_ptr.is_null() {
452            panic!("NULL POINTER: {:#?}", self);
453        }
454        unsafe { std::mem::transmute::<&mut T, &'c mut T>(&mut *self.mut_ptr) }
455    }
456
457    /// compatibility layer to [`std::pointer::as_ref`]
458    pub fn as_ref(&self) -> Option<&'c T> {
459        if self.is_written() {
460            Some(self.inner_ref())
461        } else {
462            None
463        }
464    }
465
466    /// compatibility layer to [`std::pointer::as_mut`]
467    pub fn as_mut(&mut self) -> Option<&'c mut T> {
468        if self.is_written() {
469            Some(self.inner_mut())
470        } else {
471            None
472        }
473    }
474
475    /// deallocates a `UniquePointer`.
476    ///
477    /// The [`soft`] boolean argument indicates whether the
478    /// `UniquePointer` should have its reference count decremented or
479    /// deallocated immediately.
480    ///
481    /// During "soft" deallocation (`soft=true`) calls to `dealloc`
482    /// only really deallocate memory when the reference gets down to
483    /// zero, until then each `dealloc(true)` call simply decrements
484    /// the reference count.
485    ///
486    /// Conversely during "hard" deallocation (`soft=false`) the
487    /// UniquePointer in question gets immediately deallocated,
488    /// possibly incurring a double-free or causing Undefined
489    /// Behavior.
490    pub fn dealloc(&mut self, soft: bool) {
491        if self.is_null() {
492            return;
493        }
494        if soft && self.refs > 0 {
495            self.decr_ref();
496        } else {
497            self.free();
498        }
499    }
500
501    /// sets the internal raw pointer of a `UniquePointer`.
502    ///
503    /// Prior to setting the new pointer, it checks whether the
504    /// internal pointer is non-null and matches its provenance
505    /// address, such that "copies" do not incur a double-free.
506    ///
507    /// When [`ptr`] is a NULL pointer and the internal pointer of
508    /// `UniquePointer` in question is NOT NULL, then it is
509    /// deallocated prior to setting it to NULL.
510    fn set_mut_ptr(&mut self, ptr: *mut T, dealloc: bool) {
511        if ptr.is_null() {
512            if dealloc && self.is_allocated() {
513                self.alloc = false;
514                self.written = false;
515                self.mut_addr = 0;
516                let layout = Layout::new::<T>();
517                unsafe {
518                    std::alloc::dealloc(self.mut_ptr as *mut u8, layout);
519                };
520                self.mut_ptr = std::ptr::null_mut::<T>();
521            }
522
523            self.set_mut_addr(0);
524        } else {
525            self.set_mut_addr(UniquePointer::<T>::provenance_of_mut_ptr(ptr));
526        }
527        self.mut_ptr = ptr;
528    }
529
530    /// deallocates the memory used by `UniquePointer`
531    /// once its references get down to zero.
532    pub fn drop_in_place(&mut self) {
533        self.dealloc(true);
534    }
535
536    fn set_mut_addr(&mut self, addr: usize) {
537        self.mut_addr = addr;
538    }
539
540    /// is internally used by [`dealloc`] when the number of
541    /// references gets down to zero in a "soft" deallocation and
542    /// immediately in a "hard" deallocation.
543    ///
544    /// See [`dealloc`] for more information regarding the difference
545    /// between "soft" and "hard" deallocation.
546    fn free(&mut self) {
547        if !self.can_dealloc() {
548            return;
549        }
550        if !self.is_null() {
551            self.set_mut_ptr(std::ptr::null_mut::<T>(), false);
552            self.refs.drain();
553        }
554        self.alloc = false;
555        self.written = false;
556    }
557
558    /// utility method to extend the lifetime
559    /// of references of data created within a function.
560    ///
561    /// Example
562    ///
563    /// ```
564    /// use unique_pointer::UniquePointer;
565    ///
566    /// pub struct Data<'r> {
567    ///     value: &'r String,
568    /// }
569    /// impl <'r> Data<'r> {
570    ///     pub fn new<T: std::fmt::Display>(value: T) -> Data<'r> {
571    ///         let value = value.to_string();
572    ///         Data {
573    ///             value: UniquePointer::read_only(&value).extend_lifetime()
574    ///         }
575    ///     }
576    /// }
577    /// ```
578    pub fn extend_lifetime<'t>(&self) -> &'t T {
579        unsafe { std::mem::transmute::<&T, &'t T>(self.inner_ref()) }
580    }
581
582    /// utility method to extend the lifetime
583    /// of references of data created within a function.
584    ///
585    /// Example
586    ///
587    /// ```
588    /// use unique_pointer::UniquePointer;
589    ///
590    /// pub struct Data<'r> {
591    ///     value: &'r mut String,
592    /// }
593    /// impl <'r> Data<'r> {
594    ///     pub fn new<T: std::fmt::Display>(value: T) -> Data<'r> {
595    ///         let value = value.to_string();
596    ///         Data {
597    ///             value: UniquePointer::read_only(&value).extend_lifetime_mut()
598    ///         }
599    ///     }
600    /// }
601    /// ```
602    pub fn extend_lifetime_mut<'t>(&mut self) -> &'t mut T {
603        unsafe { std::mem::transmute::<&mut T, &'t mut T>(self.inner_mut()) }
604    }
605}
606
607impl<T: UniquePointee> UniquePointer<T> {
608    /// helper method that returns the
609    /// address and provenance of a const pointer
610    pub fn provenance_of_const_ptr(ptr: *const T) -> usize {
611        ptr.expose_provenance()
612    }
613
614    /// helper method that returns the
615    /// address and provenance of a mut pointer
616    pub fn provenance_of_mut_ptr(ptr: *mut T) -> usize {
617        ptr.expose_provenance()
618    }
619
620    /// helper method that returns the
621    /// address and provenance of a reference
622    pub fn provenance_of_ref(ptr: &T) -> usize {
623        (&raw const ptr).expose_provenance()
624    }
625
626    /// helper method that returns the
627    /// address and provenance of a mutable reference
628    pub fn provenance_of_mut(mut ptr: &mut T) -> usize {
629        (&raw mut ptr).expose_provenance()
630    }
631}
632
633#[allow(unused)]
634impl<'c, T: UniquePointee + 'c> UniquePointer<T> {
635    /// unsafe method that turns a "self reference"
636    /// into a mutable "self reference"
637    unsafe fn meta_mut(&'c self) -> &'c mut UniquePointer<T> {
638        unsafe {
639            let ptr = self.meta_mut_ptr();
640            let up = &mut *ptr;
641            std::mem::transmute::<&mut UniquePointer<T>, &'c mut UniquePointer<T>>(up)
642        }
643    }
644
645    /// unsafe method that turns a [`*mut UniquePointer`] from a "self reference"
646    unsafe fn meta_mut_ptr(&self) -> *mut UniquePointer<T> {
647        let ptr = self as *const UniquePointer<T>;
648        unsafe {
649            let ptr: *mut UniquePointer<T> =
650                std::mem::transmute::<*const UniquePointer<T>, *mut UniquePointer<T>>(ptr);
651            ptr
652        }
653    }
654}
655#[allow(invalid_reference_casting)]
656impl<T: UniquePointee> UniquePointer<T> {
657    /// `incr_ref` uses unsafe rust to increment references of a
658    /// non-mut reference to `UniquePointer`
659    fn incr_ref(&self) {
660        if self.is_null() {
661            return;
662        }
663        unsafe {
664            let ptr = self.meta_mut_ptr();
665            let up = &mut *ptr;
666            up.refs.incr();
667        }
668    }
669
670    /// uses unsafe rust to decrement references of a
671    /// non-mut reference to `UniquePointer`
672    fn decr_ref(&self) {
673        if self.refs == 0 {
674            return;
675        }
676        unsafe {
677            let ptr = self.meta_mut_ptr();
678            let up = &mut *ptr;
679            up.refs.decr();
680        }
681    }
682}
683impl<T: UniquePointee> AsRef<T> for UniquePointer<T> {
684    fn as_ref(&self) -> &T {
685        if self.is_null() {
686            panic!("null pointer: {:#?}", self);
687        }
688        self.inner_ref()
689    }
690}
691impl<T: UniquePointee> AsMut<T> for UniquePointer<T> {
692    fn as_mut(&mut self) -> &mut T {
693        if self.is_null() {
694            panic!("null pointer: {:#?}", self);
695        }
696        self.inner_mut()
697    }
698}
699
700impl<T: UniquePointee> Deref for UniquePointer<T> {
701    type Target = T;
702
703    fn deref(&self) -> &T {
704        self.inner_ref()
705    }
706}
707
708impl<T: UniquePointee> DerefMut for UniquePointer<T> {
709    fn deref_mut(&mut self) -> &mut T {
710        self.inner_mut()
711    }
712}
713
714impl<T: UniquePointee> Drop for UniquePointer<T>
715where
716    T: Debug,
717{
718    fn drop(&mut self) {
719        self.drop_in_place();
720    }
721}
722
723impl<T: UniquePointee> From<&T> for UniquePointer<T>
724where
725    T: Debug,
726{
727    fn from(data: &T) -> UniquePointer<T> {
728        UniquePointer::<T>::from_ref(data)
729    }
730}
731impl<T: UniquePointee> From<&mut T> for UniquePointer<T>
732where
733    T: Debug,
734{
735    fn from(data: &mut T) -> UniquePointer<T> {
736        UniquePointer::<T>::from_ref_mut(data)
737    }
738}
739impl<T: UniquePointee> From<T> for UniquePointer<T>
740where
741    T: Debug,
742{
743    fn from(data: T) -> UniquePointer<T> {
744        UniquePointer::from_ref(&data)
745    }
746}
747/// The [`Clone`] implementation of `UniquePointer` is special
748/// because it flags cloned values as clones such that a double-free
749/// doesn not occur.
750impl<T: UniquePointee> Clone for UniquePointer<T>
751where
752    T: Debug,
753{
754    fn clone(&self) -> UniquePointer<T> {
755        self.incr_ref();
756        let mut clone = UniquePointer::<T>::copy();
757        clone.set_mut_ptr(self.mut_ptr, false);
758        clone.refs = self.refs.clone();
759        clone.alloc = self.alloc;
760        clone.written = self.written;
761        clone
762    }
763}
764
765impl<T: UniquePointee> Pointer for UniquePointer<T>
766where
767    T: Debug,
768{
769    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
770        write!(f, "{:016x}", self.addr())
771    }
772}
773
774impl<T: UniquePointee> Debug for UniquePointer<T>
775where
776    T: Debug,
777{
778    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
779        write!(
780            f,
781            "UniquePointer{}",
782            [
783                format!("{:016x}", self.addr()),
784                if self.is_not_null() {
785                    [
786                        format!("[src={:#?}]", self.inner_ref()),
787                        format!("[refs={}]", self.refs),
788                    ]
789                    .join("")
790                } else {
791                    [
792                        format!("[refs={}]", self.refs),
793                        format!("[alloc={}]", self.alloc),
794                        format!("[written={}]", self.written),
795                    ]
796                    .join("")
797                },
798                format!("[is_copy={}]", self.is_copy),
799            ]
800            .join("")
801        )
802    }
803}
804
805impl<T: UniquePointee + PartialEq> PartialEq<UniquePointer<T>> for UniquePointer<T> {
806    fn eq(&self, fles: &UniquePointer<T>) -> bool {
807        if self.addr() == fles.addr() {
808            return true;
809        }
810        if self.is_null() {
811            let eq = fles.is_null();
812            return eq;
813        }
814        self.inner_ref().eq(fles.inner_ref())
815    }
816}
817impl<T: UniquePointee + Eq> Eq for UniquePointer<T> {}
818impl<T: UniquePointee + PartialOrd> PartialOrd<UniquePointer<T>> for UniquePointer<T> {
819    fn partial_cmp(&self, other: &UniquePointer<T>) -> Option<Ordering> {
820        if self.is_null() {
821            return None;
822        }
823        if self.addr() == other.addr() {
824            return Some(Ordering::Equal);
825        }
826        self.inner_ref().partial_cmp(other.inner_ref())
827    }
828}
829
830impl<T: UniquePointee + PartialOrd> PartialOrd<T> for UniquePointer<T> {
831    fn partial_cmp(&self, other: &T) -> Option<Ordering> {
832        if self.is_null() {
833            return None;
834        }
835        self.inner_ref().partial_cmp(other)
836    }
837}
838impl<T: UniquePointee + PartialEq> PartialEq<T> for UniquePointer<T> {
839    fn eq(&self, other: &T) -> bool {
840        if self.is_null() {
841            return false;
842        }
843        self.inner_ref().eq(other)
844    }
845}
846
847impl<T: UniquePointee + Ord> Ord for UniquePointer<T> {
848    fn cmp(&self, other: &Self) -> Ordering {
849        if self.is_null() {
850            return Ordering::Less;
851        }
852        self.inner_ref().cmp(other.inner_ref())
853    }
854}
855
856impl<T: UniquePointee + Hash> Hash for UniquePointer<T> {
857    fn hash<H: Hasher>(&self, state: &mut H) {
858        self.inner_ref().hash(state)
859    }
860}
861
862// impl<T: Deref, S: Deref> PartialEq<&UniquePointer<S>> for UniquePointer<T>
863// where
864//     T: PartialEq<S::Target> + UniquePointee,
865//     S: UniquePointee,
866// {
867//     fn eq(&self, other: &&UniquePointer<S>) -> bool {
868//         T::eq(self, other)
869//     }
870
871//     fn ne(&self, other: &&UniquePointer<S>) -> bool {
872//         T::ne(self, other)
873//     }
874// }
875
876// impl<T: Deref, S: Deref> PartialEq<UniquePointer<S>> for UniquePointer<T>
877// where
878//     T: PartialEq<S::Target> + UniquePointee,
879//     S: UniquePointee,
880// {
881//     fn eq(&self, other: &UniquePointer<S>) -> bool {
882//         T::eq(self, other)
883//     }
884
885//     fn ne(&self, other: &UniquePointer<S>) -> bool {
886//         T::ne(self, other)
887//     }
888// }
889
890// impl<T: Deref<Target: Eq> + Eq + PartialEq<<T as Deref>::Target>> Eq for UniquePointer<T> where
891//     T: UniquePointee
892// {
893// }
894
895// impl<T: Deref, S: Deref> PartialOrd<UniquePointer<S>> for UniquePointer<T>
896// where
897//     T: PartialOrd<S::Target> + UniquePointee,
898//     S: UniquePointee,
899// {
900//     fn partial_cmp(&self, other: &UniquePointer<S>) -> Option<Ordering> {
901//         T::partial_cmp(self, other)
902//     }
903
904//     fn lt(&self, other: &UniquePointer<S>) -> bool {
905//         T::lt(self, other)
906//     }
907
908//     fn le(&self, other: &UniquePointer<S>) -> bool {
909//         T::le(self, other)
910//     }
911
912//     fn gt(&self, other: &UniquePointer<S>) -> bool {
913//         T::gt(self, other)
914//     }
915
916//     fn ge(&self, other: &UniquePointer<S>) -> bool {
917//         T::ge(self, other)
918//     }
919// }
920
921// impl<T: Deref<Target: Ord> + Ord + PartialOrd<<T as Deref>::Target>> Ord for UniquePointer<T>
922// where
923//     T: UniquePointee,
924// {
925//     fn cmp(&self, other: &Self) -> Ordering {
926//         T::cmp(self, other)
927//     }
928// }
929
930// impl<T: Deref<Target: Hash> + Hash> Hash for UniquePointer<T>
931// where
932//     T: UniquePointee,
933// {
934//     fn hash<H: Hasher>(&self, state: &mut H) {
935//         T::hash(self, state);
936//     }
937// }