/rust/registry/src/index.crates.io-6f17d22bba15001f/wyz-0.5.1/src/comu.rs
Line | Count | Source |
1 | | /*! Trait-level `co`nst/`mu`table tracking. |
2 | | |
3 | | This module provides a system of marker types that can be used to encode write |
4 | | permissions into type parameters rather than duplicate structures. |
5 | | !*/ |
6 | | |
7 | | // This module has no compute logic of its own; it only exists in the |
8 | | // type-system and to forward to the standard library. |
9 | | #![cfg(not(tarpaulin_include))] |
10 | | |
11 | | use core::{ |
12 | | cmp, |
13 | | convert::TryFrom, |
14 | | fmt::{ |
15 | | self, |
16 | | Debug, |
17 | | Display, |
18 | | Formatter, |
19 | | Pointer, |
20 | | }, |
21 | | hash::{ |
22 | | Hash, |
23 | | Hasher, |
24 | | }, |
25 | | ops::Deref, |
26 | | ptr::NonNull, |
27 | | slice, |
28 | | }; |
29 | | |
30 | | use tap::Pipe; |
31 | | |
32 | | /// A basic `const` marker. |
33 | | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] |
34 | | pub struct Const; |
35 | | |
36 | | /// A basic `mut` marker. |
37 | | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] |
38 | | pub struct Mut; |
39 | | |
40 | | /// A frozen wrapper over some other `Mutability` marker. |
41 | | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] |
42 | | pub struct Frozen<Inner> |
43 | | where Inner: Mutability |
44 | | { |
45 | | inner: Inner, |
46 | | } |
47 | | |
48 | | /** Generalized mutability permissions. |
49 | | |
50 | | This trait enables referent structures to be generic over the write permissions |
51 | | of their referent data. As an example, the standard library defines `*const T` |
52 | | and `*mut T` as two duplicate type families, that cannot share any logic at all. |
53 | | |
54 | | An equivalent library implementation might be `Ptr<T, M: Mutability>`, where |
55 | | shared logic can be placed in an `impl<T, M> Ptr<T, M>` block, but unique logic |
56 | | (such as freezing a `Mut` pointer, or unfreezing a `Frozen<Mut>`) can be placed |
57 | | in specialized `impl<T> Ptr<T, Mut>` blocks. |
58 | | **/ |
59 | | pub trait Mutability: 'static + Copy + Sized + self::seal::Sealed { |
60 | | /// Marks whether this type contains mutability permissions within it. |
61 | | /// |
62 | | /// This is `false` for `Const` and `true` for `Mut`. `Frozen` wrappers |
63 | | /// atop either of these types inherit their interior marker. |
64 | | const CONTAINS_MUTABILITY: bool = false; |
65 | | |
66 | | /// Counts the layers of `Frozen<>` wrapping around a base `Const` or `Mut`. |
67 | | const PEANO_NUMBER: usize = 0; |
68 | | |
69 | | /// Allow instances to be constructed generically. |
70 | | const SELF: Self; |
71 | | |
72 | | /// One of `*const` or `*mut`. |
73 | | const RENDER: &'static str; |
74 | | |
75 | | /// Freeze this type, wrapping it in a `const` marker that may later be |
76 | | /// removed to thaw it. |
77 | 18.7k | fn freeze(self) -> Frozen<Self> { |
78 | 18.7k | Frozen { inner: self } |
79 | 18.7k | } |
80 | | |
81 | | /// Thaw a previously-frozen type, removing its `Frozen` marker and |
82 | | /// restoring it to `Self`. |
83 | | fn thaw(Frozen { inner }: Frozen<Self>) -> Self { |
84 | | inner |
85 | | } |
86 | | } |
87 | | |
88 | | impl Mutability for Const { |
89 | | const RENDER: &'static str = "*const"; |
90 | | const SELF: Self = Self; |
91 | | } |
92 | | |
93 | | impl self::seal::Sealed for Const { |
94 | | } |
95 | | |
96 | | impl<Inner> Mutability for Frozen<Inner> |
97 | | where Inner: Mutability + Sized |
98 | | { |
99 | | const CONTAINS_MUTABILITY: bool = Inner::CONTAINS_MUTABILITY; |
100 | | const PEANO_NUMBER: usize = 1 + Inner::PEANO_NUMBER; |
101 | | const RENDER: &'static str = Inner::RENDER; |
102 | | const SELF: Self = Self { inner: Inner::SELF }; |
103 | | } |
104 | | |
105 | | impl<Inner> self::seal::Sealed for Frozen<Inner> where Inner: Mutability + Sized |
106 | | { |
107 | | } |
108 | | |
109 | | impl Mutability for Mut { |
110 | | const CONTAINS_MUTABILITY: bool = true; |
111 | | const RENDER: &'static str = "*mut"; |
112 | | const SELF: Self = Self; |
113 | | } |
114 | | |
115 | | impl self::seal::Sealed for Mut { |
116 | | } |
117 | | |
118 | | /** A generic non-null pointer with type-system mutability tracking. |
119 | | |
120 | | # Type Parameters |
121 | | |
122 | | - `M`: The mutability permissions of the source pointer. |
123 | | - `T`: The referent type of the source pointer. |
124 | | **/ |
125 | | pub struct Address<M, T> |
126 | | where |
127 | | M: Mutability, |
128 | | T: ?Sized, |
129 | | { |
130 | | /// The address value. |
131 | | inner: NonNull<T>, |
132 | | /// The mutability permissions. |
133 | | comu: M, |
134 | | } |
135 | | |
136 | | impl<M, T> Address<M, T> |
137 | | where M: Mutability |
138 | | { |
139 | | /// The dangling pointer. |
140 | | pub const DANGLING: Self = Self { |
141 | | inner: NonNull::dangling(), |
142 | | comu: M::SELF, |
143 | | }; |
144 | | } |
145 | | |
146 | | impl<M, T> Address<M, T> |
147 | | where |
148 | | M: Mutability, |
149 | | T: ?Sized, |
150 | | { |
151 | | /// Constructs a new `Address` over some pointer value. |
152 | | /// |
153 | | /// You are responsible for selecting the correct `Mutability` marker. |
154 | | #[inline(always)] |
155 | 1.20M | pub fn new(addr: NonNull<T>) -> Self { |
156 | 1.20M | Self { |
157 | 1.20M | inner: addr, |
158 | 1.20M | comu: M::SELF, |
159 | 1.20M | } |
160 | 1.20M | } <wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, core::cell::Cell<u8>>>::new Line | Count | Source | 155 | 18.7k | pub fn new(addr: NonNull<T>) -> Self { | 156 | 18.7k | Self { | 157 | 18.7k | inner: addr, | 158 | 18.7k | comu: M::SELF, | 159 | 18.7k | } | 160 | 18.7k | } |
<wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::new Line | Count | Source | 155 | 105k | pub fn new(addr: NonNull<T>) -> Self { | 156 | 105k | Self { | 157 | 105k | inner: addr, | 158 | 105k | comu: M::SELF, | 159 | 105k | } | 160 | 105k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::new Line | Count | Source | 155 | 512k | pub fn new(addr: NonNull<T>) -> Self { | 156 | 512k | Self { | 157 | 512k | inner: addr, | 158 | 512k | comu: M::SELF, | 159 | 512k | } | 160 | 512k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::new Line | Count | Source | 155 | 569k | pub fn new(addr: NonNull<T>) -> Self { | 156 | 569k | Self { | 157 | 569k | inner: addr, | 158 | 569k | comu: M::SELF, | 159 | 569k | } | 160 | 569k | } |
|
161 | | |
162 | | /// Permanently converts an `Address<_>` into an `Address<Const>`. |
163 | | /// |
164 | | /// You should generally prefer [`Address::freeze`]. |
165 | | #[inline(always)] |
166 | 16.7k | pub fn immut(self) -> Address<Const, T> { |
167 | 16.7k | Address { |
168 | 16.7k | inner: self.inner, |
169 | 16.7k | comu: Const, |
170 | 16.7k | } |
171 | 16.7k | } |
172 | | |
173 | | /// Force an `Address<Const>` to be `Address<Mut>`. |
174 | | /// |
175 | | /// ## Safety |
176 | | /// |
177 | | /// You should only call this on addresses you know to have been created |
178 | | /// with `Mut`able permissions and previously removed by [`Address::immut`]. |
179 | | /// |
180 | | /// You should prefer using [`Address::freeze`] for temporary, trackable, |
181 | | /// immutability constraints instead. |
182 | | #[inline(always)] |
183 | | pub unsafe fn assert_mut(self) -> Address<Mut, T> { |
184 | | Address { |
185 | | inner: self.inner, |
186 | | comu: Mut, |
187 | | } |
188 | | } |
189 | | |
190 | | /// Freezes the `Address` so that it is read-only. |
191 | | #[inline(always)] |
192 | 18.7k | pub fn freeze(self) -> Address<Frozen<M>, T> { |
193 | 18.7k | let Self { inner, comu } = self; |
194 | 18.7k | Address { |
195 | 18.7k | inner, |
196 | 18.7k | comu: comu.freeze(), |
197 | 18.7k | } |
198 | 18.7k | } |
199 | | |
200 | | /// Removes the `Address` type marker, returning the original pointer. |
201 | | #[inline(always)] |
202 | | pub fn into_inner(self) -> NonNull<T> { |
203 | | self.inner |
204 | | } |
205 | | |
206 | | /// Gets the address as a read-only pointer. |
207 | | #[inline(always)] |
208 | 742k | pub fn to_const(self) -> *const T { |
209 | 742k | self.inner.as_ptr() as *const T |
210 | 742k | } <wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::to_const Line | Count | Source | 208 | 105k | pub fn to_const(self) -> *const T { | 209 | 105k | self.inner.as_ptr() as *const T | 210 | 105k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::to_const Line | Count | Source | 208 | 207k | pub fn to_const(self) -> *const T { | 209 | 207k | self.inner.as_ptr() as *const T | 210 | 207k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::to_const Line | Count | Source | 208 | 410k | pub fn to_const(self) -> *const T { | 209 | 410k | self.inner.as_ptr() as *const T | 210 | 410k | } |
<wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, core::cell::Cell<u8>>>::to_const Line | Count | Source | 208 | 18.7k | pub fn to_const(self) -> *const T { | 209 | 18.7k | self.inner.as_ptr() as *const T | 210 | 18.7k | } |
|
211 | | } |
212 | | |
213 | | impl<T> Address<Mut, T> { |
214 | | /// Gets the address as a write-capable pointer. |
215 | | #[inline(always)] |
216 | | #[allow(clippy::wrong_self_convention)] |
217 | 115k | pub fn to_mut(self) -> *mut T { |
218 | 115k | self.inner.as_ptr() |
219 | 115k | } |
220 | | } |
221 | | |
222 | | impl<M, T> Address<Frozen<M>, T> |
223 | | where |
224 | | M: Mutability, |
225 | | T: ?Sized, |
226 | | { |
227 | | /// Thaws the `Address` to its original mutability permission. |
228 | | #[inline(always)] |
229 | | pub fn thaw(self) -> Address<M, T> { |
230 | | let Self { inner, comu } = self; |
231 | | Address { |
232 | | inner, |
233 | | comu: Mutability::thaw(comu), |
234 | | } |
235 | | } |
236 | | } |
237 | | |
238 | | /// Implement `*T -> *T` functions as `Address<T> -> Address<T>`. |
239 | | macro_rules! fwd { |
240 | | ($( |
241 | | $(@$unsafe:ident)? |
242 | | $name:ident |
243 | | $(< |
244 | | $($lt:lifetime),* |
245 | | $($typaram:ident$(: $($bound:ident),+ $(,)?)?),* |
246 | | $(,)* |
247 | | >)? |
248 | | $(, $arg:ident: $ty:ty)* |
249 | | $(=> $ret:ty)? |
250 | | );+ $(;)?) => { $( |
251 | | #[doc = concat!("Applies `<*T>::", stringify!($name), "`.")] |
252 | | /// |
253 | | /// See [original documentation][orig]. |
254 | | /// |
255 | | #[doc = concat!("[orig]: https://doc.rust-lang.org/std/primitive.pointer.html#method.", stringify!($name))] |
256 | 637k | pub $($unsafe)? fn $name$(< |
257 | 637k | $($lt,)* $($typaram$(: $($bound),+)?,)* |
258 | 637k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { |
259 | 637k | self.with_ptr(|ptr| ptr.$name($($arg),*)) <wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, u8>>::cast::<core::cell::Cell<u8>>::{closure#0} Line | Count | Source | 259 | 18.7k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
<wyz::comu::Address<wyz::comu::Mut, u8>>::cast::<u8>::{closure#0} Line | Count | Source | 259 | 115k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
<wyz::comu::Address<wyz::comu::Const, u8>>::cast::<u8>::{closure#0} Line | Count | Source | 259 | 91.4k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
<wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::offset::{closure#0} Line | Count | Source | 259 | 52.6k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Mut, u8>>::wrapping_offset::{closure#0} <wyz::comu::Address<wyz::comu::Mut, u8>>::add::{closure#0} Line | Count | Source | 259 | 97.2k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
<wyz::comu::Address<wyz::comu::Mut, u8>>::offset::{closure#0} Line | Count | Source | 259 | 56.1k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Const, u8>>::wrapping_offset::{closure#0} <wyz::comu::Address<wyz::comu::Const, u8>>::add::{closure#0} Line | Count | Source | 259 | 86.5k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
<wyz::comu::Address<wyz::comu::Const, u8>>::offset::{closure#0} Line | Count | Source | 259 | 119k | self.with_ptr(|ptr| ptr.$name($($arg),*)) |
|
260 | 637k | } <wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, u8>>::cast::<core::cell::Cell<u8>> Line | Count | Source | 256 | 18.7k | pub $($unsafe)? fn $name$(< | 257 | 18.7k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 18.7k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 18.7k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 18.7k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::cast::<u8> Line | Count | Source | 256 | 115k | pub $($unsafe)? fn $name$(< | 257 | 115k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 115k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 115k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 115k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::cast::<u8> Line | Count | Source | 256 | 91.4k | pub $($unsafe)? fn $name$(< | 257 | 91.4k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 91.4k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 91.4k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 91.4k | } |
<wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::offset Line | Count | Source | 256 | 52.6k | pub $($unsafe)? fn $name$(< | 257 | 52.6k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 52.6k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 52.6k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 52.6k | } |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Mut, u8>>::wrapping_offset <wyz::comu::Address<wyz::comu::Mut, u8>>::add Line | Count | Source | 256 | 97.2k | pub $($unsafe)? fn $name$(< | 257 | 97.2k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 97.2k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 97.2k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 97.2k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::offset Line | Count | Source | 256 | 56.1k | pub $($unsafe)? fn $name$(< | 257 | 56.1k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 56.1k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 56.1k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 56.1k | } |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Const, u8>>::wrapping_offset <wyz::comu::Address<wyz::comu::Const, u8>>::add Line | Count | Source | 256 | 86.5k | pub $($unsafe)? fn $name$(< | 257 | 86.5k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 86.5k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 86.5k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 86.5k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::offset Line | Count | Source | 256 | 119k | pub $($unsafe)? fn $name$(< | 257 | 119k | $($lt,)* $($typaram$(: $($bound),+)?,)* | 258 | 119k | >)?(self$(, $arg: $ty)*) $(-> $ret)? { | 259 | 119k | self.with_ptr(|ptr| ptr.$name($($arg),*)) | 260 | 119k | } |
|
261 | | )+ }; |
262 | | } |
263 | | |
264 | | /// Implement all other pointer functions. |
265 | | macro_rules! map { |
266 | | ($( |
267 | | $(@$unsafe:ident)? |
268 | | $name:ident |
269 | | $(< |
270 | | $($lt:lifetime),* |
271 | | $($typaram:ident$(: $($bound:ident),+ $(,)?)?),* |
272 | | $(,)? |
273 | | >)? |
274 | | $(, $arg:ident: $ty:ty $(as $map:expr)?)* |
275 | | $(=> $ret:ty)? |
276 | | );+ $(;)?) => { $( |
277 | | #[doc = concat!("Applies `<*T>::", stringify!($name), "`.")] |
278 | | /// |
279 | | /// See [original documentation][orig]. |
280 | | /// |
281 | | #[doc = concat!("[orig]: https://doc.rust-lang.org/std/primitive.pointer.html#method.", stringify!($name))] |
282 | | pub $($unsafe)? fn $name$(< |
283 | | $($lt,)* $($typaram$(: $($bound),+)?,)* |
284 | | >)?(self$(, $arg: $ty)*) $(-> $ret)? { |
285 | | self.inner.as_ptr().$name($($arg$(.pipe($map))?),*) |
286 | | } |
287 | | )+ }; |
288 | | } |
289 | | |
290 | | /// Port of the pointer inherent methods on `Address`es of `Sized` types. |
291 | | #[allow(clippy::missing_safety_doc)] |
292 | | impl<M, T> Address<M, T> |
293 | | where M: Mutability |
294 | | { |
295 | | fwd! { |
296 | | cast<U> => Address<M, U>; |
297 | | @unsafe offset, count: isize => Self; |
298 | | @unsafe add, count: usize => Self; |
299 | | @unsafe sub, count: usize => Self; |
300 | | wrapping_offset, count: isize => Self; |
301 | | wrapping_add, count: usize => Self; |
302 | | wrapping_sub, count: usize => Self; |
303 | | } |
304 | | |
305 | | map! { |
306 | | @unsafe offset_from, origin: Self as |orig| orig.to_const() as *mut T => isize; |
307 | | @unsafe read => T; |
308 | | @unsafe read_volatile => T; |
309 | | @unsafe read_unaligned => T; |
310 | | @unsafe copy_to, dest: Address<Mut, T> as Address::to_mut, count: usize; |
311 | | @unsafe copy_to_nonoverlapping, dest: Address<Mut, T> as Address::to_mut, count: usize; |
312 | | align_offset, align: usize => usize; |
313 | | } |
314 | | } |
315 | | |
316 | | /// Port of the pointer inherent methods on `Address`es of any type. |
317 | | impl<M, T> Address<M, T> |
318 | | where |
319 | | M: Mutability, |
320 | | T: ?Sized, |
321 | | { |
322 | | map! { |
323 | | @unsafe as_ref<'a> => Option<&'a T>; |
324 | | } |
325 | | |
326 | | /// Applies a pointer -> pointer function within an Address -> Address. |
327 | | #[track_caller] |
328 | 637k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { |
329 | 637k | self.inner |
330 | 637k | .as_ptr() |
331 | 637k | .pipe(func) |
332 | 637k | .pipe(NonNull::new) |
333 | 637k | .unwrap() |
334 | 637k | .pipe(Address::new) |
335 | 637k | } <wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, u8>>::with_ptr::<core::cell::Cell<u8>, <wyz::comu::Address<wyz::comu::Frozen<wyz::comu::Mut>, u8>>::cast<core::cell::Cell<u8>>::{closure#0}> Line | Count | Source | 328 | 18.7k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 18.7k | self.inner | 330 | 18.7k | .as_ptr() | 331 | 18.7k | .pipe(func) | 332 | 18.7k | .pipe(NonNull::new) | 333 | 18.7k | .unwrap() | 334 | 18.7k | .pipe(Address::new) | 335 | 18.7k | } |
<wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::with_ptr::<bitvec::access::BitSafeU8, <wyz::comu::Address<wyz::comu::Mut, bitvec::access::BitSafeU8>>::offset::{closure#0}> Line | Count | Source | 328 | 52.6k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 52.6k | self.inner | 330 | 52.6k | .as_ptr() | 331 | 52.6k | .pipe(func) | 332 | 52.6k | .pipe(NonNull::new) | 333 | 52.6k | .unwrap() | 334 | 52.6k | .pipe(Address::new) | 335 | 52.6k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Mut, u8>>::cast<u8>::{closure#0}> Line | Count | Source | 328 | 115k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 115k | self.inner | 330 | 115k | .as_ptr() | 331 | 115k | .pipe(func) | 332 | 115k | .pipe(NonNull::new) | 333 | 115k | .unwrap() | 334 | 115k | .pipe(Address::new) | 335 | 115k | } |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Mut, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Mut, u8>>::wrapping_offset::{closure#0}> <wyz::comu::Address<wyz::comu::Mut, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Mut, u8>>::add::{closure#0}> Line | Count | Source | 328 | 97.2k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 97.2k | self.inner | 330 | 97.2k | .as_ptr() | 331 | 97.2k | .pipe(func) | 332 | 97.2k | .pipe(NonNull::new) | 333 | 97.2k | .unwrap() | 334 | 97.2k | .pipe(Address::new) | 335 | 97.2k | } |
<wyz::comu::Address<wyz::comu::Mut, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Mut, u8>>::offset::{closure#0}> Line | Count | Source | 328 | 56.1k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 56.1k | self.inner | 330 | 56.1k | .as_ptr() | 331 | 56.1k | .pipe(func) | 332 | 56.1k | .pipe(NonNull::new) | 333 | 56.1k | .unwrap() | 334 | 56.1k | .pipe(Address::new) | 335 | 56.1k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Const, u8>>::cast<u8>::{closure#0}> Line | Count | Source | 328 | 91.4k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 91.4k | self.inner | 330 | 91.4k | .as_ptr() | 331 | 91.4k | .pipe(func) | 332 | 91.4k | .pipe(NonNull::new) | 333 | 91.4k | .unwrap() | 334 | 91.4k | .pipe(Address::new) | 335 | 91.4k | } |
Unexecuted instantiation: <wyz::comu::Address<wyz::comu::Const, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Const, u8>>::wrapping_offset::{closure#0}> <wyz::comu::Address<wyz::comu::Const, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Const, u8>>::add::{closure#0}> Line | Count | Source | 328 | 86.5k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 86.5k | self.inner | 330 | 86.5k | .as_ptr() | 331 | 86.5k | .pipe(func) | 332 | 86.5k | .pipe(NonNull::new) | 333 | 86.5k | .unwrap() | 334 | 86.5k | .pipe(Address::new) | 335 | 86.5k | } |
<wyz::comu::Address<wyz::comu::Const, u8>>::with_ptr::<u8, <wyz::comu::Address<wyz::comu::Const, u8>>::offset::{closure#0}> Line | Count | Source | 328 | 119k | fn with_ptr<U>(self, func: impl FnOnce(*mut T) -> *mut U) -> Address<M, U> { | 329 | 119k | self.inner | 330 | 119k | .as_ptr() | 331 | 119k | .pipe(func) | 332 | 119k | .pipe(NonNull::new) | 333 | 119k | .unwrap() | 334 | 119k | .pipe(Address::new) | 335 | 119k | } |
|
336 | | } |
337 | | |
338 | | /// Port of pointer inherent methods on mutable `Address`es of sized types. |
339 | | impl<T> Address<Mut, T> { |
340 | | map! { |
341 | | @unsafe copy_from<M2: Mutability>, src: Address<M2, T> as Address::to_const, count: usize; |
342 | | @unsafe copy_from_nonoverlapping<M2: Mutability>, src: Address<M2, T> as Address::to_const, count: usize; |
343 | | @unsafe write, value: T; |
344 | | @unsafe write_volatile, value: T; |
345 | | @unsafe write_unaligned, value: T; |
346 | | @unsafe replace, src: T => T; |
347 | | @unsafe swap, with: Self as Self::to_mut; |
348 | | } |
349 | | } |
350 | | |
351 | | /// Port of pointer inherent methods on mutable `Address`es of any type. |
352 | | impl<T> Address<Mut, T> |
353 | | where T: ?Sized |
354 | | { |
355 | | map! { |
356 | | @unsafe as_mut<'a> => Option<&'a mut T>; |
357 | | @unsafe drop_in_place; |
358 | | } |
359 | | } |
360 | | |
361 | | impl<M, T> Clone for Address<M, T> |
362 | | where |
363 | | M: Mutability, |
364 | | T: ?Sized, |
365 | | { |
366 | | #[inline(always)] |
367 | | fn clone(&self) -> Self { |
368 | | *self |
369 | | } |
370 | | } |
371 | | |
372 | | impl<T> TryFrom<*const T> for Address<Const, T> |
373 | | where T: ?Sized |
374 | | { |
375 | | type Error = NullPtrError; |
376 | | |
377 | | #[inline(always)] |
378 | | fn try_from(elem: *const T) -> Result<Self, Self::Error> { |
379 | | NonNull::new(elem as *mut T) |
380 | | .ok_or(NullPtrError) |
381 | | .map(Self::new) |
382 | | } |
383 | | } |
384 | | |
385 | | impl<T> From<&T> for Address<Const, T> |
386 | | where T: ?Sized |
387 | | { |
388 | | #[inline(always)] |
389 | | fn from(elem: &T) -> Self { |
390 | | Self::new(elem.into()) |
391 | | } |
392 | | } |
393 | | |
394 | | impl<T> TryFrom<*mut T> for Address<Mut, T> |
395 | | where T: ?Sized |
396 | | { |
397 | | type Error = NullPtrError; |
398 | | |
399 | | #[inline(always)] |
400 | | fn try_from(elem: *mut T) -> Result<Self, Self::Error> { |
401 | | NonNull::new(elem).ok_or(NullPtrError).map(Self::new) |
402 | | } |
403 | | } |
404 | | |
405 | | impl<T> From<&mut T> for Address<Mut, T> |
406 | | where T: ?Sized |
407 | | { |
408 | | #[inline(always)] |
409 | | fn from(elem: &mut T) -> Self { |
410 | | Self::new(elem.into()) |
411 | | } |
412 | | } |
413 | | |
414 | | impl<M, T> Eq for Address<M, T> where M: Mutability |
415 | | { |
416 | | } |
417 | | |
418 | | impl<M1, M2, T1, T2> PartialEq<Address<M2, T2>> for Address<M1, T1> |
419 | | where |
420 | | M1: Mutability, |
421 | | M2: Mutability, |
422 | | { |
423 | | #[inline] |
424 | | fn eq(&self, other: &Address<M2, T2>) -> bool { |
425 | | self.inner.as_ptr() as usize == other.inner.as_ptr() as usize |
426 | | } |
427 | | } |
428 | | |
429 | | impl<M, T> Ord for Address<M, T> |
430 | | where M: Mutability |
431 | | { |
432 | | #[inline] |
433 | | fn cmp(&self, other: &Self) -> cmp::Ordering { |
434 | | self.partial_cmp(other) |
435 | | .expect("Addresses have a total ordering") |
436 | | } |
437 | | } |
438 | | |
439 | | impl<M1, M2, T1, T2> PartialOrd<Address<M2, T2>> for Address<M1, T1> |
440 | | where |
441 | | M1: Mutability, |
442 | | M2: Mutability, |
443 | | { |
444 | | #[inline] |
445 | | fn partial_cmp(&self, other: &Address<M2, T2>) -> Option<cmp::Ordering> { |
446 | | (self.inner.as_ptr() as usize) |
447 | | .partial_cmp(&(other.inner.as_ptr() as usize)) |
448 | | } |
449 | | } |
450 | | |
451 | | impl<M, T> Debug for Address<M, T> |
452 | | where |
453 | | M: Mutability, |
454 | | T: ?Sized, |
455 | | { |
456 | | #[inline(always)] |
457 | | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
458 | | Debug::fmt(&self.to_const(), fmt) |
459 | | } |
460 | | } |
461 | | |
462 | | impl<M, T> Pointer for Address<M, T> |
463 | | where |
464 | | M: Mutability, |
465 | | T: ?Sized, |
466 | | { |
467 | | #[inline(always)] |
468 | | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
469 | | Pointer::fmt(&self.to_const(), fmt) |
470 | | } |
471 | | } |
472 | | |
473 | | impl<M, T> Hash for Address<M, T> |
474 | | where |
475 | | M: Mutability, |
476 | | T: ?Sized, |
477 | | { |
478 | | #[inline(always)] |
479 | | fn hash<H>(&self, state: &mut H) |
480 | | where H: Hasher { |
481 | | self.inner.hash(state) |
482 | | } |
483 | | } |
484 | | |
485 | | impl<M, T> Copy for Address<M, T> |
486 | | where |
487 | | M: Mutability, |
488 | | T: ?Sized, |
489 | | { |
490 | | } |
491 | | |
492 | | impl<M, T> self::seal::Sealed for Address<M, T> |
493 | | where |
494 | | M: Mutability, |
495 | | T: ?Sized, |
496 | | { |
497 | | } |
498 | | |
499 | | /// Allows an `Address` to produce an ordinary reference. |
500 | | pub trait Referential<'a>: self::seal::Sealed { |
501 | | /// The created reference type. Must be one of `&T` or `&mut T`. |
502 | | type Ref: 'a + Deref; |
503 | | |
504 | | /// Converts the `Address` to a reference. |
505 | | /// |
506 | | /// ## Safety |
507 | | /// |
508 | | /// The caller is responsible for ensuring that the memory location that the |
509 | | /// `Address` describes contains an initialized value, and that the produced |
510 | | /// reference abides by the Rust `&`/`&mut` exclusion rules. |
511 | | unsafe fn to_ref(self) -> Self::Ref; |
512 | | |
513 | | /// Converts a reference back into an `Address`. |
514 | | fn from_ref(this: Self::Ref) -> Self; |
515 | | } |
516 | | |
517 | | impl<'a, T> Referential<'a> for Address<Const, T> |
518 | | where T: 'a + ?Sized |
519 | | { |
520 | | type Ref = &'a T; |
521 | | |
522 | | unsafe fn to_ref(self) -> Self::Ref { |
523 | | self.inner.as_ref() |
524 | | } |
525 | | |
526 | | fn from_ref(this: Self::Ref) -> Self { |
527 | | this.into() |
528 | | } |
529 | | } |
530 | | |
531 | | impl<'a, T> Referential<'a> for Address<Mut, T> |
532 | | where T: 'a + ?Sized |
533 | | { |
534 | | type Ref = &'a mut T; |
535 | | |
536 | | unsafe fn to_ref(mut self) -> Self::Ref { |
537 | | self.inner.as_mut() |
538 | | } |
539 | | |
540 | | fn from_ref(this: Self::Ref) -> Self { |
541 | | this.into() |
542 | | } |
543 | | } |
544 | | |
545 | | impl<'a, M, T> Referential<'a> for Address<Frozen<M>, T> |
546 | | where |
547 | | M: Mutability, |
548 | | T: 'a + ?Sized, |
549 | | { |
550 | | type Ref = &'a T; |
551 | | |
552 | | unsafe fn to_ref(self) -> Self::Ref { |
553 | | self.inner.as_ref() |
554 | | } |
555 | | |
556 | | fn from_ref(this: Self::Ref) -> Self { |
557 | | Self::new(NonNull::from(this)) |
558 | | } |
559 | | } |
560 | | |
561 | | /// A generically-mutable reference. |
562 | | pub type Reference<'a, M, T> = <Address<M, T> as Referential<'a>>::Ref; |
563 | | |
564 | | /// Allows an `Address<M, [T]>` to produce an ordinary slice reference. |
565 | | pub trait SliceReferential<'a>: Referential<'a> + self::seal::Sealed { |
566 | | /// The type of the element pointer. |
567 | | type ElementAddr; |
568 | | |
569 | | /// Constructs an ordinary slice reference from a base-address and a length. |
570 | | /// |
571 | | /// ## Parameters |
572 | | /// |
573 | | /// - `ptr`: The address of the base element in the slice. |
574 | | /// - `len`: The number of elements, beginning at `ptr`, in the slice. |
575 | | /// |
576 | | /// ## Safety |
577 | | /// |
578 | | /// The base address and the element count must describe a valid region of |
579 | | /// memory. |
580 | | unsafe fn from_raw_parts(ptr: Self::ElementAddr, len: usize) -> Self::Ref; |
581 | | } |
582 | | |
583 | | impl<'a, T> SliceReferential<'a> for Address<Const, [T]> |
584 | | where T: 'a |
585 | | { |
586 | | type ElementAddr = Address<Const, T>; |
587 | | |
588 | 91.4k | unsafe fn from_raw_parts(ptr: Self::ElementAddr, len: usize) -> Self::Ref { |
589 | 91.4k | slice::from_raw_parts(ptr.to_const(), len) |
590 | 91.4k | } |
591 | | } |
592 | | |
593 | | impl<'a, M, T> SliceReferential<'a> for Address<Frozen<M>, [T]> |
594 | | where |
595 | | M: Mutability, |
596 | | T: 'a, |
597 | | { |
598 | | type ElementAddr = Address<Frozen<M>, T>; |
599 | | |
600 | | unsafe fn from_raw_parts(ptr: Self::ElementAddr, len: usize) -> Self::Ref { |
601 | | slice::from_raw_parts(ptr.to_const(), len) |
602 | | } |
603 | | } |
604 | | |
605 | | impl<'a, T> SliceReferential<'a> for Address<Mut, [T]> |
606 | | where T: 'a |
607 | | { |
608 | | type ElementAddr = Address<Mut, T>; |
609 | | |
610 | 115k | unsafe fn from_raw_parts(ptr: Self::ElementAddr, len: usize) -> Self::Ref { |
611 | 115k | slice::from_raw_parts_mut(ptr.to_mut(), len) |
612 | 115k | } |
613 | | } |
614 | | |
615 | | /// [`Address`] cannot be constructed over null pointers. |
616 | | #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] |
617 | | pub struct NullPtrError; |
618 | | |
619 | | impl Display for NullPtrError { |
620 | | #[inline] |
621 | | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
622 | | write!(fmt, "wyz::Address cannot contain a null pointer") |
623 | | } |
624 | | } |
625 | | |
626 | | #[cfg(feature = "std")] |
627 | | impl std::error::Error for NullPtrError { |
628 | | } |
629 | | |
630 | | #[doc(hidden)] |
631 | | mod seal { |
632 | | #[doc(hidden)] |
633 | | pub trait Sealed {} |
634 | | } |