Coverage Report

Created: 2026-03-20 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitvec-1.0.1/src/domain.rs
Line
Count
Source
1
#![doc = include_str!("../doc/domain.md")]
2
3
use core::{
4
  any,
5
  convert::{
6
    TryFrom,
7
    TryInto,
8
  },
9
  fmt::{
10
    self,
11
    Binary,
12
    Debug,
13
    Display,
14
    Formatter,
15
    LowerHex,
16
    Octal,
17
    UpperHex,
18
  },
19
  hash::{
20
    Hash,
21
    Hasher,
22
  },
23
  iter::FusedIterator,
24
  marker::PhantomData,
25
};
26
27
use tap::{
28
  Conv,
29
  Pipe,
30
  Tap,
31
};
32
use wyz::{
33
  comu::{
34
    Address,
35
    Const,
36
    Mut,
37
    Mutability,
38
    Reference,
39
    Referential,
40
    SliceReferential,
41
  },
42
  fmt::FmtForward,
43
};
44
45
use crate::{
46
  access::BitAccess,
47
  index::{
48
    BitEnd,
49
    BitIdx,
50
    BitMask,
51
  },
52
  order::{
53
    BitOrder,
54
    Lsb0,
55
  },
56
  ptr::BitSpan,
57
  slice::BitSlice,
58
  store::BitStore,
59
};
60
61
#[doc = include_str!("../doc/domain/BitDomain.md")]
62
pub enum BitDomain<'a, M = Const, T = usize, O = Lsb0>
63
where
64
  M: Mutability,
65
  T: 'a + BitStore,
66
  O: BitOrder,
67
  Address<M, BitSlice<T, O>>: Referential<'a>,
68
  Address<M, BitSlice<T::Unalias, O>>: Referential<'a>,
69
{
70
  /// Indicates that a bit-slice’s contents are entirely in the interior
71
  /// indices of a single memory element.
72
  ///
73
  /// The contained value is always the bit-slice that created this view.
74
  Enclave(Reference<'a, M, BitSlice<T, O>>),
75
  /// Indicates that a bit-slice’s contents touch an element edge.
76
  ///
77
  /// This splits the bit-slice into three partitions, each of which may be
78
  /// empty: two partially-occupied edge elements, with their original type
79
  /// status, and one interior span, which is known to not have any other
80
  /// aliases derived from the bit-slice that created this view.
81
  Region {
82
    /// Any bits that partially-fill the first element of the underlying
83
    /// storage region.
84
    ///
85
    /// This does not modify its aliasing status, as it will already be
86
    /// appropriately marked before this view is constructed.
87
    head: Reference<'a, M, BitSlice<T, O>>,
88
    /// Any bits that wholly-fill elements in the interior of the bit-slice.
89
    ///
90
    /// This is marked as unaliased, because it is statically impossible for
91
    /// any other handle derived from the source bit-slice to have
92
    /// conflicting access to the region of memory it describes. As such,
93
    /// even a bit-slice that was marked as `::Alias` can revert this
94
    /// protection on the known-unaliased interior.
95
    ///
96
    /// Proofs:
97
    ///
98
    /// - Rust’s `&`/`&mut` exclusion rules universally apply. If a
99
    ///   reference exists, no other reference has unsynchronized write
100
    ///   capability.
101
    /// - `BitStore::Unalias` only modifies unsynchronized types. `Cell` and
102
    ///   atomic types unalias to themselves, and retain their original
103
    ///   behavior.
104
    body: Reference<'a, M, BitSlice<T::Unalias, O>>,
105
    /// Any bits that partially-fill the last element of the underlying
106
    /// storage region.
107
    ///
108
    /// This does not modify its aliasing status, as it will already be
109
    /// appropriately marked before this view is constructed.
110
    tail: Reference<'a, M, BitSlice<T, O>>,
111
  },
112
}
113
114
impl<'a, M, T, O> BitDomain<'a, M, T, O>
115
where
116
  M: Mutability,
117
  T: 'a + BitStore,
118
  O: BitOrder,
119
  Address<M, BitSlice<T, O>>: Referential<'a>,
120
  Address<M, BitSlice<T::Unalias, O>>: Referential<'a>,
121
{
122
  /// Attempts to unpack the bit-domain as an [`Enclave`] variant. This is
123
  /// just a shorthand for explicit destructuring.
124
  ///
125
  /// [`Enclave`]: Self::Enclave
126
  #[inline]
127
0
  pub fn enclave(self) -> Option<Reference<'a, M, BitSlice<T, O>>> {
128
0
    match self {
129
0
      Self::Enclave(bits) => Some(bits),
130
0
      _ => None,
131
    }
132
0
  }
133
134
  /// Attempts to unpack the bit-domain as a [`Region`] variant. This is just
135
  /// a shorthand for explicit destructuring.
136
  ///
137
  /// [`Region`]: Self::Region
138
  #[inline]
139
0
  pub fn region(
140
0
    self,
141
0
  ) -> Option<(
142
0
    Reference<'a, M, BitSlice<T, O>>,
143
0
    Reference<'a, M, BitSlice<T::Unalias, O>>,
144
0
    Reference<'a, M, BitSlice<T, O>>,
145
0
  )> {
146
0
    match self {
147
0
      Self::Region { head, body, tail } => Some((head, body, tail)),
148
0
      _ => None,
149
    }
150
0
  }
151
}
152
153
impl<'a, M, T, O> Default for BitDomain<'a, M, T, O>
154
where
155
  M: Mutability,
156
  T: 'a + BitStore,
157
  O: BitOrder,
158
  Address<M, BitSlice<T, O>>: Referential<'a>,
159
  Address<M, BitSlice<T::Unalias, O>>: Referential<'a>,
160
  Reference<'a, M, BitSlice<T, O>>: Default,
161
  Reference<'a, M, BitSlice<T::Unalias, O>>: Default,
162
{
163
  #[inline]
164
0
  fn default() -> Self {
165
0
    Self::Region {
166
0
      head: Default::default(),
167
0
      body: Default::default(),
168
0
      tail: Default::default(),
169
0
    }
170
0
  }
171
}
172
173
impl<'a, M, T, O> Debug for BitDomain<'a, M, T, O>
174
where
175
  M: Mutability,
176
  T: 'a + BitStore,
177
  O: BitOrder,
178
  Address<M, BitSlice<T, O>>: Referential<'a>,
179
  Address<M, BitSlice<T::Unalias, O>>: Referential<'a>,
180
  Reference<'a, M, BitSlice<T, O>>: Debug,
181
  Reference<'a, M, BitSlice<T::Unalias, O>>: Debug,
182
{
183
  #[inline]
184
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
185
0
    write!(
186
0
      fmt,
187
0
      "BitDomain::<{} {}, {}>::",
188
      M::RENDER,
189
0
      any::type_name::<T::Mem>(),
190
0
      any::type_name::<O>(),
191
0
    )?;
192
0
    match self {
193
0
      Self::Enclave(elem) => {
194
0
        fmt.debug_tuple("Enclave").field(elem).finish()
195
      },
196
0
      Self::Region { head, body, tail } => fmt
197
0
        .debug_struct("Region")
198
0
        .field("head", head)
199
0
        .field("body", body)
200
0
        .field("tail", tail)
201
0
        .finish(),
202
    }
203
0
  }
