1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use std::{marker::PhantomData, ptr::NonNull};

/// An owned pointer
///
/// **NOTE**: Does not deallocate when dropped
pub(crate) struct OwnedPtr<T: ?Sized> {
    ptr: NonNull<T>,
}

impl<T: ?Sized> Copy for OwnedPtr<T> {}

impl<T: ?Sized> Clone for OwnedPtr<T> {
    fn clone(&self) -> Self {
        *self
    }
}

unsafe impl<T> Send for OwnedPtr<T> where T: Send {}
unsafe impl<T> Sync for OwnedPtr<T> where T: Send {}

impl<T> OwnedPtr<T> {
    pub(crate) fn new(value: T) -> Self {
        Self::from_boxed(Box::new(value))
    }

    pub(crate) fn from_boxed(boxed: Box<T>) -> Self {
        // Safety: `Box::into_raw` is guaranteed to be non-null
        Self {
            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
        }
    }

    /// Convert the pointer to another type
    pub(crate) fn cast<U>(self) -> OwnedPtr<U> {
        OwnedPtr {
            ptr: self.ptr.cast(),
        }
    }

    /// Context the pointer into a Box
    ///
    /// # Safety
    ///
    /// Dropping the Box will deallocate a layout of `T` and run the destructor of `T`.
    ///
    /// A cast pointer must therefore be cast back to the original type before calling this method.
    pub(crate) unsafe fn into_box(self) -> Box<T> {
        unsafe { Box::from_raw(self.ptr.as_ptr()) }
    }

    pub(crate) const fn as_ref(&self) -> RefPtr<'_, T> {
        RefPtr {
            ptr: self.ptr,
            _marker: PhantomData,
        }
    }

    pub(crate) fn as_mut(&mut self) -> MutPtr<'_, T> {
        MutPtr {
            ptr: self.ptr,
            _marker: PhantomData,
        }
    }
}

/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
/// in a `fn` pointer.
pub(crate) struct RefPtr<'a, T: ?Sized> {
    pub(crate) ptr: NonNull<T>,
    _marker: PhantomData<&'a T>,
}

/// Safety: RefPtr indicates a shared reference to a value and as such exhibits the same Send +
/// Sync behavior of &'a T
unsafe impl<'a, T: ?Sized> Send for RefPtr<'a, T> where &'a T: Send {}
unsafe impl<'a, T: ?Sized> Sync for RefPtr<'a, T> where &'a T: Sync {}

impl<'a, T: ?Sized> Copy for RefPtr<'a, T> {}
impl<'a, T: ?Sized> Clone for RefPtr<'a, T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<'a, T: ?Sized> RefPtr<'a, T> {
    pub(crate) fn new(ptr: &'a T) -> Self {
        Self {
            ptr: NonNull::from(ptr),
            _marker: PhantomData,
        }
    }

    /// Convert the pointer to another type
    pub(crate) fn cast<U>(self) -> RefPtr<'a, U> {
        RefPtr {
            ptr: self.ptr.cast(),
            _marker: PhantomData,
        }
    }

    /// Returns a shared reference to the owned value
    ///
    /// # Safety
    ///
    /// See: [`NonNull::as_ref`]
    #[inline]
    pub(crate) unsafe fn as_ref(&self) -> &'a T {
        unsafe { self.ptr.as_ref() }
    }
}

/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
/// in a `fn` pointer.
pub(crate) struct MutPtr<'a, T: ?Sized> {
    pub(crate) ptr: NonNull<T>,
    _marker: PhantomData<&'a mut T>,
}

/// Safety: RefPtr indicates an exclusive reference to a value and as such exhibits the same Send +
/// Sync behavior of &'a mut T
unsafe impl<'a, T: ?Sized> Send for MutPtr<'a, T> where &'a mut T: Send {}
unsafe impl<'a, T: ?Sized> Sync for MutPtr<'a, T> where &'a mut T: Sync {}

impl<'a, T: ?Sized> Copy for MutPtr<'a, T> {}
impl<'a, T: ?Sized> Clone for MutPtr<'a, T> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<'a, T: ?Sized> MutPtr<'a, T> {
    /// Convert the pointer to another type
    pub(crate) fn cast<U>(self) -> MutPtr<'a, U> {
        MutPtr {
            ptr: self.ptr.cast(),
            _marker: PhantomData,
        }
    }

    /// Returns a mutable reference to the owned value with the lifetime decoupled from self
    ///
    /// # Safety
    ///
    /// See: [`NonNull::as_mut`]
    #[inline]
    pub(crate) unsafe fn into_mut(mut self) -> &'a mut T {
        unsafe { self.ptr.as_mut() }
    }
}