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// }