204
}
205
206
#[cfg(not(tarpaulin_include))]
207
impl<T, O> Clone for BitDomain<'_, Const, T, O>
208
where
209
  T: BitStore,
210
  O: BitOrder,
211
{
212
  #[inline]
213
0
  fn clone(&self) -> Self {
214
0
    *self
215
0
  }
216
}
217
218
impl<T, O> Copy for BitDomain<'_, Const, T, O>
219
where
220
  T: BitStore,
221
  O: BitOrder,
222
{
223
}
224
225
#[doc = include_str!("../doc/domain/Domain.md")]
226
pub enum Domain<'a, M = Const, T = usize, O = Lsb0>
227
where
228
  M: Mutability,
229
  T: 'a + BitStore,
230
  O: BitOrder,
231
  Address<M, T>: Referential<'a>,
232
  Address<M, [T::Unalias]>: SliceReferential<'a>,
233
{
234
  /// Indicates that a bit-slice’s contents are entirely in the interior
235
  /// indices of a single memory element.
236
  ///
237
  /// The contained reference is only able to observe the bits governed by the
238
  /// generating bit-slice. Other handles to the element may exist, and may
239
  /// write to bits outside the range that this reference can observe.
240
  Enclave(PartialElement<'a, M, T, O>),
241
  /// Indicates that a bit-slice’s contents touch an element edge.
242
  ///
243
  /// This splits the bit-slice into three partitions, each of which may be
244
  /// empty: two partially-occupied edge elements, with their original type
245
  /// status, and one interior span, which is known not to have any other
246
  /// aliases derived from the bit-slice that created this view.
247
  Region {
248
    /// The first element in the bit-slice’s underlying storage, if it is
249
    /// only partially used.
250
    head: Option<PartialElement<'a, M, T, O>>,
251
    /// All fully-used elements in the bit-slice’s underlying storage.
252
    ///
253
    /// This is marked as unaliased, because it is statically impossible for
254
    /// any other handle derived from the source bit-slice to have
255
    /// conflicting access to the region of memory it describes. As such,
256
    /// even a bit-slice that was marked as `::Alias` can revert this
257
    /// protection on the known-unaliased interior.
258
    body: Reference<'a, M, [T::Unalias]>,
259
    /// The last element in the bit-slice’s underlying storage, if it is
260
    /// only partially used.
261
    tail: Option<PartialElement<'a, M, T, O>>,
262
  },
263
}
264
265
impl<'a, M, T, O> Domain<'a, M, T, O>
266
where
267
  M: Mutability,
268
  T: 'a + BitStore,
269
  O: BitOrder,
270
  Address<M, T>: Referential<'a>,
271
  Address<M, [T::Unalias]>: SliceReferential<'a>,
272
{
273
  /// Attempts to unpack the bit-domain as an [`Enclave`] variant. This is
274
  /// just a shorthand for explicit destructuring.
275
  ///
276
  /// [`Enclave`]: Self::Enclave
277
  #[inline]
278
0
  pub fn enclave(self) -> Option<PartialElement<'a, M, T, O>> {
279
0
    match self {
280
0
      Self::Enclave(elem) => Some(elem),
281
0
      _ => None,
282
    }
283
0
  }
284
285
  /// Attempts to unpack the bit-domain as a [`Region`] variant. This is just
286
  /// a shorthand for explicit destructuring.
287
  ///
288
  /// [`Region`]: Self::Region
289
  #[inline]
290
0
  pub fn region(
291
0
    self,
292
0
  ) -> Option<(
293
0
    Option<PartialElement<'a, M, T, O>>,
294
0
    Reference<'a, M, [T::Unalias]>,
295
0
    Option<PartialElement<'a, M, T, O>>,
296
0
  )> {
297
0
    match self {
298
0
      Self::Region { head, body, tail } => Some((head, body, tail)),
299
0
      _ => None,
300
    }
301
0
  }
302
303
  /// Converts the element-wise `Domain` into the equivalent `BitDomain`.
304
  ///
305
  /// This transform replaces each memory reference with an equivalent
306
  /// `BitSlice` reference.
307
  #[inline]
308
0
  pub fn into_bit_domain(self) -> BitDomain<'a, M, T, O>
309
0
  where
310
0
    Address<M, BitSlice<T, O>>: Referential<'a>,
311
0
    Address<M, BitSlice<T::Unalias, O>>: Referential<'a>,
312
0
    Reference<'a, M, BitSlice<T, O>>: Default,
313
0
    Reference<'a, M, BitSlice<T::Unalias, O>>:
314
0
      TryFrom<Reference<'a, M, [T::Unalias]>>,
315
  {
316
0
    match self {
317
0
      Self::Enclave(elem) => BitDomain::Enclave(elem.into_bitslice()),
318
0
      Self::Region { head, body, tail } => BitDomain::Region {
319
0
        head: head.map_or_else(
320
          Default::default,
321
          PartialElement::into_bitslice,
322
        ),
323
0
        body: body.try_into().unwrap_or_else(|_| {
324
0
          match option_env!("CARGO_PKG_REPOSITORY") {
325
0
            Some(env) => unreachable!(
326
              "Construction of a slice with length {} should not \
327
               be possible. If this assumption is outdated, \
328
               please file an issue at {}",
329
              (isize::MIN as usize) >> 3,
330
              env,
331
            ),
332
0
            None => unreachable!(
333
              "Construction of a slice with length {} should not \
334
               be possible. If this assumption is outdated, \
335
               please consider filing an issue",
336
              (isize::MIN as usize) >> 3
337
            ),
338
          }
339
        }),
340
0
        tail: tail.map_or_else(
341
          Default::default,
342
          PartialElement::into_bitslice,
343
        ),
344
      },
345
    }
346
0
  }
347
}
348
349
/** Domain constructors.
350
351
Only `Domain<Const>` and `Domain<Mut>` are ever constructed, and they of course
352
are only constructed from `&BitSlice` and `&mut BitSlice`, respectively.
353
354
However, the Rust trait system does not have a way to express a closed set, so
355
**/
356
impl<'a, M, T, O> Domain<'a, M, T, O>
357
where
358
  M: Mutability,
359
  T: 'a + BitStore,
360
  O: BitOrder,
361
  Address<M, T>: Referential<'a>,
362
  Address<M, [T::Unalias]>:
363
    SliceReferential<'a, ElementAddr = Address<M, T::Unalias>>,
364
  Address<M, BitSlice<T, O>>: Referential<'a>,
365
  Reference<'a, M, [T::Unalias]>: Default,
