1 | use alloc::boxed::Box; |
2 | use core::marker::PhantomData; |
3 | use core::ptr::NonNull; |
4 | |
5 | #[repr (transparent)] |
6 | pub struct Own<T> |
7 | where |
8 | T: ?Sized, |
9 | { |
10 | pub ptr: NonNull<T>, |
11 | } |
12 | |
13 | unsafe impl<T> Send for Own<T> where T: ?Sized {} |
14 | |
15 | unsafe impl<T> Sync for Own<T> where T: ?Sized {} |
16 | |
17 | impl<T> Copy for Own<T> where T: ?Sized {} |
18 | |
19 | impl<T> Clone for Own<T> |
20 | where |
21 | T: ?Sized, |
22 | { |
23 | fn clone(&self) -> Self { |
24 | *self |
25 | } |
26 | } |
27 | |
28 | impl<T> Own<T> |
29 | where |
30 | T: ?Sized, |
31 | { |
32 | pub fn new(ptr: Box<T>) -> Self { |
33 | Own { |
34 | ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) }, |
35 | } |
36 | } |
37 | |
38 | pub fn cast<U: CastTo>(self) -> Own<U::Target> { |
39 | Own { |
40 | ptr: self.ptr.cast(), |
41 | } |
42 | } |
43 | |
44 | pub unsafe fn boxed(self) -> Box<T> { |
45 | Box::from_raw(self.ptr.as_ptr()) |
46 | } |
47 | |
48 | pub fn by_ref(&self) -> Ref<T> { |
49 | Ref { |
50 | ptr: self.ptr, |
51 | lifetime: PhantomData, |
52 | } |
53 | } |
54 | |
55 | pub fn by_mut(&mut self) -> Mut<T> { |
56 | Mut { |
57 | ptr: self.ptr, |
58 | lifetime: PhantomData, |
59 | } |
60 | } |
61 | } |
62 | |
63 | #[repr (transparent)] |
64 | pub struct Ref<'a, T> |
65 | where |
66 | T: ?Sized, |
67 | { |
68 | pub ptr: NonNull<T>, |
69 | lifetime: PhantomData<&'a T>, |
70 | } |
71 | |
72 | impl<'a, T> Copy for Ref<'a, T> where T: ?Sized {} |
73 | |
74 | impl<'a, T> Clone for Ref<'a, T> |
75 | where |
76 | T: ?Sized, |
77 | { |
78 | fn clone(&self) -> Self { |
79 | *self |
80 | } |
81 | } |
82 | |
83 | impl<'a, T> Ref<'a, T> |
84 | where |
85 | T: ?Sized, |
86 | { |
87 | pub fn new(ptr: &'a T) -> Self { |
88 | Ref { |
89 | ptr: NonNull::from(ptr), |
90 | lifetime: PhantomData, |
91 | } |
92 | } |
93 | |
94 | #[cfg (not(anyhow_no_ptr_addr_of))] |
95 | pub fn from_raw(ptr: NonNull<T>) -> Self { |
96 | Ref { |
97 | ptr, |
98 | lifetime: PhantomData, |
99 | } |
100 | } |
101 | |
102 | pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> { |
103 | Ref { |
104 | ptr: self.ptr.cast(), |
105 | lifetime: PhantomData, |
106 | } |
107 | } |
108 | |
109 | #[cfg (not(anyhow_no_ptr_addr_of))] |
110 | pub fn by_mut(self) -> Mut<'a, T> { |
111 | Mut { |
112 | ptr: self.ptr, |
113 | lifetime: PhantomData, |
114 | } |
115 | } |
116 | |
117 | #[cfg (not(anyhow_no_ptr_addr_of))] |
118 | pub fn as_ptr(self) -> *const T { |
119 | self.ptr.as_ptr() as *const T |
120 | } |
121 | |
122 | pub unsafe fn deref(self) -> &'a T { |
123 | &*self.ptr.as_ptr() |
124 | } |
125 | } |
126 | |
127 | #[repr (transparent)] |
128 | pub struct Mut<'a, T> |
129 | where |
130 | T: ?Sized, |
131 | { |
132 | pub ptr: NonNull<T>, |
133 | lifetime: PhantomData<&'a mut T>, |
134 | } |
135 | |
136 | impl<'a, T> Copy for Mut<'a, T> where T: ?Sized {} |
137 | |
138 | impl<'a, T> Clone for Mut<'a, T> |
139 | where |
140 | T: ?Sized, |
141 | { |
142 | fn clone(&self) -> Self { |
143 | *self |
144 | } |
145 | } |
146 | |
147 | impl<'a, T> Mut<'a, T> |
148 | where |
149 | T: ?Sized, |
150 | { |
151 | #[cfg (anyhow_no_ptr_addr_of)] |
152 | pub fn new(ptr: &'a mut T) -> Self { |
153 | Mut { |
154 | ptr: NonNull::from(ptr), |
155 | lifetime: PhantomData, |
156 | } |
157 | } |
158 | |
159 | pub fn cast<U: CastTo>(self) -> Mut<'a, U::Target> { |
160 | Mut { |
161 | ptr: self.ptr.cast(), |
162 | lifetime: PhantomData, |
163 | } |
164 | } |
165 | |
166 | #[cfg (not(anyhow_no_ptr_addr_of))] |
167 | pub fn by_ref(self) -> Ref<'a, T> { |
168 | Ref { |
169 | ptr: self.ptr, |
170 | lifetime: PhantomData, |
171 | } |
172 | } |
173 | |
174 | pub fn extend<'b>(self) -> Mut<'b, T> { |
175 | Mut { |
176 | ptr: self.ptr, |
177 | lifetime: PhantomData, |
178 | } |
179 | } |
180 | |
181 | pub unsafe fn deref_mut(self) -> &'a mut T { |
182 | &mut *self.ptr.as_ptr() |
183 | } |
184 | } |
185 | |
186 | impl<'a, T> Mut<'a, T> { |
187 | pub unsafe fn read(self) -> T { |
188 | self.ptr.as_ptr().read() |
189 | } |
190 | } |
191 | |
192 | // Force turbofish on all calls of `.cast::<U>()`. |
193 | pub trait CastTo { |
194 | type Target; |
195 | } |
196 | |
197 | impl<T> CastTo for T { |
198 | type Target = T; |
199 | } |
200 | |