Coverage Report

Created: 2025-07-01 06:28

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