366
{
367
  /// Creates a new `Domain` over a bit-slice.
368
  ///
369
  /// ## Parameters
370
  ///
371
  /// - `bits`: Either a `&BitSlice` or `&mut BitSlice` reference, depending
372
  ///   on whether a `Domain<Const>` or `Domain<Mut>` is being produced.
373
  ///
374
  /// ## Returns
375
  ///
376
  /// A `Domain` description of the raw memory governed by `bits`.
377
527k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
527k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
527k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
527k
    let (head, elts, tail) =
381
527k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
527k
    let base = bitspan.address();
383
527k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
527k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
527k
      (h, _, t) if h == min && t == max => Self::spanning,
387
350k
      (_, _, t) if t == max => Self::partial_head,
388
146k
      (h, ..) if h == min => Self::partial_tail,
389
14.7k
      (_, 1, _) => Self::minor,
390
123k
      _ => Self::major,
391
    };
392
527k
    ctor(base, elts, head, tail)
393
527k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::new
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new
Line
Count
Source
377
293k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
293k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
293k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
293k
    let (head, elts, tail) =
381
293k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
293k
    let base = bitspan.address();
383
293k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
293k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
293k
      (h, _, t) if h == min && t == max => Self::spanning,
387
171k
      (_, _, t) if t == max => Self::partial_head,
388
86.5k
      (h, ..) if h == min => Self::partial_tail,
389
7.59k
      (_, 1, _) => Self::minor,
390
78.9k
      _ => Self::major,
391
    };
392
293k
    ctor(base, elts, head, tail)
393
293k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::new
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::new
Line
Count
Source
377
234k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
234k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
234k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
234k
    let (head, elts, tail) =
381
234k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
234k
    let base = bitspan.address();
383
234k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
234k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
234k
      (h, _, t) if h == min && t == max => Self::spanning,
387
178k
      (_, _, t) if t == max => Self::partial_head,
388
59.5k
      (h, ..) if h == min => Self::partial_tail,
389
7.13k
      (_, 1, _) => Self::minor,
390
44.1k
      _ => Self::major,
391
    };
392
234k
    ctor(base, elts, head, tail)
393
234k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::new
394
395
  /// Produces the canonical empty `Domain`.
396
  #[inline]
