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/// `UniquePointer` is an experimental data structure that makes
11/// extensive use of unsafe rust to provide a shared pointer
12/// throughout the runtime of a rust program as transparently as
13/// possible.
14///
15/// [UniquePointer]'s design's purpose is two-fold:
16///
17/// - Leverage the implementation of circular data structures such as
18/// Lisp cons cells.
19///
20/// - Making easier the task of practicing the implementation of basic
21/// computer science data-structures (e.g.: Binary Trees, Linked Lists
22/// etc) such that the concept of pointer is as close to C as possible
23/// in terms of developer experience and so when a CS teacher speaks
24/// in terms of pointers, students can use [UniquePointer] in their
25/// data-structures knowing that cloning their data-structures also
26/// means cloning the pointers transparently.
27///
28/// In fact, the author designed `UniquePointer` while studying the
29/// MIT CourseWare material of professor Erik Demaine in addition to
30/// studying lisp "cons" cells.
31///
32/// To this point the author reiterates: `UniquePointer` is an
33/// **experimental** data-structure designed primarily as a
34/// building-block of other data-structures in rust.
35///
36/// `UniquePointer` provides the methods [`UniquePointer::cast_mut`]
37/// and [`UniquePointer::cast_const`] not unlike those of raw
38/// pointers, and also implements the methods
39/// [`UniquePointer::as_ref`] and [`UniquePointer::as_mut`] with a
40/// signature compatible with that of the [AsRef] and [AsMut]
41/// traits such that users of raw pointers can migrate to
42/// [UniquePointer] without much difficulty.
43///
44/// `UniquePointer` is designed a way such that Enums and Structs
45/// using `UniquePointer` can safely clone `UniquePointer` while the
46/// memory address and provenance of its value is shared.
47///
48/// [UniquePointer] is able to extend lifetimes because it maintains
49/// its own reference counting outside of the rust compiler.
50///
51/// Reference Counting is provided by [RefCounter] which uses unsafe
52/// rust to ensure that ref counts are shared across cloned objects
53/// memory.
54///
55/// Both [UniquePointer] and [RefCounter] use relatively obscure
56/// rust techniques under the hood to allow writing in non-mut
57/// references in strategic occasions such as incrementing its
58/// reference count within its [Clone] implementation.
59///
60/// UniquePointer only supports [Sized] types, that is, [Zero-Sized
61/// Types](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts)
62/// (ZSTs) are not supported.
63///
64/// Example
65///
66/// ```
67/// use unique_pointer::UniquePointer;
68///
69/// fn create_unique_pointer<'a>() -> UniquePointer<&'a str> {
70/// UniquePointer::from("string")
71/// }
72/// let mut value: UniquePointer<&'_ str> = create_unique_pointer();
73///
74/// assert_eq!(value.is_null(), false);
75///
76/// assert_eq!(value.is_allocated(), true);
77/// assert!(value.addr() > 0, "address should not be null");
78/// assert_eq!(value.is_written(), true);
79/// assert_eq!(value.inner_ref(), &"string");
80///
81/// assert_eq!(value.read(), "string");
82/// assert_eq!(value.as_ref(), Some(&"string"));
83/// ```
84///
85/// # Caveats
86///
87/// - Only supports types that implement [Debug]
88/// - Does not support [ZSTs](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) (Zero-Sized Types)
89/// - [UniquePointer] **IS NOT THREAD SAFE**
90///
91/// # Lisp Cons Cell Example
92///
93/// ```
94/// use std::iter::Extend;
95///
96/// use unique_pointer::{RefCounter, UniquePointer};
97/// # use std::borrow::Cow;
98/// # use std::convert::{AsMut, AsRef};
99/// #
100/// # #[derive(Clone, PartialOrd, Ord, Default, PartialEq, Eq)]
101/// # pub enum Value<'c> {
102/// # #[default]
103/// # Nil,
104/// # String(Cow<'c, str>),
105/// # Byte(u8),
106/// # UInt(u64),
107/// # Int(i64),
108/// # }
109/// # impl<'c> Value<'_> {
110/// # pub fn nil() -> Value<'c> {
111/// # Value::Nil
112/// # }
113/// #
114/// # pub fn is_nil(&self) -> bool {
115/// # if *self == Value::Nil {
116/// # true
117/// # } else {
118/// # false
119/// # }
120/// # }
121/// # }
122/// #
123/// # impl<'c> Drop for Value<'c> {
124/// # fn drop(&mut self) {}
125/// # }
126/// #
127/// # impl std::fmt::Display for Value<'_> {
128/// # fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
129/// # write!(
130/// # f,
131/// # "{}",
132/// # match self {
133/// # Value::Nil => "nil".to_string(),
134/// # Value::String(h) => format!("{}", h),
135/// # Value::Byte(h) => format!("{}", h),
136/// # Value::UInt(h) => format!("{}", h),
137/// # Value::Int(h) => format!("{}", h),
138/// # }
139/// # )
140/// # }
141/// # }
142/// # impl std::fmt::Debug for Value<'_> {
143/// # fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
144/// # write!(
145/// # f,
146/// # "{}",
147/// # match self {
148/// # Value::Nil => "nil".to_string(),
149/// # Value::String(h) => format!("{:#?}", h),
150/// # Value::Byte(h) => format!("{}u8", h),
151/// # Value::UInt(h) => format!("{}u64", h),
152/// # Value::Int(h) => format!("{}i64", h),
153/// # }
154/// # )
155/// # }
156/// # }
157/// #
158/// # impl<'c> From<u8> for Value<'c> {
159/// # fn from(value: u8) -> Value<'c> {
160/// # Value::Byte(value)
161/// # }
162/// # }
163/// # impl<'c> From<u64> for Value<'c> {
164/// # fn from(value: u64) -> Value<'c> {
165/// # Value::UInt(value)
166/// # }
167/// # }
168/// # impl<'c> From<i64> for Value<'c> {
169/// # fn from(value: i64) -> Value<'c> {
170/// # Value::Int(value)
171/// # }
172/// # }
173/// # impl<'c> From<&'c str> for Value<'c> {
174/// # fn from(value: &'c str) -> Value<'c> {
175/// # Value::String(Cow::from(value))
176/// # }
177/// # }
178/// # impl<'c> From<Cow<'c, str>> for Value<'c> {
179/// # fn from(value: Cow<'c, str>) -> Value<'c> {
180/// # Value::from(value.into_owned())
181/// # }
182/// # }
183/// # impl<'c> From<&'c mut str> for Value<'c> {
184/// # fn from(value: &'c mut str) -> Value<'c> {
185/// # Value::String(Cow::<'c, str>::Borrowed(&*value))
186/// # }
187/// # }
188/// # impl<'c> From<String> for Value<'c> {
189/// # fn from(value: String) -> Value<'c> {
190/// # Value::String(Cow::from(value))
191/// # }
192/// # }
193/// # impl<'c> From<Option<String>> for Value<'c> {
194/// # fn from(value: Option<String>) -> Value<'c> {
195/// # match value {
196/// # None => Value::Nil,
197/// # Some(value) => Value::from(value),
198/// # }
199/// # }
200/// # }
201/// #
202/// # impl<'c> AsRef<Value<'c>> for Value<'c> {
203/// # fn as_ref(&self) -> &Value<'c> {
204/// # unsafe { &*self }
205/// # }
206/// # }
207/// # impl<'c> AsMut<Value<'c>> for Value<'c> {
208/// # fn as_mut(&mut self) -> &mut Value<'c> {
209/// # unsafe { &mut *self }
210/// # }
211/// # }
212/// #
213/// # impl<'c> PartialEq<&Value<'c>> for Value<'c> {
214/// # fn eq(&self, other: &&Value<'c>) -> bool {
215/// # let other = unsafe { &**other };
216/// # self == other
217/// # }
218/// # }
219/// #
220/// # impl<'c> PartialEq<&mut Value<'c>> for Value<'c> {
221/// # fn eq(&self, other: &&mut Value<'c>) -> bool {
222/// # let other = unsafe { &**other };
223/// # self == other
224/// # }
225/// # }
226/// #
227///
228/// #[derive(Debug)]
229/// pub struct Cell<'c> {
230/// head: UniquePointer<Value<'c>>,
231/// tail: UniquePointer<Cell<'c>>,
232/// refs: RefCounter,
233/// length: usize,
234/// }
235///
236/// impl<'c> Cell<'c> {
237/// pub fn nil() -> Cell<'c> {
238/// Cell {
239/// head: UniquePointer::<Value<'c>>::null(),
240/// tail: UniquePointer::<Cell<'c>>::null(),
241/// refs: RefCounter::null(),
242/// length: 0,
243/// }
244/// }
245///
246/// pub fn is_nil(&self) -> bool {
247/// self.head.is_null() && self.tail.is_null()
248/// }
249///
250/// pub fn new(value: Value<'c>) -> Cell<'c> {
251/// let mut cell = Cell::nil();
252/// cell.write(value);
253/// cell
254/// }
255///
256/// fn write(&mut self, value: Value<'c>) {
257/// self.head.write(value);
258/// self.refs.write(1);
259/// self.length = 1;
260/// }
261///
262/// fn swap_head(&mut self, other: &mut Self) {
263/// self.head = unsafe {
264/// let head = other.head.propagate();
265/// other.head = self.head.propagate();
266/// head
267/// };
268/// }
269///
270/// fn swap_refs(&mut self, other: &mut Self) {
271/// self.refs = {
272/// let refs = other.refs.clone();
273/// other.refs = self.refs.clone();
274/// refs
275/// };
276/// }
277///
278/// pub fn head(&self) -> Option<Value<'c>> {
279/// self.head.try_read()
280/// }
281///
282/// pub fn add(&mut self, new: &mut Cell<'c>) {
283/// new.incr_ref();
284/// self.incr_ref();
285/// if self.head.is_null() {
286/// unsafe {
287/// if !new.head.is_null() {
288/// self.swap_head(new);
289/// }
290///
291/// if !new.tail.is_null() {
292/// let tail = new.tail.inner_mut();
293/// tail.swap_head(new);
294/// self.swap_refs(new);
295/// }
296/// self.tail = UniquePointer::read_only(new);
297/// }
298/// } else {
299/// if self.tail.is_null() {
300/// self.tail = UniquePointer::read_only(new);
301/// } else {
302/// self.tail.inner_mut().add(new);
303/// }
304/// }
305/// }
306///
307/// pub fn pop(&mut self) -> bool {
308/// if !self.tail.is_null() {
309/// self.tail.drop_in_place();
310/// self.tail = UniquePointer::null();
311/// true
312/// } else if !self.head.is_null() {
313/// self.head.drop_in_place();
314/// self.head = UniquePointer::null();
315/// true
316/// } else {
317/// false
318/// }
319/// }
320///
321/// pub fn is_empty(&self) -> bool {
322/// self.len() > 0
323/// }
324///
325/// pub fn len(&self) -> usize {
326/// let mut len = 0;
327/// if !self.head.is_null() {
328/// len += 1
329/// }
330/// if let Some(tail) = self.tail() {
331/// len += tail.len();
332/// }
333/// len
334/// }
335///
336/// pub fn tail(&self) -> Option<&'c Cell<'c>> {
337/// self.tail.as_ref()
338/// }
339///
340/// pub fn values(&self) -> Vec<Value<'c>> {
341/// let mut values = Vec::<Value>::new();
342/// if let Some(head) = self.head() {
343/// values.push(head.clone());
344/// }
345/// if let Some(tail) = self.tail() {
346/// values.extend(tail.values());
347/// }
348/// values
349/// }
350///
351/// fn incr_ref(&mut self) {
352/// self.refs += 1;
353/// if !self.tail.is_null() {
354/// if let Some(tail) = self.tail.as_mut() {
355/// tail.incr_ref();
356/// }
357/// }
358/// }
359///
360/// fn decr_ref(&mut self) {
361/// self.refs -= 1;
362/// if !self.tail.is_null() {
363/// if let Some(tail) = self.tail.as_mut() {
364/// tail.decr_ref();
365/// }
366/// }
367/// }
368///
369/// fn dealloc(&mut self) {
370/// if self.refs > 0 {
371/// self.decr_ref();
372/// } else {
373/// self.head.drop_in_place();
374/// self.tail.drop_in_place();
375/// }
376/// }
377/// }
378///
379/// impl<'c> From<Value<'c>> for Cell<'c> {
380/// fn from(value: Value<'c>) -> Cell<'c> {
381/// Cell::new(value)
382/// }
383/// }
384/// impl<'c> From<&'c str> for Cell<'c> {
385/// fn from(value: &'c str) -> Cell<'c> {
386/// let value = Value::from(value);
387/// Cell::new(value)
388/// }
389/// }
390/// impl<'c> From<u8> for Cell<'c> {
391/// fn from(value: u8) -> Cell<'c> {
392/// Cell::new(Value::Byte(value))
393/// }
394/// }
395/// impl<'c> From<u64> for Cell<'c> {
396/// fn from(value: u64) -> Cell<'c> {
397/// if value < u8::MAX.into() {
398/// Cell::new(Value::Byte(value as u8))
399/// } else {
400/// Cell::new(Value::UInt(value))
401/// }
402/// }
403/// }
404/// impl<'c> From<i32> for Cell<'c> {
405/// fn from(value: i32) -> Cell<'c> {
406/// if let Ok(value) = TryInto::<u64>::try_into(value) {
407/// Cell::new(Value::UInt(value))
408/// } else {
409/// Cell::new(Value::Int(value.into()))
410/// }
411/// }
412/// }
413/// impl<'c> From<i64> for Cell<'c> {
414/// fn from(value: i64) -> Cell<'c> {
415/// Cell::new(Value::from(value))
416/// }
417/// }
418///
419/// impl<'c> PartialEq<Cell<'c>> for Cell<'c> {
420/// fn eq(&self, other: &Cell<'c>) -> bool {
421/// if self.head.is_null() == other.head.is_null() {
422/// true
423/// } else if let Some(head) = self.head() {
424/// if let Some(value) = other.head() {
425/// return head == value && (self.tail() == other.tail());
426/// } else {
427/// false
428/// }
429/// } else {
430/// false
431/// }
432/// }
433/// }
434///
435/// impl<'c> Default for Cell<'c> {
436/// fn default() -> Cell<'c> {
437/// Cell::nil()
438/// }
439/// }
440/// impl<'c> Clone for Cell<'c> {
441/// fn clone(&self) -> Cell<'c> {
442/// let mut cell = Cell::nil();
443/// cell.refs = self.refs.clone();
444/// if self.head.is_not_null() {
445/// cell.head = self.head.clone();
446/// }
447/// if self.tail.is_not_null() {
448/// cell.tail = self.tail.clone();
449/// }
450/// cell
451/// }
452/// }
453/// impl<'c> Drop for Cell<'c> {
454/// fn drop(&mut self) {
455/// self.dealloc();
456/// }
457/// }
458/// ```
459///
460#[doc(alias = "Pointer")]
461pub struct UniquePointer<T: UniquePointee> {
462 mut_addr: usize,
463 mut_ptr: *mut T,
464 refs: RefCounter,
465 alloc: bool,
466 is_copy: bool,
467 written: bool,
468}
469
470impl<'c, T: UniquePointee + 'c> UniquePointer<T> {
471 /// creates a NULL `UniquePointer` ready to be written via [write].
472 pub fn null() -> UniquePointer<T> {
473 UniquePointer {
474 mut_addr: 0,
475 mut_ptr: std::ptr::null_mut::<T>(),
476 refs: RefCounter::new(),
477 written: false,
478 alloc: false,
479 is_copy: false,
480 }
481 }
482
483 /// creates a new `UniquePointer` by effectively
484 /// reading the value referenced by [src]
485 ///
486 pub fn from_ref(src: &T) -> UniquePointer<T> {
487 let mut up = UniquePointer::<T>::null();
488 up.write_ref(src);
489 up
490 }
491
492 /// `from_ref_mut` creates a new `UniquePointer` by effectively
493 /// reading the value referenced by `src`
494 ///
495 pub fn from_ref_mut(src: &mut T) -> UniquePointer<T> {
496 let mut up = UniquePointer::<T>::null();
497 up.write_ref_mut(src);
498 up
499 }
500
501 /// is designed for use within the [Clone] implementation
502 /// of `UniquePointer`.
503 ///
504 /// The [copy] method creates a NULL `UniquePointer` flagged as
505 /// [`is_copy`] such that a double-free does not happen in
506 /// [dealloc].
507 fn copy() -> UniquePointer<T> {
508 let mut up = UniquePointer::<T>::null();
509 up.is_copy = true;
510 up
511 }
512
513 /// produces a copy of a `UniquePointer` which is not a copy in
514 /// the sense that [`UniquePointer::is_copy`] returns true.
515 ///
516 /// Because of that rationale a double-free occurs if there are
517 /// two or more "containers" (e.g.: [struct]s and [enum]s)
518 /// implementing [Drop] and holding the same propagated
519 /// `UniquePointer` instance. For this reason
520 /// [`UniquePointer::propagate`] is unsafe.
521 ///
522 /// [`UniquePointer::propagate`] can be relatively observed as a
523 /// drop-in replacement to [`UniquePointer::clone`] for cases
524 /// when, for instance, swapping `UniquePointer` "instances"
525 /// between instances of `UniquePointer`-containing (structs
526 /// and/or enums) is desired.
527 ///
528 /// Example
529 ///
530 /// ```
531 /// use unique_pointer::UniquePointer;
532 /// use std::fmt::Debug;
533 /// use std::cmp::PartialEq;
534 ///
535 /// #[derive(Clone, Debug)]
536 /// pub struct BinaryTreeNode<T: Debug> {
537 /// pub item: T,
538 /// pub parent: UniquePointer<BinaryTreeNode<T>>,
539 /// pub left: UniquePointer<BinaryTreeNode<T>>,
540 /// pub right: UniquePointer<BinaryTreeNode<T>>,
541 /// }
542 /// impl<T: Debug> BinaryTreeNode<T> {
543 /// pub fn new(item: T) -> BinaryTreeNode<T> {
544 /// BinaryTreeNode {
545 /// item,
546 /// parent: UniquePointer::null(),
547 /// left: UniquePointer::null(),
548 /// right: UniquePointer::null(),
549 /// }
550 /// }
551 ///
552 /// pub fn rotate_left(&mut self) {
553 /// if self.parent.is_null() {
554 /// if self.right.is_not_null() {
555 /// self.parent = unsafe { self.right.propagate() };
556 /// self.right = UniquePointer::null();
557 /// }
558 /// }
559 /// }
560 ///
561 /// pub fn set_parent(&mut self, parent: &mut BinaryTreeNode<T>) {
562 /// self.parent = UniquePointer::read_only(parent);
563 /// }
564 ///
565 /// pub fn set_left(&mut self, left: &mut BinaryTreeNode<T>) {
566 /// left.set_parent(self);
567 /// self.left = UniquePointer::read_only(left);
568 /// }
569 ///
570 /// pub fn set_right(&mut self, right: &mut BinaryTreeNode<T>) {
571 /// right.set_parent(self);
572 /// self.right = UniquePointer::read_only(right);
573 /// }
574 /// }
575 ///
576 /// let mut node_a = BinaryTreeNode::new("A");
577 /// let mut node_b = BinaryTreeNode::new("B");
578 /// let mut node_c = BinaryTreeNode::new("C");
579 /// node_a.set_left(&mut node_b);
580 /// node_a.set_right(&mut node_c);
581 ///
582 /// ```
583 pub unsafe fn propagate(&self) -> UniquePointer<T> {
584 self.incr_ref();
585 let mut back_node = UniquePointer::<T>::null();
586 back_node.set_mut_ptr(self.mut_ptr, false);
587 back_node.refs = self.refs.clone();
588 back_node.alloc = self.alloc;
589 back_node.written = self.written;
590 back_node
591 }
592
593 /// calls [`UniquePointer::copy_from_ref`] to create a *read-only* `UniquePointer` from a
594 /// reference of `T`, useful for iterating over self-referential
595 /// data structures.
596 ///
597 /// Example:
598 ///
599 /// ```
600 /// use unique_pointer::UniquePointer;
601 ///
602 /// pub struct Data<'r> {
603 /// value: &'r String,
604 /// }
605 /// impl <'r> Data<'r> {
606 /// pub fn new<T: std::fmt::Display>(value: T) -> Data<'r> {
607 /// let value = value.to_string();
608 /// Data {
609 /// value: UniquePointer::read_only(&value).extend_lifetime()
610 /// }
611 /// }
612 /// }
613 /// ```
614 pub fn read_only(data: &T) -> UniquePointer<T> {
615 UniquePointer::copy_from_ref(data, 1)
616 }
617
618 /// calls [`UniquePointer::copy_from_mut_ptr`] to create a *read-only*
619 /// `UniquePointer` from a reference of `T`, useful for
620 /// iterating over self-referential data structures that use
621 /// [RefCounter] to count refs.
622 ///
623 /// Note: [`UniquePointer::read_only`] might be a better alternative when `T` is
624 /// a data structure that does not use [RefCounter].
625 pub fn copy_from_ref(data: &T, refs: usize) -> UniquePointer<T> {
626 let ptr = (data as *const T).cast_mut();
627 UniquePointer::copy_from_mut_ptr(ptr, refs)
628 }
629
630 /// creates a *read-only* `UniquePointer`
631 /// from a reference of `T`, useful for iterating over
632 /// self-referential data structures that use [RefCounter] to
633 /// count refs.
634 ///
635 /// Note: [`UniquePointer::read_only`] might be a better alternative when `T` is
636 /// a data structure that does not use [RefCounter].
637 pub fn copy_from_mut_ptr(ptr: *mut T, refs: usize) -> UniquePointer<T> {
638 let addr = UniquePointer::provenance_of_mut_ptr(ptr);
639 let refs = RefCounter::from(refs);
640 UniquePointer {
641 mut_addr: addr,
642 mut_ptr: ptr,
643 refs: refs,
644 written: true,
645 alloc: true,
646 is_copy: true,
647 }
648 }
649
650 /// returns the value containing both the provenance and
651 /// memory address of a pointer
652 pub fn addr(&self) -> usize {
653 self.mut_addr
654 }
655
656 /// returns the reference count of a `UniquePointer`
657 pub fn refs(&self) -> usize {
658 *self.refs
659 }
660
661 /// returns true if the `UniquePointer` is NULL.
662 pub fn is_null(&self) -> bool {
663 let mut_is_null = self.mut_ptr.is_null();
664 #[cfg(feature="null-check")]
665 if mut_is_null {
666 assert!(self.mut_addr == 0);
667 } else {
668 assert!(self.mut_addr != 0);
669 }
670 let is_null = mut_is_null;
671 is_null
672 }
673
674 /// returns true if the `UniquePointer` is not
675 /// NULL. [`UniquePointer::is_not_null`] is a idiomatic shortcut
676 /// to negating a call to [`UniquePointer::is_null`] such that the
677 /// negation is less likely to be clearly visible.
678 pub fn is_not_null(&self) -> bool {
679 !self.is_null()
680 }
681
682 /// returns true if the `UniquePointer` is not a
683 /// copy. [`UniquePointer::is_not_copy`] is a idiomatic shortcut
684 /// to negating a call to [`UniquePointer::is_copy`] such that the
685 /// negation is less likely to be clearly visible.
686 pub fn is_not_copy(&self) -> bool {
687 !self.is_copy
688 }
689
690 /// returns true if the `UniquePointer` is not NULL
691 /// and is not flagged as a copy, meaning it can be deallocated
692 /// without concern for double-free.
693 pub fn can_dealloc(&self) -> bool {
694 self.alloc && self.is_not_copy() && self.is_not_null()
695 }
696
697 /// returns true if the `UniquePointer` has been
698 /// allocated and therefore is no longer a NULL pointer.
699 pub fn is_allocated(&self) -> bool {
700 let is_allocated = self.is_not_null() && self.alloc;
701 is_allocated
702 }
703
704 /// returns true if the `UniquePointer` has been written to
705 pub fn is_written(&self) -> bool {
706 let is_written = self.is_allocated() && self.written;
707 is_written
708 }
709
710 /// returns true if a `UniquePointer` is a "copy" of
711 /// another `UniquePointer` in the sense that dropping or
712 /// "hard-deallocating" said `UniquePointer` does not incur a
713 /// double-free.
714 pub fn is_copy(&self) -> bool {
715 self.is_copy
716 }
717
718 /// allocates memory in a null `UniquePointer`
719 pub fn alloc(&mut self) {
720 if self.is_allocated() {
721 return;
722 }
723
724 let layout = Layout::new::<T>();
725 let mut_ptr = unsafe {
726 let ptr = std::alloc::alloc_zeroed(layout);
727 if ptr.is_null() {
728 std::alloc::handle_alloc_error(layout);
729 }
730 ptr as *mut T
731 };
732 self.set_mut_ptr(mut_ptr, false);
733 self.alloc = true;
734 }
735
736 /// compatibility API to a raw mut pointer's [`pointer::cast_mut`].
737 pub fn cast_mut(&self) -> *mut T {
738 if self.is_null() {
739 panic!("{:#?}", self);
740 } else {
741 self.mut_ptr
742 }
743 }
744
745 /// compatibility API to a raw const pointer's [`pointer::cast_const`].
746 pub fn cast_const(&self) -> *const T {
747 if self.is_null() {
748 panic!("{:#?}", self);
749 } else {
750 self.mut_ptr.cast_const()
751 }
752 }
753
754 /// allocates memory and writes the given value into the
755 /// newly allocated area.
756 pub fn write(&mut self, data: T) {
757 self.alloc();
758
759 unsafe {
760 self.mut_ptr.write(data);
761 }
762
763 self.written = true;
764 }
765
766 /// takes a mutable reference to a value and
767 /// writes to a `UniquePointer`
768 pub fn write_ref_mut(&mut self, data: &mut T) {
769 self.alloc();
770 unsafe {
771 let ptr = data as *mut T;
772 ptr.copy_to(self.mut_ptr, 1);
773 };
774 self.written = true;
775 }
776
777 /// takes a read-only reference to a value and
778 /// writes to a `UniquePointer`
779 pub fn write_ref(&mut self, data: &T) {
780 self.alloc();
781 unsafe {
782 let ptr = data as *const T;
783 ptr.copy_to(self.mut_ptr, 1);
784 };
785 self.written = true;
786 }
787
788 /// swaps the memory addresses storing `T` with other `UniquePointer`
789 pub fn swap(&mut self, other: &mut Self) {
790 if self.is_null() && other.is_null() {
791 return;
792 }
793 if self.mut_ptr.is_null() {
794 self.alloc();
795 }
796 if other.mut_ptr.is_null() {
797 other.alloc();
798 }
799 unsafe {
800 self.mut_ptr.swap(other.mut_ptr);
801 }
802 }
803
804 /// reads data from memory `UniquePointer`. Panics if
805 /// the pointer is either null or allocated but never written to.
806 pub fn read(&self) -> T {
807 if !self.is_written() {
808 panic!("{:#?} not written", self);
809 }
810 let ptr = self.cast_const();
811 unsafe { ptr.read() }
812 }
813
814 /// reads data from memory `UniquePointer`
815 pub fn try_read(&self) -> Option<T> {
816 if self.is_written() {
817 Some(self.read())
818 } else {
819 None
820 }
821 }
822
823 /// obtains a read-only reference to the value inside
824 /// `UniquePointer` but does not increment references
825 pub fn inner_ref(&self) -> &'c T {
826 if self.mut_ptr.is_null() {
827 panic!("NULL POINTER: {:#?}", self);
828 }
829 unsafe { std::mem::transmute::<&T, &'c T>(&*self.cast_const()) }
830 }
831
832 /// obtains a mutable reference to the value inside
833 /// `UniquePointer` but does not increment references
834 pub fn inner_mut(&mut self) -> &'c mut T {
835 if self.mut_ptr.is_null() {
836 panic!("NULL POINTER: {:#?}", self);
837 }
838 unsafe { std::mem::transmute::<&mut T, &'c mut T>(&mut *self.mut_ptr) }
839 }
840
841 /// compatibility layer to [`std::pointer::as_ref`]
842 pub fn as_ref(&self) -> Option<&'c T> {
843 if self.is_written() {
844 Some(self.inner_ref())
845 } else {
846 None
847 }
848 }
849
850 /// compatibility layer to [`std::pointer::as_mut`]
851 pub fn as_mut(&mut self) -> Option<&'c mut T> {
852 if self.is_written() {
853 Some(self.inner_mut())
854 } else {
855 None
856 }
857 }
858
859 /// deallocates a `UniquePointer`.
860 ///
861 /// The [soft] boolean argument indicates whether the
862 /// `UniquePointer` should have its reference count decremented or
863 /// deallocated immediately.
864 ///
865 /// During "soft" deallocation (`soft=true`) calls to `dealloc`
866 /// only really deallocate memory when the reference gets down to
867 /// zero, until then each `dealloc(true)` call simply decrements
868 /// the reference count.
869 ///
870 /// Conversely during "hard" deallocation (`soft=false`) the
871 /// UniquePointer in question gets immediately deallocated,
872 /// possibly incurring a double-free or causing Undefined
873 /// Behavior.
874 pub fn dealloc(&mut self, soft: bool) {
875 if self.is_null() {
876 return;
877 }
878 if soft && self.refs > 0 {
879 self.decr_ref();
880 } else {
881 self.free();
882 }
883 }
884
885 /// sets the internal raw pointer of a `UniquePointer`.
886 ///
887 /// Prior to setting the new pointer, it checks whether the
888 /// internal pointer is non-null and matches its provenance
889 /// address, such that "copies" do not incur a double-free.
890 ///
891 /// When [ptr] is a NULL pointer and the internal pointer of
892 /// `UniquePointer` in question is NOT NULL, then it is
893 /// deallocated prior to setting it to NULL.
894 fn set_mut_ptr(&mut self, ptr: *mut T, dealloc: bool) {
895 if ptr.is_null() {
896 if dealloc && self.is_allocated() {
897 self.alloc = false;
898 self.written = false;
899 self.mut_addr = 0;
900 let layout = Layout::new::<T>();
901 unsafe {
902 std::alloc::dealloc(self.mut_ptr as *mut u8, layout);
903 };
904 self.mut_ptr = std::ptr::null_mut::<T>();
905 }
906
907 self.set_mut_addr(0);
908 } else {
909 self.set_mut_addr(UniquePointer::<T>::provenance_of_mut_ptr(ptr));
910 }
911 self.mut_ptr = ptr;
912 }
913
914 /// deallocates the memory used by `UniquePointer`
915 /// once its references get down to zero.
916 pub fn drop_in_place(&mut self) {
917 self.dealloc(true);
918 }
919
920 fn set_mut_addr(&mut self, addr: usize) {
921 self.mut_addr = addr;
922 }
923
924 /// is internally used by [dealloc] when the number of
925 /// references gets down to zero in a "soft" deallocation and
926 /// immediately in a "hard" deallocation.
927 ///
928 /// See [dealloc] for more information regarding the difference
929 /// between "soft" and "hard" deallocation.
930 fn free(&mut self) {
931 if !self.can_dealloc() {
932 return;
933 }
934 if !self.is_null() {
935 self.set_mut_ptr(std::ptr::null_mut::<T>(), false);
936 self.refs.drain();
937 }
938 self.alloc = false;
939 self.written = false;
940 }
941
942 /// utility method to extend the lifetime
943 /// of references of data created within a function.
944 ///
945 /// Example
946 ///
947 /// ```
948 /// use unique_pointer::UniquePointer;
949 ///
950 /// pub struct Data<'r> {
951 /// value: &'r String,
952 /// }
953 /// impl <'r> Data<'r> {
954 /// pub fn new<T: std::fmt::Display>(value: T) -> Data<'r> {
955 /// let value = value.to_string();
956 /// Data {
957 /// value: UniquePointer::read_only(&value).extend_lifetime()
958 /// }
959 /// }
960 /// }
961 /// ```
962 pub fn extend_lifetime<'t>(&self) -> &'t T {
963 unsafe { std::mem::transmute::<&T, &'t T>(self.inner_ref()) }
964 }
965
966 /// utility method to extend the lifetime
967 /// of references of data created within a function.
968 ///
969 /// Example
970 ///
971 /// ```
972 /// use unique_pointer::UniquePointer;
973 ///
974 /// pub struct Data<'r> {
975 /// value: &'r mut String,
976 /// }
977 /// impl <'r> Data<'r> {
978 /// pub fn new<T: std::fmt::Display>(value: T) -> Data<'r> {
979 /// let value = value.to_string();
980 /// Data {
981 /// value: UniquePointer::read_only(&value).extend_lifetime_mut()
982 /// }
983 /// }
984 /// }
985 /// ```
986 pub fn extend_lifetime_mut<'t>(&mut self) -> &'t mut T {
987 unsafe { std::mem::transmute::<&mut T, &'t mut T>(self.inner_mut()) }
988 }
989}
990
991impl<T: UniquePointee> UniquePointer<T> {
992 /// helper method that returns the
993 /// address and provenance of a const pointer
994 pub fn provenance_of_const_ptr(ptr: *const T) -> usize {
995 ptr.expose_provenance()
996 }
997
998 /// helper method that returns the
999 /// address and provenance of a mut pointer
1000 pub fn provenance_of_mut_ptr(ptr: *mut T) -> usize {
1001 ptr.expose_provenance()
1002 }
1003
1004 /// helper method that returns the
1005 /// address and provenance of a reference
1006 pub fn provenance_of_ref(ptr: &T) -> usize {
1007 (&raw const ptr).expose_provenance()
1008 }
1009
1010 /// helper method that returns the
1011 /// address and provenance of a mutable reference
1012 pub fn provenance_of_mut(mut ptr: &mut T) -> usize {
1013 (&raw mut ptr).expose_provenance()
1014 }
1015}
1016
1017#[allow(unused)]
1018impl<'c, T: UniquePointee + 'c> UniquePointer<T> {
1019 /// unsafe method that turns a "self reference"
1020 /// into a mutable "self reference"
1021 unsafe fn meta_mut(&'c self) -> &'c mut UniquePointer<T> {
1022 unsafe {
1023 let ptr = self.meta_mut_ptr();
1024 let up = &mut *ptr;
1025 std::mem::transmute::<&mut UniquePointer<T>, &'c mut UniquePointer<T>>(up)
1026 }
1027 }
1028
1029 /// unsafe method that turns a [`*mut UniquePointer`] from a "self reference"
1030 unsafe fn meta_mut_ptr(&self) -> *mut UniquePointer<T> {
1031 let ptr = self as *const UniquePointer<T>;
1032 unsafe {
1033 let ptr: *mut UniquePointer<T> =
1034 std::mem::transmute::<*const UniquePointer<T>, *mut UniquePointer<T>>(ptr);
1035 ptr
1036 }
1037 }
1038}
1039#[allow(invalid_reference_casting)]
1040impl<T: UniquePointee> UniquePointer<T> {
1041 /// `incr_ref` uses unsafe rust to increment references of a
1042 /// non-mut reference to `UniquePointer`
1043 fn incr_ref(&self) {
1044 if self.is_null() {
1045 return;
1046 }
1047 unsafe {
1048 let ptr = self.meta_mut_ptr();
1049 let up = &mut *ptr;
1050 up.refs.incr();
1051 }
1052 }
1053
1054 /// uses unsafe rust to decrement references of a
1055 /// non-mut reference to `UniquePointer`
1056 fn decr_ref(&self) {
1057 if self.refs == 0 {
1058 return;
1059 }
1060 unsafe {
1061 let ptr = self.meta_mut_ptr();
1062 let up = &mut *ptr;
1063 up.refs.decr();
1064 }
1065 }
1066}
1067impl<T: UniquePointee> AsRef<T> for UniquePointer<T> {
1068 fn as_ref(&self) -> &T {
1069 if self.is_null() {
1070 panic!("null pointer: {:#?}", self);
1071 }
1072 self.inner_ref()
1073 }
1074}
1075impl<T: UniquePointee> AsMut<T> for UniquePointer<T> {
1076 fn as_mut(&mut self) -> &mut T {
1077 if self.is_null() {
1078 panic!("null pointer: {:#?}", self);
1079 }
1080 self.inner_mut()
1081 }
1082}
1083
1084impl<T: UniquePointee> Deref for UniquePointer<T> {
1085 type Target = T;
1086
1087 fn deref(&self) -> &T {
1088 self.inner_ref()
1089 }
1090}
1091
1092impl<T: UniquePointee> DerefMut for UniquePointer<T> {
1093 fn deref_mut(&mut self) -> &mut T {
1094 self.inner_mut()
1095 }
1096}
1097
1098impl<T: UniquePointee> Drop for UniquePointer<T>
1099where
1100 T: Debug,
1101{
1102 fn drop(&mut self) {
1103 self.drop_in_place();
1104 }
1105}
1106
1107impl<T: UniquePointee> From<&T> for UniquePointer<T>
1108where
1109 T: Debug,
1110{
1111 fn from(data: &T) -> UniquePointer<T> {
1112 UniquePointer::<T>::from_ref(data)
1113 }
1114}
1115impl<T: UniquePointee> From<&mut T> for UniquePointer<T>
1116where
1117 T: Debug,
1118{
1119 fn from(data: &mut T) -> UniquePointer<T> {
1120 UniquePointer::<T>::from_ref_mut(data)
1121 }
1122}
1123impl<T: UniquePointee> From<T> for UniquePointer<T>
1124where
1125 T: Debug,
1126{
1127 fn from(data: T) -> UniquePointer<T> {
1128 let mut up = UniquePointer::<T>::null();
1129 up.write(data);
1130 up
1131 }
1132}
1133/// The [Clone] implementation of `UniquePointer` is special
1134/// because it flags cloned values as clones such that a double-free
1135/// doesn not occur.
1136impl<T: UniquePointee> Clone for UniquePointer<T>
1137where
1138 T: Debug,
1139{
1140 fn clone(&self) -> UniquePointer<T> {
1141 self.incr_ref();
1142 let mut clone = UniquePointer::<T>::copy();
1143 clone.set_mut_ptr(self.mut_ptr, false);
1144 clone.refs = self.refs.clone();
1145 clone.alloc = self.alloc;
1146 clone.written = self.written;
1147 clone
1148 }
1149}
1150
1151impl<T: UniquePointee> Pointer for UniquePointer<T>
1152where
1153 T: Debug,
1154{
1155 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1156 write!(f, "{:016x}", self.addr())
1157 }
1158}
1159
1160impl<T: UniquePointee> Debug for UniquePointer<T>
1161where
1162 T: Debug,
1163{
1164 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1165 write!(
1166 f,
1167 "UniquePointer{}",
1168 [
1169 format!("{:016x}", self.addr()),
1170 if self.is_not_null() {
1171 [
1172 format!("[src={:#?}]", self.inner_ref()),
1173 format!("[refs={}]", self.refs),
1174 ]
1175 .join("")
1176 } else {
1177 [
1178 format!("[refs={}]", self.refs),
1179 format!("[alloc={}]", self.alloc),
1180 format!("[written={}]", self.written),
1181 ]
1182 .join("")
1183 },
1184 format!("[is_copy={}]", self.is_copy),
1185 ]
1186 .join("")
1187 )
1188 }
1189}
1190
1191impl<T: UniquePointee + PartialEq> PartialEq<UniquePointer<T>> for UniquePointer<T> {
1192 fn eq(&self, fles: &UniquePointer<T>) -> bool {
1193 if self.addr() == fles.addr() {
1194 return true;
1195 }
1196 if self.is_null() {
1197 let eq = fles.is_null();
1198 return eq;
1199 }
1200 self.inner_ref().eq(fles.inner_ref())
1201 }
1202}
1203impl<T: UniquePointee + Eq> Eq for UniquePointer<T> {}
1204impl<T: UniquePointee + PartialOrd> PartialOrd<UniquePointer<T>> for UniquePointer<T> {
1205 fn partial_cmp(&self, other: &UniquePointer<T>) -> Option<Ordering> {
1206 if self.is_null() {
1207 return None;
1208 }
1209 if self.addr() == other.addr() {
1210 return Some(Ordering::Equal);
1211 }
1212 self.inner_ref().partial_cmp(other.inner_ref())
1213 }
1214}
1215
1216impl<T: UniquePointee + PartialOrd> PartialOrd<T> for UniquePointer<T> {
1217 fn partial_cmp(&self, other: &T) -> Option<Ordering> {
1218 if self.is_null() {
1219 return None;
1220 }
1221 self.inner_ref().partial_cmp(other)
1222 }
1223}
1224impl<T: UniquePointee + PartialEq> PartialEq<T> for UniquePointer<T> {
1225 fn eq(&self, other: &T) -> bool {
1226 if self.is_null() {
1227 return false;
1228 }
1229 self.inner_ref().eq(other)
1230 }
1231}
1232
1233impl<T: UniquePointee + Ord> Ord for UniquePointer<T> {
1234 fn cmp(&self, other: &Self) -> Ordering {
1235 if self.is_null() {
1236 return Ordering::Less;
1237 }
1238 self.inner_ref().cmp(other.inner_ref())
1239 }
1240}
1241
1242impl<T: UniquePointee + Hash> Hash for UniquePointer<T> {
1243 fn hash<H: Hasher>(&self, state: &mut H) {
1244 self.inner_ref().hash(state)
1245 }
1246}
1247
1248// impl<T: Deref, S: Deref> PartialEq<&UniquePointer<S>> for UniquePointer<T>
1249// where
1250// T: PartialEq<S::Target> + UniquePointee,
1251// S: UniquePointee,
1252// {
1253// fn eq(&self, other: &&UniquePointer<S>) -> bool {
1254// T::eq(self, other)
1255// }
1256
1257// fn ne(&self, other: &&UniquePointer<S>) -> bool {
1258// T::ne(self, other)
1259// }
1260// }
1261
1262// impl<T: Deref, S: Deref> PartialEq<UniquePointer<S>> for UniquePointer<T>
1263// where
1264// T: PartialEq<S::Target> + UniquePointee,
1265// S: UniquePointee,
1266// {
1267// fn eq(&self, other: &UniquePointer<S>) -> bool {
1268// T::eq(self, other)
1269// }
1270
1271// fn ne(&self, other: &UniquePointer<S>) -> bool {
1272// T::ne(self, other)
1273// }
1274// }
1275
1276// impl<T: Deref<Target: Eq> + Eq + PartialEq<<T as Deref>::Target>> Eq for UniquePointer<T> where
1277// T: UniquePointee
1278// {
1279// }
1280
1281// impl<T: Deref, S: Deref> PartialOrd<UniquePointer<S>> for UniquePointer<T>
1282// where
1283// T: PartialOrd<S::Target> + UniquePointee,
1284// S: UniquePointee,
1285// {
1286// fn partial_cmp(&self, other: &UniquePointer<S>) -> Option<Ordering> {
1287// T::partial_cmp(self, other)
1288// }
1289
1290// fn lt(&self, other: &UniquePointer<S>) -> bool {
1291// T::lt(self, other)
1292// }
1293
1294// fn le(&self, other: &UniquePointer<S>) -> bool {
1295// T::le(self, other)
1296// }
1297
1298// fn gt(&self, other: &UniquePointer<S>) -> bool {
1299// T::gt(self, other)
1300// }
1301
1302// fn ge(&self, other: &UniquePointer<S>) -> bool {
1303// T::ge(self, other)
1304// }
1305// }
1306
1307// impl<T: Deref<Target: Ord> + Ord + PartialOrd<<T as Deref>::Target>> Ord for UniquePointer<T>
1308// where
1309// T: UniquePointee,
1310// {
1311// fn cmp(&self, other: &Self) -> Ordering {
1312// T::cmp(self, other)
1313// }
1314// }
1315
1316// impl<T: Deref<Target: Hash> + Hash> Hash for UniquePointer<T>
1317// where
1318// T: UniquePointee,
1319// {
1320// fn hash<H: Hasher>(&self, state: &mut H) {
1321// T::hash(self, state);
1322// }
1323// }