397
0
  fn empty(
398
0
    _: Address<M, T>,
399
0
    _: usize,
400
0
    _: BitIdx<T::Mem>,
401
0
    _: BitEnd<T::Mem>,
402
0
  ) -> Self {
403
0
    Default::default()
404
0
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::empty
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::empty
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::empty
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::empty
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::empty
405
406
  /// Produces a `Domain::Region` that contains both `head` and `tail` partial
407
  /// elements as well as a `body` slice (which may be empty).
408
  #[inline]
409
123k
  fn major(
410
123k
    addr: Address<M, T>,
411
123k
    elts: usize,
412
123k
    head: BitIdx<T::Mem>,
413
123k
    tail: BitEnd<T::Mem>,
414
123k
  ) -> Self {
415
123k
    let h_elem = addr;
416
123k
    let t_elem = unsafe { addr.add(elts - 1) };
417
123k
    let body = unsafe {
418
123k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
123k
        addr.add(1).cast::<T::Unalias>(),
420
123k
        elts - 2,
421
      )
422
    };
423
123k
    Self::Region {
424
123k
      head: Some(PartialElement::new(h_elem, head, None)),
425
123k
      body,
426
123k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
123k
    }
428
123k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::major
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::major
Line
Count
Source
409
78.9k
  fn major(
410
78.9k
    addr: Address<M, T>,
411
78.9k
    elts: usize,
412
78.9k
    head: BitIdx<T::Mem>,
413
78.9k
    tail: BitEnd<T::Mem>,
414
78.9k
  ) -> Self {
415
78.9k
    let h_elem = addr;
416
78.9k
    let t_elem = unsafe { addr.add(elts - 1) };
417
78.9k
    let body = unsafe {
418
78.9k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
78.9k
        addr.add(1).cast::<T::Unalias>(),
420
78.9k
        elts - 2,
421
      )
422
    };
423
78.9k
    Self::Region {
424
78.9k
      head: Some(PartialElement::new(h_elem, head, None)),
425
78.9k
      body,
426
78.9k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
78.9k
    }
428
78.9k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::major
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::major
Line
Count
Source
409
44.1k
  fn major(
410
44.1k
    addr: Address<M, T>,
411
44.1k
    elts: usize,
412
44.1k
    head: BitIdx<T::Mem>,
413
44.1k
    tail: BitEnd<T::Mem>,
414
44.1k
  ) -> Self {
415
44.1k
    let h_elem = addr;
416
44.1k
    let t_elem = unsafe { addr.add(elts - 1) };
417
44.1k
    let body = unsafe {
418
44.1k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
44.1k
        addr.add(1).cast::<T::Unalias>(),
420
44.1k
        elts - 2,
421
      )
422
    };
423
44.1k
    Self::Region {
424
44.1k
      head: Some(PartialElement::new(h_elem, head, None)),
425
44.1k
      body,
426
44.1k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
44.1k
    }
428
44.1k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::major
429
430
  /// Produces a `Domain::Enclave`.
431
  #[inline]
432
14.7k
  fn minor(
433
14.7k
    addr: Address<M, T>,
434
14.7k
    _: usize,
435
14.7k
    head: BitIdx<T::Mem>,
436
14.7k
    tail: BitEnd<T::Mem>,
437
14.7k
  ) -> Self {
438
14.7k
    let elem = addr;
439
14.7k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
14.7k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::minor
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::minor
Line
Count
Source
432
7.59k
  fn minor(
433
7.59k
    addr: Address<M, T>,
434
7.59k
    _: usize,
435
7.59k
    head: BitIdx<T::Mem>,
436
7.59k
    tail: BitEnd<T::Mem>,
437
7.59k
  ) -> Self {
438
7.59k
    let elem = addr;
439
7.59k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
7.59k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::minor
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::minor
Line
Count
Source
432
7.13k
  fn minor(
433
7.13k
    addr: Address<M, T>,
434
7.13k
    _: usize,
435
7.13k
    head: BitIdx<T::Mem>,
436
7.13k
    tail: BitEnd<T::Mem>,
437
7.13k
  ) -> Self {
438
7.13k
    let elem = addr;
439
7.13k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
7.13k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::minor
441
442
  /// Produces a `Domain::Region` with a partial `head` and a `body`, but no
443
  /// `tail`.
444
  #[inline]
445
204k
  fn partial_head(
446
204k
    addr: Address<M, T>,
447
204k
    elts: usize,
448
204k
    head: BitIdx<T::Mem>,
449
204k
    _: BitEnd<T::Mem>,
450
204k
  ) -> Self {
451
204k
    let elem = addr;
452
204k
    let body = unsafe {
453
204k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
204k
        addr.add(1).cast::<T::Unalias>(),
455
204k
        elts - 1,
456
      )
457
    };
458
204k
    Self::Region {
459
204k
      head: Some(PartialElement::new(elem, head, None)),
460
204k
      body,
461
204k
      tail: None,
462
204k
    }
463
204k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::partial_head
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::partial_head
Line
Count
Source
445
85.0k
  fn partial_head(
446
85.0k
    addr: Address<M, T>,
447
85.0k
    elts: usize,
448
85.0k
    head: BitIdx<T::Mem>,
449
85.0k
    _: BitEnd<T::Mem>,
450
85.0k
  ) -> Self {
451
85.0k
    let elem = addr;
452
85.0k
    let body = unsafe {
453
85.0k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
85.0k
        addr.add(1).cast::<T::Unalias>(),
455
85.0k
        elts - 1,
456
      )
457
    };
458
85.0k
    Self::Region {
459
85.0k
      head: Some(PartialElement::new(elem, head, None)),
460
85.0k
      body,
461
85.0k
      tail: None,
462
85.0k
    }
463
85.0k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::partial_head
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::partial_head
Line
Count
Source
445
119k
  fn partial_head(
446
119k
    addr: Address<M, T>,
447
119k
    elts: usize,
448
119k
    head: BitIdx<T::Mem>,
449
119k
    _: BitEnd<T::Mem>,
450
119k
  ) -> Self {
451
119k
    let elem = addr;
452
119k
    let body = unsafe {
453
119k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
119k
        addr.add(1).cast::<T::Unalias>(),
455
119k
        elts - 1,
456
      )
457
    };
458
119k
    Self::Region {
459
119k
      head: Some(PartialElement::new(elem, head, None)),
460
119k
      body,
461
119k
      tail: None,
462
119k
    }
463
119k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::partial_head
464
465
  /// Produces a `Domain::Region` with a partial `tail` and a `body`, but no
466
  /// `head`.
467
  #[inline]
468
8.20k
  fn partial_tail(
469
8.20k
    addr: Address<M, T>,
470
8.20k
    elts: usize,
471
8.20k
    _: BitIdx<T::Mem>,
472
8.20k
    tail: BitEnd<T::Mem>,
473
8.20k
  ) -> Self {
474
8.20k
    let elem = unsafe { addr.add(elts - 1) };
475
8.20k
    let body = unsafe {
476
8.20k
      Address::<M, [T::Unalias]>::from_raw_parts(
477
8.20k
        addr.cast::<T::Unalias>(),
478
8.20k
        elts - 1,
479
      )
480
    };
481
8.20k
    Self::Region {
482
8.20k
      head: None,
483
8.20k
      body,
484
8.20k
      tail: Some(PartialElement::new(elem, None, tail)),
485
8.20k
    }
486
8.20k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::partial_tail
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::partial_tail
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::partial_tail
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::partial_tail
Line
Count
Source
468
8.20k
  fn partial_tail(
469
8.20k
    addr: Address<M, T>,
470
8.20k
    elts: usize,
471
8.20k
    _: BitIdx<T::Mem>,
472
8.20k
    tail: BitEnd<T::Mem>,
473
8.20k
  ) -> Self {
474
8.20k
    let elem = unsafe { addr.add(elts - 1) };
475
8.20k
    let body = unsafe {
476
8.20k
      Address::<M, [T::Unalias]>::from_raw_parts(
477
8.20k
        addr.cast::<T::Unalias>(),
478
8.20k
        elts - 1,
479
      )
480
    };
481
8.20k
    Self::Region {
482
8.20k
      head: None,
483
8.20k
      body,
484
8.20k
      tail: Some(PartialElement::new(elem, None, tail)),
485
8.20k
    }
486
8.20k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::partial_tail
487
488
  /// Produces a `Domain::Region` with neither `head` nor `tail`, but only a
489
  /// `body`.
490
  #[inline]
491
177k
  fn spanning(
492
177k
    addr: Address<M, T>,
493
177k
    elts: usize,
494
177k
    _: BitIdx<T::Mem>,
495
177k
    _: BitEnd<T::Mem>,
496
177k
  ) -> Self {
497
177k
    Self::Region {
498
177k
      head: None,
499
177k
      body: unsafe {
500
177k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
177k
          addr.cast::<T::Unalias>(),
502
177k
          elts,
503
177k
        )
504
177k
      },
505
177k
      tail: None,
506
177k
    }
507
177k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::spanning
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::spanning
Line
Count
Source
491
121k
  fn spanning(
492
121k
    addr: Address<M, T>,
493
121k
    elts: usize,
494
121k
    _: BitIdx<T::Mem>,
495
121k
    _: BitEnd<T::Mem>,
496
121k
  ) -> Self {
497
121k
    Self::Region {
498
121k
      head: None,
499
121k
      body: unsafe {
500
121k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
121k
          addr.cast::<T::Unalias>(),
502
121k
          elts,
503
121k
        )
504
121k
      },
505
121k
      tail: None,
506
121k
    }
507
121k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::spanning
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::spanning
Line
Count
Source
491
56.1k
  fn spanning(
492
56.1k
    addr: Address<M, T>,
493
56.1k
    elts: usize,
494
56.1k
    _: BitIdx<T::Mem>,
495
56.1k
    _: BitEnd<T::Mem>,
496
56.1k
  ) -> Self {
497
56.1k
    Self::Region {
498
56.1k
      head: None,
499
56.1k
      body: unsafe {
500
56.1k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
56.1k
          addr.cast::<T::Unalias>(),
502
56.1k
          elts,
503
56.1k
        )
504
56.1k
      },
505
56.1k
      tail: None,
506
56.1k
    }
507
56.1k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::spanning
508
}
509
510
impl<'a, M, T, O> Default for Domain<'a, M, T, O>
511
where
512
  M: Mutability,
513
  T: 'a + BitStore,
514
  O: BitOrder,
515
  Address<M, T>: Referential<'a>,
516
  Address<M, [T::Unalias]>: SliceReferential<'a>,
517
  Reference<'a, M, [T::Unalias]>: Default,
518
{
519
  #[inline]
520
0
  fn default() -> Self {
521
0
    Self::Region {
522
0
      head: None,
523
0
      body: Reference::<M, [T::Unalias]>::default(),
524
0
      tail: None,
525
0
    }
526
0
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8> as core::default::Default>::default
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0> as core::default::Default>::default
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8> as core::default::Default>::default
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0> as core::default::Default>::default
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _> as core::default::Default>::default
527
}
528
529
impl<'a, M, T, O> Debug for Domain<'a, M, T, O>
530
where
531
  M: Mutability,
532
  T: 'a + BitStore,
533
  O: BitOrder,
534
  Address<M, T>: Referential<'a>,
535
  Address<M, [T::Unalias]>: SliceReferential<'a>,
536
  Reference<'a, M, [T::Unalias]>: Debug,
537
{
538
  #[inline]
539
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
540
0
    write!(
541
0
      fmt,
542
0
      "Domain::<{} {}, {}>::",
543
      M::RENDER,
544
0
      any::type_name::<T>(),
545
0
      any::type_name::<O>(),
546
0
    )?;
547
0
    match self {
548
0
      Self::Enclave(elem) => {
549
0
        fmt.debug_tuple("Enclave").field(elem).finish()
550
      },
551
0
      Self::Region { head, body, tail } => fmt
552
0
        .debug_struct("Region")
553
0
        .field("head", head)
554
0
        .field("body", body)
555
0
        .field("tail", tail)
556
0
        .finish(),
557
    }
558
0
  }
559
}
560
561
#[cfg(not(tarpaulin_include))]
562
impl<T, O> Clone for Domain<'_, Const, T, O>
563
where
564
  T: BitStore,
565
  O: BitOrder,
566
{
567
  #[inline]
568
0
  fn clone(&self) -> Self {
569
0
    *self
570
0
  }
571
}
572
573
impl<T, O> Iterator for Domain<'_, Const, T, O>
574
where
575
  T: BitStore,
576
  O: BitOrder,
577
{
578
  type Item = T::Mem;
579
580
  #[inline]
581
0
  fn next(&mut self) -> Option<Self::Item> {
582
0
    match self {
583
0
      Self::Enclave(elem) => {
584
0
        elem.load_value().tap(|_| *self = Default::default()).into()
585
      },
586
0
      Self::Region { head, body, tail } => {
587
0
        if let Some(elem) = head.take() {
588
0
          return elem.load_value().into();
589
0
        }
590
0
        if let Some((elem, rest)) = body.split_first() {
591
0
          *body = rest;
592
0
          return elem.load_value().into();
593
0
        }
594
0
        if let Some(elem) = tail.take() {
595
0
          return elem.load_value().into();
596
0
        }
597
0
        None
598
      },
599
    }
600
0
  }
601
}
602
603
impl<T, O> DoubleEndedIterator for Domain<'_, Const, T, O>
604
where
605
  T: BitStore,
606
  O: BitOrder,
607
{
608
  #[inline]
609
0
  fn next_back(&mut self) -> Option<Self::Item> {
610
0
    match self {
611
0
      Self::Enclave(elem) => {
612
0
        elem.load_value().tap(|_| *self = Default::default()).into()
613
      },
614
0
      Self::Region { head, body, tail } => {
615
0
        if let Some(elem) = tail.take() {
616
0
          return elem.load_value().into();
617
0
        }
618
0
        if let Some((elem, rest)) = body.split_last() {
619
0
          *body = rest;
620
0
          return elem.load_value().into();
621
0
        }
622
0
        if let Some(elem) = head.take() {
623
0
          return elem.load_value().into();
624
0
        }
625
0
        None
626
      },
627
    }
628
0
  }
629
}
630
631
impl<T, O> ExactSizeIterator for Domain<'_, Const, T, O>
632
where
633
  T: BitStore,
634
  O: BitOrder,
635
{
636
  #[inline]
637
0
  fn len(&self) -> usize {
638
0
    match self {
639
0
      Self::Enclave(_) => 1,
640
0
      Self::Region { head, body, tail } => {
641
0
        head.is_some() as usize + body.len() + tail.is_some() as usize
642
      },
643
    }
644
0
  }
645
}
646
647
impl<T, O> FusedIterator for Domain<'_, Const, T, O>
648
where
649
  T: BitStore,
650
  O: BitOrder,
651
{
652
}
653
654
impl<T, O> Copy for Domain<'_, Const, T, O>
655
where
656
  T: BitStore,
657
  O: BitOrder,
658
{
659
}
660
661
/// Implements numeric formatting by rendering each element.
662
macro_rules! fmt {
663
  ($($fmt:ty => $fwd:ident),+ $(,)?) => { $(
664
    impl<'a, T, O> $fmt for Domain<'a, Const, T, O>
665
    where
666
      O: BitOrder,
667
      T: BitStore,
668
    {
669
      #[inline]
670
0
      fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
671
0
        fmt.debug_list()
672
0
          .entries(self.into_iter().map(FmtForward::$fwd))
673
0
          .finish()
674
0
      }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, _, _> as core::fmt::Binary>::fmt
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, _, _> as core::fmt::Display>::fmt
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, _, _> as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, _, _> as core::fmt::Octal>::fmt
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, _, _> as core::fmt::UpperHex>::fmt
675
    }
676
  )+ };
677
}
678
679
fmt! {
680
  Binary => fmt_binary,
681
  Display => fmt_display,
682
  LowerHex => fmt_lower_hex,
683
  Octal => fmt_octal,
684
  UpperHex => fmt_upper_hex,
685
}
686
687
#[doc = include_str!("../doc/domain/PartialElement.md")]
688
pub struct PartialElement<'a, M, T, O>
689
where
690
  M: Mutability,
691
  T: 'a + BitStore,
692
  O: BitOrder,
693
{
694
  /// The address of the memory element being partially viewed.
695
  ///
696
  /// This must be stored as a pointer, not a reference, because it must
697
  /// retain mutability permissions but cannot have an `&mut` reference to
698
  /// a shared element.
699
  ///
700
  /// Similarly, it must remain typed as `T`, not `T::Access`, to allow the
701
  /// `<Const, uN>` case not to inappropriately produce a `<Const, Cell<uN>>`
702
  /// even if no write is performed.
703
  elem: Address<M, T>,
704
  /// Cache the selector mask, so it never needs to be recomputed.
705
  mask: BitMask<T::Mem>,
706
  /// The starting index.
707
  head: BitIdx<T::Mem>,
708
  /// The ending index.
709
  tail: BitEnd<T::Mem>,
710
  /// Preserve the originating bit-order
711
  _ord: PhantomData<O>,
712
  /// This type acts as-if it were a shared-mutable reference.
713
  _ref: PhantomData<&'a T::Access>,
714
}
715
716
impl<'a, M, T, O> PartialElement<'a, M, T, O>
717
where
718
  M: Mutability,
719
  T: 'a + BitStore,
720
  O: BitOrder,
721
{
722
  /// Constructs a new partial-element guarded reference.
723
  ///
724
  /// ## Parameters
725
  ///
726
  /// - `elem`: the element to which this partially points.
727
  /// - `head`: the index at which the partial region begins.
728
  /// - `tail`: the index at which the partial region ends.
729
  #[inline]
730
473k
  fn new(
731
473k
    elem: Address<M, T>,
732
473k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
473k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
473k
  ) -> Self {
735
473k
    let (head, tail) = (
736
473k
      head.into().unwrap_or(BitIdx::MIN),
737
473k
      tail.into().unwrap_or(BitEnd::MAX),
738
473k
    );
739
473k
    Self {
740
473k
      elem,
741
473k
      mask: O::mask(head, tail),
742
473k
      head,
743
473k
      tail,
744
473k
      _ord: PhantomData,
745
473k
      _ref: PhantomData,
746
473k
    }
747
473k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::new::<bitvec::index::BitIdx<u8>, bitvec::index::BitEnd<u8>>
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::new::<bitvec::index::BitIdx<u8>, core::option::Option<bitvec::index::BitEnd<u8>>>
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::new::<core::option::Option<bitvec::index::BitIdx<u8>>, bitvec::index::BitEnd<u8>>
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new::<bitvec::index::BitIdx<u8>, bitvec::index::BitEnd<u8>>
Line
Count
Source
730
7.59k
  fn new(
731
7.59k
    elem: Address<M, T>,
732
7.59k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
7.59k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
7.59k
  ) -> Self {
735
7.59k
    let (head, tail) = (
736
7.59k
      head.into().unwrap_or(BitIdx::MIN),
737
7.59k
      tail.into().unwrap_or(BitEnd::MAX),
738
7.59k
    );
739
7.59k
    Self {
740
7.59k
      elem,
741
7.59k
      mask: O::mask(head, tail),
742
7.59k
      head,
743
7.59k
      tail,
744
7.59k
      _ord: PhantomData,
745
7.59k
      _ref: PhantomData,
746
7.59k
    }
747
7.59k
  }
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new::<bitvec::index::BitIdx<u8>, core::option::Option<bitvec::index::BitEnd<u8>>>
Line
Count
Source
730
164k
  fn new(
731
164k
    elem: Address<M, T>,
732
164k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
164k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
164k
  ) -> Self {
735
164k
    let (head, tail) = (
736
164k
      head.into().unwrap_or(BitIdx::MIN),
737
164k
      tail.into().unwrap_or(BitEnd::MAX),
738
164k
    );
739
164k
    Self {
740
164k
      elem,
741
164k
      mask: O::mask(head, tail),
742
164k
      head,
743
164k
      tail,
744
164k
      _ord: PhantomData,
745
164k
      _ref: PhantomData,
746
164k
    }
747
164k
  }
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new::<core::option::Option<bitvec::index::BitIdx<u8>>, bitvec::index::BitEnd<u8>>
Line
Count
Source
730
78.9k
  fn new(
731
78.9k
    elem: Address<M, T>,
732
78.9k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
78.9k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
78.9k
  ) -> Self {
735
78.9k
    let (head, tail) = (
736
78.9k
      head.into().unwrap_or(BitIdx::MIN),
737
78.9k
      tail.into().unwrap_or(BitEnd::MAX),
738
78.9k
    );
739
78.9k
    Self {
740
78.9k
      elem,
741
78.9k
      mask: O::mask(head, tail),
742
78.9k
      head,
743
78.9k
      tail,
744
78.9k
      _ord: PhantomData,
745
78.9k
      _ref: PhantomData,
746
78.9k
    }
747
78.9k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::new::<bitvec::index::BitIdx<u8>, bitvec::index::BitEnd<u8>>
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::new::<bitvec::index::BitIdx<u8>, core::option::Option<bitvec::index::BitEnd<u8>>>
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::new::<core::option::Option<bitvec::index::BitIdx<u8>>, bitvec::index::BitEnd<u8>>
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::new::<bitvec::index::BitIdx<u8>, bitvec::index::BitEnd<u8>>
Line
Count
Source
730
7.13k
  fn new(
731
7.13k
    elem: Address<M, T>,
732
7.13k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
7.13k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
7.13k
  ) -> Self {
735
7.13k
    let (head, tail) = (
736
7.13k
      head.into().unwrap_or(BitIdx::MIN),
737
7.13k
      tail.into().unwrap_or(BitEnd::MAX),
738
7.13k
    );
739
7.13k
    Self {
740
7.13k
      elem,
741
7.13k
      mask: O::mask(head, tail),
742
7.13k
      head,
743
7.13k
      tail,
744
7.13k
      _ord: PhantomData,
745
7.13k
      _ref: PhantomData,
746
7.13k
    }
747
7.13k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::new::<bitvec::index::BitIdx<u8>, core::option::Option<bitvec::index::BitEnd<u8>>>
Line
Count
Source
730
163k
  fn new(
731
163k
    elem: Address<M, T>,
732
163k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
163k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
163k
  ) -> Self {
735
163k
    let (head, tail) = (
736
163k
      head.into().unwrap_or(BitIdx::MIN),
737
163k
      tail.into().unwrap_or(BitEnd::MAX),
738
163k
    );
739
163k
    Self {
740
163k
      elem,
741
163k
      mask: O::mask(head, tail),
742
163k
      head,
743
163k
      tail,
744
163k
      _ord: PhantomData,
745
163k
      _ref: PhantomData,
746
163k
    }
747
163k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::new::<core::option::Option<bitvec::index::BitIdx<u8>>, bitvec::index::BitEnd<u8>>
Line
Count
Source
730
52.4k
  fn new(
731
52.4k
    elem: Address<M, T>,
732
52.4k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
52.4k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
52.4k
  ) -> Self {
735
52.4k
    let (head, tail) = (
736
52.4k
      head.into().unwrap_or(BitIdx::MIN),
737
52.4k
      tail.into().unwrap_or(BitEnd::MAX),
738
52.4k
    );
739
52.4k
    Self {
740
52.4k
      elem,
741
52.4k
      mask: O::mask(head, tail),
742
52.4k
      head,
743
52.4k
      tail,
744
52.4k
      _ord: PhantomData,
745
52.4k
      _ref: PhantomData,
746
52.4k
    }
747
52.4k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::new::<_, _>
748
749
  /// Fetches the value stored through `self` and masks away extra bits.
750
  ///
751
  /// ## Returns
752
  ///
753
  /// A bit-map containing any bits set to `1` in the governed bits. All other
754
  /// bits are cleared to `0`.
755
  #[inline]
756
222k
  pub fn load_value(&self) -> T::Mem {
757
222k
    self.elem
758
222k
      .pipe(|addr| unsafe { &*addr.to_const() })
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::load_value::{closure#0}
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::load_value::{closure#0}
Line
Count
Source
758
222k
      .pipe(|addr| unsafe { &*addr.to_const() })
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::load_value::{closure#0}
759
222k
      .load_value()
760
222k
      & self.mask.into_inner()
761
222k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::load_value
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::load_value
Line
Count
Source
756
222k
  pub fn load_value(&self) -> T::Mem {
757
222k
    self.elem
758
222k
      .pipe(|addr| unsafe { &*addr.to_const() })
759
222k
      .load_value()
760
222k
      & self.mask.into_inner()
761
222k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::load_value
762
763
  /// Gets the starting index of the live bits in the element.
764
  #[inline]
765
  #[cfg(not(tarpaulin_include))]
766
0
  pub fn head(&self) -> BitIdx<T::Mem> {
767
0
    self.head
768
0
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::head
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::head
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Lsb0>>::head
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::head
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::head
769
770
  /// Gets the ending index of the live bits in the element.
771
  #[inline]
772
  #[cfg(not(tarpaulin_include))]
773
138k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
138k
    self.tail
775
138k
  }
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
773
86.5k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
86.5k
    self.tail
775
86.5k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
773
52.4k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
52.4k
    self.tail
775
52.4k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::tail
776
777
  /// Gets the semantic head and tail indices that constrain which bits of the
778
  /// referent element may be accessed.
779
  #[inline]
780
  #[cfg(not(tarpaulin_include))]
781
0
  pub fn bounds(&self) -> (BitIdx<T::Mem>, BitEnd<T::Mem>) {
782
0
    (self.head, self.tail)
783
0
  }
784
785
  /// Gets the bit-mask over all accessible bits.
786
  #[inline]
787
  #[cfg(not(tarpaulin_include))]
788
7.13k
  pub fn mask(&self) -> BitMask<T::Mem> {
789
7.13k
    self.mask
790
7.13k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::mask
Line
Count
Source
788
7.13k
  pub fn mask(&self) -> BitMask<T::Mem> {
789
7.13k
    self.mask
790
7.13k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::mask
791
792
  /// Converts the partial element into a bit-slice over its governed bits.
793
  #[inline]
794
0
  pub fn into_bitslice(self) -> Reference<'a, M, BitSlice<T, O>>
795
0
  where Address<M, BitSlice<T, O>>: Referential<'a> {
796
    unsafe {
797
0
      BitSpan::new_unchecked(
798
0
        self.elem,
799
0
        self.head,
800
0
        (self.tail.into_inner() - self.head.into_inner()) as usize,
801
      )
802
    }
803
0
    .to_bitslice()
804
0
  }
805
}
806
807
impl<'a, T, O> PartialElement<'a, Mut, T, O>
808
where
809
  T: BitStore,
810
  O: BitOrder,
811
  Address<Mut, T>: Referential<'a>,
812
{
813
  /// Stores a value through `self` after masking away extra bits.
814
  ///
815
  /// ## Parameters
816
  ///
817
  /// - `&mut self`
818
  /// - `value`: A bit-map which will be written into the governed bits. This
819
  ///   is a bit-map store, not an integer store; the value will not be
820
  ///   shifted into position and will only be masked directly against the
821
  ///   bits that this partial-element governs.
822
  ///
823
  /// ## Returns
824
  ///
825
  /// The previous value of the governed bits.
826
  #[inline]
827
250k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
828
250k
    let this = self.access();
829
250k
    let prev = this.clear_bits(self.mask);
830
250k
    this.set_bits(self.mask & value);
831
250k
    prev & self.mask.into_inner()
832
250k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::store_value
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::store_value
Line
Count
Source
827
250k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
828
250k
    let this = self.access();
829
250k
    let prev = this.clear_bits(self.mask);
830
250k
    this.set_bits(self.mask & value);
831
250k
    prev & self.mask.into_inner()
832
250k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, _, _>>::store_value
833
834
  /// Inverts the value of each bit governed by the partial-element.
835
  ///
836
  /// ## Returns
837
  ///
838
  /// The previous value of the governed bits.
839
  #[inline]
840
  #[cfg(not(tarpaulin_include))]
841
0
  pub fn invert(&mut self) -> T::Mem {
842
0
    self.access().invert_bits(self.mask) & self.mask.into_inner()
843
0
  }
844
845
  /// Clears all bits governed by the partial-element to `0`.
846
  ///
847
  /// ## Returns
848
  ///
849
  /// The previous value of the governed bits.
850
  #[inline]
851
  #[cfg(not(tarpaulin_include))]
852
0
  pub fn clear(&mut self) -> T::Mem {
853
0
    self.access().clear_bits(self.mask) & self.mask.into_inner()
854
0
  }
855
856
  /// Sets all bits governed by the partial-element to `1`.
857
  ///
858
  /// ## Returns
859
  ///
860
  /// The previous value of the governed bits.
861
  #[inline]
862
  #[cfg(not(tarpaulin_include))]
863
0
  pub fn set(&mut self) -> T::Mem {
864
0
    self.access().set_bits(self.mask) & self.mask.into_inner()
865
0
  }
866
867
  /// Produces a reference capable of tolerating other handles viewing the
868
  /// same *memory element*.
869
  #[inline]
870
250k
  fn access(&self) -> &T::Access {
871
250k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
872
250k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Lsb0>>::access
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::access
Line
Count
Source
870
250k
  fn access(&self) -> &T::Access {
871
250k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
872
250k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, _, _>>::access
873
}
874
875
impl<'a, M, T, O> PartialElement<'a, M, T, O>
876
where
877
  M: Mutability,
878
  O: BitOrder,
879
  T: 'a + BitStore + radium::Radium,
880
{
881
  /// Performs a store operation on a partial-element whose bits might be
882
  /// observed by another handle.
883
  #[inline]
884
0
  pub fn store_value_aliased(&self, value: T::Mem) -> T::Mem {
885
0
    let this = unsafe { &*self.elem.to_const().cast::<T::Access>() };
886
0
    let prev = this.clear_bits(self.mask);
887
0
    this.set_bits(self.mask & value);
888
0
    prev & self.mask.into_inner()
889
0
  }
890
}
891
892
#[cfg(not(tarpaulin_include))]
893
impl<'a, T, O> Clone for PartialElement<'a, Const, T, O>
894
where
895
  T: BitStore,
896
  O: BitOrder,
897
  Address<Const, T>: Referential<'a>,
898
{
899
  #[inline]
900
0
  fn clone(&self) -> Self {
901
0
    *self
902
0
  }
903
}
904
905
impl<'a, M, T, O> Debug for PartialElement<'a, M, T, O>
906
where
907
  M: Mutability,
908
  T: 'a + BitStore,
909
  O: BitOrder,
910
{
911
  #[inline]
912
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
913
0
    write!(
914
0
      fmt,
915
0
      "PartialElement<{} {}, {}>",
916
      M::RENDER,
917
0
      any::type_name::<T>(),
918
0
      any::type_name::<O>(),
919
0
    )?;
920
0
    fmt.debug_struct("")
921
0
      .field("elem", &self.load_value())
922
0
      .field("mask", &self.mask.fmt_display())
923
0
      .field("head", &self.head.fmt_display())
924
0
      .field("tail", &self.tail.fmt_display())
925
0
      .finish()
926
0
  }
927
}
928
929
#[cfg(not(tarpaulin_include))]
930
impl<'a, M, T, O> Hash for PartialElement<'a, M, T, O>
931
where
932
  M: Mutability,
933
  T: 'a + BitStore,
934
  O: BitOrder,
935
{
936
  #[inline]
937
0
  fn hash<H>(&self, hasher: &mut H)
938
0
  where H: Hasher {
939
0
    self.load_value().hash(hasher);
940
0
    self.mask.hash(hasher);
941
0
    self.head.hash(hasher);
942
0
    self.tail.hash(hasher);
943
0
  }
944
}
945
946
impl<T, O> Copy for PartialElement<'_, Const, T, O>
947
where
948
  T: BitStore,
949
  O: BitOrder,
950
{
951
}
952
953
#[cfg(test)]
954
mod tests {
955
  use rand::random;
956
957
  use super::*;
958
  use crate::prelude::*;
959
960
  #[test]
961
  fn bit_domain() {
962
    let data = BitArray::<[u32; 3], Msb0>::new(random());
963
964
    let bd = data.bit_domain();
965
    assert!(bd.enclave().is_none());
966
    let (head, body, tail) = bd.region().unwrap();
967
    assert_eq!(data, body);
968
    assert!(head.is_empty());
969
    assert!(tail.is_empty());
970
971
    let bd = data[2 ..].bit_domain();
972
    let (head, body, tail) = bd.region().unwrap();
973
    assert_eq!(head, &data[2 .. 32]);
974
    assert_eq!(body, &data[32 ..]);
975
    assert!(tail.is_empty());
976
977
    let bd = data[.. 94].bit_domain();
978
    let (head, body, tail) = bd.region().unwrap();
979
    assert!(head.is_empty());
980
    assert_eq!(body, &data[.. 64]);
981
    assert_eq!(tail, &data[64 .. 94]);
982
983
    let bd = data[2 .. 94].bit_domain();
984
    let (head, body, tail) = bd.region().unwrap();
985
    assert_eq!(head, &data[2 .. 32]);
986
    assert_eq!(body, &data[32 .. 64]);
987
    assert_eq!(tail, &data[64 .. 94]);
988
989
    let bd = data[34 .. 62].bit_domain();
990
    assert!(bd.region().is_none());
991
    assert_eq!(bd.enclave().unwrap(), data[34 .. 62]);
992
993
    let (head, body, tail) =
994
      BitDomain::<Const, usize, Lsb0>::default().region().unwrap();
995
    assert!(head.is_empty());
996
    assert!(body.is_empty());
997
    assert!(tail.is_empty());
998
  }
999
1000
  #[test]
1001
  fn domain() {
1002
    let data: [u32; 3] = random();
1003
    let bits = data.view_bits::<Msb0>();
1004
1005
    let d = bits.domain();
1006
    assert!(d.enclave().is_none());
1007
    let (head, body, tail) = d.region().unwrap();
1008
    assert!(head.is_none());
1009
    assert!(tail.is_none());
1010
    assert_eq!(body, data);
1011
1012
    let d = bits[2 ..].domain();
1013
    let (head, body, tail) = d.region().unwrap();
1014
    assert_eq!(head.unwrap().load_value(), (data[0] << 2) >> 2);
1015
    assert_eq!(body, &data[1 ..]);
1016
    assert!(tail.is_none());
1017
1018
    let d = bits[.. 94].domain();
1019
    let (head, body, tail) = d.region().unwrap();
1020
    assert!(head.is_none());
1021
    assert_eq!(body, &data[.. 2]);
1022
    assert_eq!(tail.unwrap().load_value(), (data[2] >> 2) << 2);
1023
1024
    let d = bits[2 .. 94].domain();
1025
    let (head, body, tail) = d.region().unwrap();
1026
    assert_eq!(head.unwrap().load_value(), (data[0] << 2) >> 2);
1027
    assert_eq!(body, &data[1 .. 2]);
1028
    assert_eq!(tail.unwrap().load_value(), (data[2] >> 2) << 2);
1029
1030
    let d = bits[34 .. 62].domain();
1031
    assert!(d.region().is_none());
1032
    assert_eq!(
1033
      d.enclave().unwrap().load_value(),
1034
      ((data[1] << 2) >> 4) << 2,
1035
    );
1036
1037
    assert!(matches!(bits![].domain(), Domain::Region {
1038
      head: None,
1039
      body: &[],
1040
      tail: None,
1041
    }));
1042
1043
    assert!(matches!(
1044
      Domain::<Const, usize, Lsb0>::default(),
1045
      Domain::Region {
1046
        head: None,
1047
        body: &[],
1048
        tail: None,
1049
      },
1050
    ));
1051
1052
    let data = core::cell::Cell::new(0u8);
1053
    let partial =
1054
      data.view_bits::<Lsb0>()[2 .. 6].domain().enclave().unwrap();
1055
    assert_eq!(partial.store_value_aliased(!0), 0);
1056
    assert_eq!(data.get(), 0b00_1111_00);
1057
  }
1058
1059
  #[test]
1060
  fn iter() {
1061
    let bits = [0x12u8, 0x34, 0x56].view_bits::<Lsb0>();
1062
    let mut domain = bits[4 .. 12].domain();
1063
    assert_eq!(domain.len(), 2);
1064
    assert_eq!(domain.next().unwrap(), 0x10);
1065
    assert_eq!(domain.next_back().unwrap(), 0x04);
1066
1067
    assert!(domain.next().is_none());
1068
    assert!(domain.next_back().is_none());
1069
1070
    assert_eq!(bits[2 .. 6].domain().len(), 1);
1071
    assert_eq!(bits[18 .. 22].domain().next_back().unwrap(), 0b00_0101_00);
1072
1073
    let mut domain = bits[4 .. 20].domain();
1074
    assert_eq!(domain.next_back().unwrap(), 0x06);
1075
    assert_eq!(domain.next_back().unwrap(), 0x34);
1076
    assert_eq!(domain.next_back().unwrap(), 0x10);
1077
  }
1078
1079
  #[test]
1080
  #[cfg(feature = "alloc")]
1081
  fn render() {
1082
    #[cfg(not(feature = "std"))]
1083
    use alloc::format;
1084
1085
    let data = BitArray::<u32, Msb0>::new(random());
1086
1087
    let render = format!("{:?}", data.bit_domain());
1088
    let expected = format!(
1089
      "BitDomain::<*const u32, {}>::Region {{ head: {:?}, body: {:?}, \
1090
       tail: {:?} }}",
1091
      any::type_name::<Msb0>(),
1092
      BitSlice::<u32, Msb0>::empty(),
1093
      data.as_bitslice(),
1094
      BitSlice::<u32, Msb0>::empty(),
1095
    );
1096
    assert_eq!(render, expected);
1097
1098
    let render = format!("{:?}", data[2 .. 30].bit_domain());
1099
    let expected = format!(
1100
      "BitDomain::<*const u32, {}>::Enclave({:?})",
1101
      any::type_name::<Msb0>(),
1102
      &data[2 .. 30],
1103
    );
1104
    assert_eq!(render, expected);
1105
1106
    let render = format!("{:?}", data.domain());
1107
    let expected = format!(
1108
      "Domain::<*const u32, {}>::Region {{ head: None, body: {:?}, tail: \
1109
       None }}",
1110
      any::type_name::<Msb0>(),
1111
      data.as_raw_slice(),
1112
    );
1113
    assert_eq!(render, expected);
1114
1115
    let render = format!("{:?}", data[2 .. 30].domain());
1116
    let expected = format!(
1117
      "Domain::<*const u32, {}>::Enclave",
1118
      any::type_name::<Msb0>(),
1119
    );
1120
    assert!(render.starts_with(&expected));
1121
1122
    let partial = 0x3Cu8.view_bits::<Lsb0>()[2 .. 6]
1123
      .domain()
1124
      .enclave()
1125
      .unwrap();
1126
    let render = format!("{:?}", partial);
1127
    assert_eq!(
1128
      render,
1129
      format!(
1130
        "PartialElement<*const u8, {}> {{ elem: 60, mask: {}, head: \
1131
         {}, tail: {} }}",
1132
        any::type_name::<Lsb0>(),
1133
        partial.mask,
1134
        partial.head,
1135
        partial.tail,
1136
      ),
1137
    );
1138
  }
1139
}