Coverage Report

Created: 2026-09-03 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitvec-1.1.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
this has to be spelled out explicitly in the trait bounds.
356
**/
357
impl<'a, M, T, O> Domain<'a, M, T, O>
358
where
359
  M: Mutability,
360
  T: 'a + BitStore,
361
  O: BitOrder,
362
  Address<M, T>: Referential<'a>,
363
  Address<M, [T::Unalias]>:
364
    SliceReferential<'a, ElementAddr = Address<M, T::Unalias>>,
365
  Address<M, BitSlice<T, O>>: Referential<'a>,
366
  Reference<'a, M, [T::Unalias]>: Default,
367
{
368
  /// Creates a new `Domain` over a bit-slice.
369
  ///
370
  /// ## Parameters
371
  ///
372
  /// - `bits`: Either a `&BitSlice` or `&mut BitSlice` reference, depending
373
  ///   on whether a `Domain<Const>` or `Domain<Mut>` is being produced.
374
  ///
375
  /// ## Returns
376
  ///
377
  /// A `Domain` description of the raw memory governed by `bits`.
378
488k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
379
488k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
380
488k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
381
488k
    let (head, elts, tail) =
382
488k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
383
488k
    let base = bitspan.address();
384
488k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
385
488k
    let ctor = match (head, elts, tail) {
386
0
      (_, 0, _) => Self::empty,
387
488k
      (h, _, t) if h == min && t == max => Self::spanning,
388
323k
      (_, _, t) if t == max => Self::partial_head,
389
139k
      (h, ..) if h == min => Self::partial_tail,
390
17.1k
      (_, 1, _) => Self::minor,
391
111k
      _ => Self::major,
392
    };
393
488k
    ctor(base, elts, head, tail)
394
488k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::new
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new
Line
Count
Source
378
268k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
379
268k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
380
268k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
381
268k
    let (head, elts, tail) =
382
268k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
383
268k
    let base = bitspan.address();
384
268k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
385
268k
    let ctor = match (head, elts, tail) {
386
0
      (_, 0, _) => Self::empty,
387
268k
      (h, _, t) if h == min && t == max => Self::spanning,
388
157k
      (_, _, t) if t == max => Self::partial_head,
389
80.2k
      (h, ..) if h == min => Self::partial_tail,
390
9.36k
      (_, 1, _) => Self::minor,
391
70.9k
      _ => Self::major,
392
    };
393
268k
    ctor(base, elts, head, tail)
394
268k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::new
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::new
Line
Count
Source
378
220k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
379
220k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
380
220k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
381
220k
    let (head, elts, tail) =
382
220k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
383
220k
    let base = bitspan.address();
384
220k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
385
220k
    let ctor = match (head, elts, tail) {
386
0
      (_, 0, _) => Self::empty,
387
220k
      (h, _, t) if h == min && t == max => Self::spanning,
388
165k
      (_, _, t) if t == max => Self::partial_head,
389
58.7k
      (h, ..) if h == min => Self::partial_tail,
390
7.83k
      (_, 1, _) => Self::minor,
391
40.6k
      _ => Self::major,
392
    };
393
220k
    ctor(base, elts, head, tail)
394
220k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::new
395
396
  /// Produces the canonical empty `Domain`.
397
  #[inline]
398
0
  fn empty(
399
0
    _: Address<M, T>,
400
0
    _: usize,
401
0
    _: BitIdx<T::Mem>,
402
0
    _: BitEnd<T::Mem>,
403
0
  ) -> Self {
404
0
    Default::default()
405
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
406
407
  /// Produces a `Domain::Region` that contains both `head` and `tail` partial
408
  /// elements as well as a `body` slice (which may be empty).
409
  #[inline]
410
111k
  fn major(
411
111k
    addr: Address<M, T>,
412
111k
    elts: usize,
413
111k
    head: BitIdx<T::Mem>,
414
111k
    tail: BitEnd<T::Mem>,
415
111k
  ) -> Self {
416
111k
    let h_elem = addr;
417
111k
    let t_elem = unsafe { addr.add(elts - 1) };
418
111k
    let body = unsafe {
419
111k
      Address::<M, [T::Unalias]>::from_raw_parts(
420
111k
        addr.add(1).cast::<T::Unalias>(),
421
111k
        elts - 2,
422
      )
423
    };
424
111k
    Self::Region {
425
111k
      head: Some(PartialElement::new(h_elem, head, None)),
426
111k
      body,
427
111k
      tail: Some(PartialElement::new(t_elem, None, tail)),
428
111k
    }
429
111k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::major
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::major
Line
Count
Source
410
70.9k
  fn major(
411
70.9k
    addr: Address<M, T>,
412
70.9k
    elts: usize,
413
70.9k
    head: BitIdx<T::Mem>,
414
70.9k
    tail: BitEnd<T::Mem>,
415
70.9k
  ) -> Self {
416
70.9k
    let h_elem = addr;
417
70.9k
    let t_elem = unsafe { addr.add(elts - 1) };
418
70.9k
    let body = unsafe {
419
70.9k
      Address::<M, [T::Unalias]>::from_raw_parts(
420
70.9k
        addr.add(1).cast::<T::Unalias>(),
421
70.9k
        elts - 2,
422
      )
423
    };
424
70.9k
    Self::Region {
425
70.9k
      head: Some(PartialElement::new(h_elem, head, None)),
426
70.9k
      body,
427
70.9k
      tail: Some(PartialElement::new(t_elem, None, tail)),
428
70.9k
    }
429
70.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
410
40.6k
  fn major(
411
40.6k
    addr: Address<M, T>,
412
40.6k
    elts: usize,
413
40.6k
    head: BitIdx<T::Mem>,
414
40.6k
    tail: BitEnd<T::Mem>,
415
40.6k
  ) -> Self {
416
40.6k
    let h_elem = addr;
417
40.6k
    let t_elem = unsafe { addr.add(elts - 1) };
418
40.6k
    let body = unsafe {
419
40.6k
      Address::<M, [T::Unalias]>::from_raw_parts(
420
40.6k
        addr.add(1).cast::<T::Unalias>(),
421
40.6k
        elts - 2,
422
      )
423
    };
424
40.6k
    Self::Region {
425
40.6k
      head: Some(PartialElement::new(h_elem, head, None)),
426
40.6k
      body,
427
40.6k
      tail: Some(PartialElement::new(t_elem, None, tail)),
428
40.6k
    }
429
40.6k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::major
430
431
  /// Produces a `Domain::Enclave`.
432
  #[inline]
433
17.1k
  fn minor(
434
17.1k
    addr: Address<M, T>,
435
17.1k
    _: usize,
436
17.1k
    head: BitIdx<T::Mem>,
437
17.1k
    tail: BitEnd<T::Mem>,
438
17.1k
  ) -> Self {
439
17.1k
    let elem = addr;
440
17.1k
    Self::Enclave(PartialElement::new(elem, head, tail))
441
17.1k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::minor
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::minor
Line
Count
Source
433
9.36k
  fn minor(
434
9.36k
    addr: Address<M, T>,
435
9.36k
    _: usize,
436
9.36k
    head: BitIdx<T::Mem>,
437
9.36k
    tail: BitEnd<T::Mem>,
438
9.36k
  ) -> Self {
439
9.36k
    let elem = addr;
440
9.36k
    Self::Enclave(PartialElement::new(elem, head, tail))
441
9.36k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::minor
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::minor
Line
Count
Source
433
7.83k
  fn minor(
434
7.83k
    addr: Address<M, T>,
435
7.83k
    _: usize,
436
7.83k
    head: BitIdx<T::Mem>,
437
7.83k
    tail: BitEnd<T::Mem>,
438
7.83k
  ) -> Self {
439
7.83k
    let elem = addr;
440
7.83k
    Self::Enclave(PartialElement::new(elem, head, tail))
441
7.83k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::minor
442
443
  /// Produces a `Domain::Region` with a partial `head` and a `body`, but no
444
  /// `tail`.
445
  #[inline]
446
184k
  fn partial_head(
447
184k
    addr: Address<M, T>,
448
184k
    elts: usize,
449
184k
    head: BitIdx<T::Mem>,
450
184k
    _: BitEnd<T::Mem>,
451
184k
  ) -> Self {
452
184k
    let elem = addr;
453
184k
    let body = unsafe {
454
184k
      Address::<M, [T::Unalias]>::from_raw_parts(
455
184k
        addr.add(1).cast::<T::Unalias>(),
456
184k
        elts - 1,
457
      )
458
    };
459
184k
    Self::Region {
460
184k
      head: Some(PartialElement::new(elem, head, None)),
461
184k
      body,
462
184k
      tail: None,
463
184k
    }
464
184k
  }
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
446
77.4k
  fn partial_head(
447
77.4k
    addr: Address<M, T>,
448
77.4k
    elts: usize,
449
77.4k
    head: BitIdx<T::Mem>,
450
77.4k
    _: BitEnd<T::Mem>,
451
77.4k
  ) -> Self {
452
77.4k
    let elem = addr;
453
77.4k
    let body = unsafe {
454
77.4k
      Address::<M, [T::Unalias]>::from_raw_parts(
455
77.4k
        addr.add(1).cast::<T::Unalias>(),
456
77.4k
        elts - 1,
457
      )
458
    };
459
77.4k
    Self::Region {
460
77.4k
      head: Some(PartialElement::new(elem, head, None)),
461
77.4k
      body,
462
77.4k
      tail: None,
463
77.4k
    }
464
77.4k
  }
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
446
106k
  fn partial_head(
447
106k
    addr: Address<M, T>,
448
106k
    elts: usize,
449
106k
    head: BitIdx<T::Mem>,
450
106k
    _: BitEnd<T::Mem>,
451
106k
  ) -> Self {
452
106k
    let elem = addr;
453
106k
    let body = unsafe {
454
106k
      Address::<M, [T::Unalias]>::from_raw_parts(
455
106k
        addr.add(1).cast::<T::Unalias>(),
456
106k
        elts - 1,
457
      )
458
    };
459
106k
    Self::Region {
460
106k
      head: Some(PartialElement::new(elem, head, None)),
461
106k
      body,
462
106k
      tail: None,
463
106k
    }
464
106k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::partial_head
465
466
  /// Produces a `Domain::Region` with a partial `tail` and a `body`, but no
467
  /// `head`.
468
  #[inline]
469
10.3k
  fn partial_tail(
470
10.3k
    addr: Address<M, T>,
471
10.3k
    elts: usize,
472
10.3k
    _: BitIdx<T::Mem>,
473
10.3k
    tail: BitEnd<T::Mem>,
474
10.3k
  ) -> Self {
475
10.3k
    let elem = unsafe { addr.add(elts - 1) };
476
10.3k
    let body = unsafe {
477
10.3k
      Address::<M, [T::Unalias]>::from_raw_parts(
478
10.3k
        addr.cast::<T::Unalias>(),
479
10.3k
        elts - 1,
480
      )
481
    };
482
10.3k
    Self::Region {
483
10.3k
      head: None,
484
10.3k
      body,
485
10.3k
      tail: Some(PartialElement::new(elem, None, tail)),
486
10.3k
    }
487
10.3k
  }
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
469
10.3k
  fn partial_tail(
470
10.3k
    addr: Address<M, T>,
471
10.3k
    elts: usize,
472
10.3k
    _: BitIdx<T::Mem>,
473
10.3k
    tail: BitEnd<T::Mem>,
474
10.3k
  ) -> Self {
475
10.3k
    let elem = unsafe { addr.add(elts - 1) };
476
10.3k
    let body = unsafe {
477
10.3k
      Address::<M, [T::Unalias]>::from_raw_parts(
478
10.3k
        addr.cast::<T::Unalias>(),
479
10.3k
        elts - 1,
480
      )
481
    };
482
10.3k
    Self::Region {
483
10.3k
      head: None,
484
10.3k
      body,
485
10.3k
      tail: Some(PartialElement::new(elem, None, tail)),
486
10.3k
    }
487
10.3k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::partial_tail
488
489
  /// Produces a `Domain::Region` with neither `head` nor `tail`, but only a
490
  /// `body`.
491
  #[inline]
492
165k
  fn spanning(
493
165k
    addr: Address<M, T>,
494
165k
    elts: usize,
495
165k
    _: BitIdx<T::Mem>,
496
165k
    _: BitEnd<T::Mem>,
497
165k
  ) -> Self {
498
165k
    Self::Region {
499
165k
      head: None,
500
165k
      body: unsafe {
501
165k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
502
165k
          addr.cast::<T::Unalias>(),
503
165k
          elts,
504
165k
        )
505
165k
      },
506
165k
      tail: None,
507
165k
    }
508
165k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Mut, u8>>::spanning
<bitvec::domain::Domain<wyz::comu::Mut, u8, bitvec::order::Msb0>>::spanning
Line
Count
Source
492
110k
  fn spanning(
493
110k
    addr: Address<M, T>,
494
110k
    elts: usize,
495
110k
    _: BitIdx<T::Mem>,
496
110k
    _: BitEnd<T::Mem>,
497
110k
  ) -> Self {
498
110k
    Self::Region {
499
110k
      head: None,
500
110k
      body: unsafe {
501
110k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
502
110k
          addr.cast::<T::Unalias>(),
503
110k
          elts,
504
110k
        )
505
110k
      },
506
110k
      tail: None,
507
110k
    }
508
110k
  }
Unexecuted instantiation: <bitvec::domain::Domain<wyz::comu::Const, u8>>::spanning
<bitvec::domain::Domain<wyz::comu::Const, u8, bitvec::order::Msb0>>::spanning
Line
Count
Source
492
55.0k
  fn spanning(
493
55.0k
    addr: Address<M, T>,
494
55.0k
    elts: usize,
495
55.0k
    _: BitIdx<T::Mem>,
496
55.0k
    _: BitEnd<T::Mem>,
497
55.0k
  ) -> Self {
498
55.0k
    Self::Region {
499
55.0k
      head: None,
500
55.0k
      body: unsafe {
501
55.0k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
502
55.0k
          addr.cast::<T::Unalias>(),
503
55.0k
          elts,
504
55.0k
        )
505
55.0k
      },
506
55.0k
      tail: None,
507
55.0k
    }
508
55.0k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::spanning
509
}
510
511
impl<'a, M, T, O> Default for Domain<'a, M, T, O>
512
where
513
  M: Mutability,
514
  T: 'a + BitStore,
515
  O: BitOrder,
516
  Address<M, T>: Referential<'a>,
517
  Address<M, [T::Unalias]>: SliceReferential<'a>,
518
  Reference<'a, M, [T::Unalias]>: Default,
519
{
520
  #[inline]
521
0
  fn default() -> Self {
522
0
    Self::Region {
523
0
      head: None,
524
0
      body: Reference::<M, [T::Unalias]>::default(),
525
0
      tail: None,
526
0
    }
527
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
528
}
529
530
impl<'a, M, T, O> Debug for Domain<'a, M, T, O>
531
where
532
  M: Mutability,
533
  T: 'a + BitStore,
534
  O: BitOrder,
535
  Address<M, T>: Referential<'a>,
536
  Address<M, [T::Unalias]>: SliceReferential<'a>,
537
  Reference<'a, M, [T::Unalias]>: Debug,
538
{
539
  #[inline]
540
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
541
0
    write!(
542
0
      fmt,
543
0
      "Domain::<{} {}, {}>::",
544
      M::RENDER,
545
0
      any::type_name::<T>(),
546
0
      any::type_name::<O>(),
547
0
    )?;
548
0
    match self {
549
0
      Self::Enclave(elem) => {
550
0
        fmt.debug_tuple("Enclave").field(elem).finish()
551
      },
552
0
      Self::Region { head, body, tail } => fmt
553
0
        .debug_struct("Region")
554
0
        .field("head", head)
555
0
        .field("body", body)
556
0
        .field("tail", tail)
557
0
        .finish(),
558
    }
559
0
  }
560
}
561
562
#[cfg(not(tarpaulin_include))]
563
impl<T, O> Clone for Domain<'_, Const, T, O>
564
where
565
  T: BitStore,
566
  O: BitOrder,
567
{
568
  #[inline]
569
0
  fn clone(&self) -> Self {
570
0
    *self
571
0
  }
572
}
573
574
impl<T, O> Iterator for Domain<'_, Const, T, O>
575
where
576
  T: BitStore,
577
  O: BitOrder,
578
{
579
  type Item = T::Mem;
580
581
  #[inline]
582
0
  fn next(&mut self) -> Option<Self::Item> {
583
0
    match self {
584
0
      Self::Enclave(elem) => {
585
0
        elem.load_value().tap(|_| *self = Default::default()).into()
586
      },
587
0
      Self::Region { head, body, tail } => {
588
0
        if let Some(elem) = head.take() {
589
0
          return elem.load_value().into();
590
0
        }
591
0
        if let Some((elem, rest)) = body.split_first() {
592
0
          *body = rest;
593
0
          return elem.load_value().into();
594
0
        }
595
0
        if let Some(elem) = tail.take() {
596
0
          return elem.load_value().into();
597
0
        }
598
0
        None
599
      },
600
    }
601
0
  }
602
}
603
604
impl<T, O> DoubleEndedIterator for Domain<'_, Const, T, O>
605
where
606
  T: BitStore,
607
  O: BitOrder,
608
{
609
  #[inline]
610
0
  fn next_back(&mut self) -> Option<Self::Item> {
611
0
    match self {
612
0
      Self::Enclave(elem) => {
613
0
        elem.load_value().tap(|_| *self = Default::default()).into()
614
      },
615
0
      Self::Region { head, body, tail } => {
616
0
        if let Some(elem) = tail.take() {
617
0
          return elem.load_value().into();
618
0
        }
619
0
        if let Some((elem, rest)) = body.split_last() {
620
0
          *body = rest;
621
0
          return elem.load_value().into();
622
0
        }
623
0
        if let Some(elem) = head.take() {
624
0
          return elem.load_value().into();
625
0
        }
626
0
        None
627
      },
628
    }
629
0
  }
630
}
631
632
impl<T, O> ExactSizeIterator for Domain<'_, Const, T, O>
633
where
634
  T: BitStore,
635
  O: BitOrder,
636
{
637
  #[inline]
638
0
  fn len(&self) -> usize {
639
0
    match self {
640
0
      Self::Enclave(_) => 1,
641
0
      Self::Region { head, body, tail } => {
642
0
        head.is_some() as usize + body.len() + tail.is_some() as usize
643
      },
644
    }
645
0
  }
646
}
647
648
impl<T, O> FusedIterator for Domain<'_, Const, T, O>
649
where
650
  T: BitStore,
651
  O: BitOrder,
652
{
653
}
654
655
impl<T, O> Copy for Domain<'_, Const, T, O>
656
where
657
  T: BitStore,
658
  O: BitOrder,
659
{
660
}
661
662
/// Implements numeric formatting by rendering each element.
663
macro_rules! fmt {
664
  ($($fmt:ty => $fwd:ident),+ $(,)?) => { $(
665
    impl<'a, T, O> $fmt for Domain<'a, Const, T, O>
666
    where
667
      O: BitOrder,
668
      T: BitStore,
669
    {
670
      #[inline]
671
0
      fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
672
0
        fmt.debug_list()
673
0
          .entries(self.into_iter().map(FmtForward::$fwd))
674
0
          .finish()
675
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
676
    }
677
  )+ };
678
}
679
680
fmt! {
681
  Binary => fmt_binary,
682
  Display => fmt_display,
683
  LowerHex => fmt_lower_hex,
684
  Octal => fmt_octal,
685
  UpperHex => fmt_upper_hex,
686
}
687
688
#[doc = include_str!("../doc/domain/PartialElement.md")]
689
pub struct PartialElement<'a, M, T, O>
690
where
691
  M: Mutability,
692
  T: 'a + BitStore,
693
  O: BitOrder,
694
{
695
  /// The address of the memory element being partially viewed.
696
  ///
697
  /// This must be stored as a pointer, not a reference, because it must
698
  /// retain mutability permissions but cannot have an `&mut` reference to
699
  /// a shared element.
700
  ///
701
  /// Similarly, it must remain typed as `T`, not `T::Access`, to allow the
702
  /// `<Const, uN>` case not to inappropriately produce a `<Const, Cell<uN>>`
703
  /// even if no write is performed.
704
  elem: Address<M, T>,
705
  /// Cache the selector mask, so it never needs to be recomputed.
706
  mask: BitMask<T::Mem>,
707
  /// The starting index.
708
  head: BitIdx<T::Mem>,
709
  /// The ending index.
710
  tail: BitEnd<T::Mem>,
711
  /// Preserve the originating bit-order
712
  _ord: PhantomData<O>,
713
  /// This type acts as-if it were a shared-mutable reference.
714
  _ref: PhantomData<&'a T::Access>,
715
}
716
717
impl<'a, M, T, O> PartialElement<'a, M, T, O>
718
where
719
  M: Mutability,
720
  T: 'a + BitStore,
721
  O: BitOrder,
722
{
723
  /// Constructs a new partial-element guarded reference.
724
  ///
725
  /// ## Parameters
726
  ///
727
  /// - `elem`: the element to which this partially points.
728
  /// - `head`: the index at which the partial region begins.
729
  /// - `tail`: the index at which the partial region ends.
730
  #[inline]
731
434k
  fn new(
732
434k
    elem: Address<M, T>,
733
434k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
434k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
434k
  ) -> Self {
736
434k
    let (head, tail) = (
737
434k
      head.into().unwrap_or(BitIdx::MIN),
738
434k
      tail.into().unwrap_or(BitEnd::MAX),
739
434k
    );
740
434k
    Self {
741
434k
      elem,
742
434k
      mask: O::mask(head, tail),
743
434k
      head,
744
434k
      tail,
745
434k
      _ord: PhantomData,
746
434k
      _ref: PhantomData,
747
434k
    }
748
434k
  }
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
731
9.36k
  fn new(
732
9.36k
    elem: Address<M, T>,
733
9.36k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
9.36k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
9.36k
  ) -> Self {
736
9.36k
    let (head, tail) = (
737
9.36k
      head.into().unwrap_or(BitIdx::MIN),
738
9.36k
      tail.into().unwrap_or(BitEnd::MAX),
739
9.36k
    );
740
9.36k
    Self {
741
9.36k
      elem,
742
9.36k
      mask: O::mask(head, tail),
743
9.36k
      head,
744
9.36k
      tail,
745
9.36k
      _ord: PhantomData,
746
9.36k
      _ref: PhantomData,
747
9.36k
    }
748
9.36k
  }
<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
731
148k
  fn new(
732
148k
    elem: Address<M, T>,
733
148k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
148k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
148k
  ) -> Self {
736
148k
    let (head, tail) = (
737
148k
      head.into().unwrap_or(BitIdx::MIN),
738
148k
      tail.into().unwrap_or(BitEnd::MAX),
739
148k
    );
740
148k
    Self {
741
148k
      elem,
742
148k
      mask: O::mask(head, tail),
743
148k
      head,
744
148k
      tail,
745
148k
      _ord: PhantomData,
746
148k
      _ref: PhantomData,
747
148k
    }
748
148k
  }
<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
731
70.9k
  fn new(
732
70.9k
    elem: Address<M, T>,
733
70.9k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
70.9k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
70.9k
  ) -> Self {
736
70.9k
    let (head, tail) = (
737
70.9k
      head.into().unwrap_or(BitIdx::MIN),
738
70.9k
      tail.into().unwrap_or(BitEnd::MAX),
739
70.9k
    );
740
70.9k
    Self {
741
70.9k
      elem,
742
70.9k
      mask: O::mask(head, tail),
743
70.9k
      head,
744
70.9k
      tail,
745
70.9k
      _ord: PhantomData,
746
70.9k
      _ref: PhantomData,
747
70.9k
    }
748
70.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
731
7.83k
  fn new(
732
7.83k
    elem: Address<M, T>,
733
7.83k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
7.83k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
7.83k
  ) -> Self {
736
7.83k
    let (head, tail) = (
737
7.83k
      head.into().unwrap_or(BitIdx::MIN),
738
7.83k
      tail.into().unwrap_or(BitEnd::MAX),
739
7.83k
    );
740
7.83k
    Self {
741
7.83k
      elem,
742
7.83k
      mask: O::mask(head, tail),
743
7.83k
      head,
744
7.83k
      tail,
745
7.83k
      _ord: PhantomData,
746
7.83k
      _ref: PhantomData,
747
7.83k
    }
748
7.83k
  }
<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
731
147k
  fn new(
732
147k
    elem: Address<M, T>,
733
147k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
147k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
147k
  ) -> Self {
736
147k
    let (head, tail) = (
737
147k
      head.into().unwrap_or(BitIdx::MIN),
738
147k
      tail.into().unwrap_or(BitEnd::MAX),
739
147k
    );
740
147k
    Self {
741
147k
      elem,
742
147k
      mask: O::mask(head, tail),
743
147k
      head,
744
147k
      tail,
745
147k
      _ord: PhantomData,
746
147k
      _ref: PhantomData,
747
147k
    }
748
147k
  }
<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
731
50.9k
  fn new(
732
50.9k
    elem: Address<M, T>,
733
50.9k
    head: impl Into<Option<BitIdx<T::Mem>>>,
734
50.9k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
735
50.9k
  ) -> Self {
736
50.9k
    let (head, tail) = (
737
50.9k
      head.into().unwrap_or(BitIdx::MIN),
738
50.9k
      tail.into().unwrap_or(BitEnd::MAX),
739
50.9k
    );
740
50.9k
    Self {
741
50.9k
      elem,
742
50.9k
      mask: O::mask(head, tail),
743
50.9k
      head,
744
50.9k
      tail,
745
50.9k
      _ord: PhantomData,
746
50.9k
      _ref: PhantomData,
747
50.9k
    }
748
50.9k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::new::<_, _>
749
750
  /// Fetches the value stored through `self` and masks away extra bits.
751
  ///
752
  /// ## Returns
753
  ///
754
  /// A bit-map containing any bits set to `1` in the governed bits. All other
755
  /// bits are cleared to `0`.
756
  #[inline]
757
206k
  pub fn load_value(&self) -> T::Mem {
758
206k
    self.elem
759
206k
      .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
759
206k
      .pipe(|addr| unsafe { &*addr.to_const() })
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::load_value::{closure#0}
760
206k
      .load_value()
761
206k
      & self.mask.into_inner()
762
206k
  }
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
757
206k
  pub fn load_value(&self) -> T::Mem {
758
206k
    self.elem
759
206k
      .pipe(|addr| unsafe { &*addr.to_const() })
760
206k
      .load_value()
761
206k
      & self.mask.into_inner()
762
206k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::load_value
763
764
  /// Gets the starting index of the live bits in the element.
765
  #[inline]
766
  #[cfg(not(tarpaulin_include))]
767
0
  pub fn head(&self) -> BitIdx<T::Mem> {
768
0
    self.head
769
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
770
771
  /// Gets the ending index of the live bits in the element.
772
  #[inline]
773
  #[cfg(not(tarpaulin_include))]
774
131k
  pub fn tail(&self) -> BitEnd<T::Mem> {
775
131k
    self.tail
776
131k
  }
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
774
80.2k
  pub fn tail(&self) -> BitEnd<T::Mem> {
775
80.2k
    self.tail
776
80.2k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
774
50.9k
  pub fn tail(&self) -> BitEnd<T::Mem> {
775
50.9k
    self.tail
776
50.9k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::tail
777
778
  /// Gets the semantic head and tail indices that constrain which bits of the
779
  /// referent element may be accessed.
780
  #[inline]
781
  #[cfg(not(tarpaulin_include))]
782
0
  pub fn bounds(&self) -> (BitIdx<T::Mem>, BitEnd<T::Mem>) {
783
0
    (self.head, self.tail)
784
0
  }
785
786
  /// Gets the bit-mask over all accessible bits.
787
  #[inline]
788
  #[cfg(not(tarpaulin_include))]
789
7.83k
  pub fn mask(&self) -> BitMask<T::Mem> {
790
7.83k
    self.mask
791
7.83k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::mask
Line
Count
Source
789
7.83k
  pub fn mask(&self) -> BitMask<T::Mem> {
790
7.83k
    self.mask
791
7.83k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::mask
792
793
  /// Converts the partial element into a bit-slice over its governed bits.
794
  #[inline]
795
0
  pub fn into_bitslice(self) -> Reference<'a, M, BitSlice<T, O>>
796
0
  where Address<M, BitSlice<T, O>>: Referential<'a> {
797
    unsafe {
798
0
      BitSpan::new_unchecked(
799
0
        self.elem,
800
0
        self.head,
801
0
        (self.tail.into_inner() - self.head.into_inner()) as usize,
802
      )
803
    }
804
0
    .to_bitslice()
805
0
  }
806
}
807
808
impl<'a, T, O> PartialElement<'a, Mut, T, O>
809
where
810
  T: BitStore,
811
  O: BitOrder,
812
  Address<Mut, T>: Referential<'a>,
813
{
814
  /// Stores a value through `self` after masking away extra bits.
815
  ///
816
  /// ## Parameters
817
  ///
818
  /// - `&mut self`
819
  /// - `value`: A bit-map which will be written into the governed bits. This
820
  ///   is a bit-map store, not an integer store; the value will not be
821
  ///   shifted into position and will only be masked directly against the
822
  ///   bits that this partial-element governs.
823
  ///
824
  /// ## Returns
825
  ///
826
  /// The previous value of the governed bits.
827
  #[inline]
828
228k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
829
228k
    let this = self.access();
830
228k
    let prev = this.clear_bits(self.mask);
831
228k
    this.set_bits(self.mask & value);
832
228k
    prev & self.mask.into_inner()
833
228k
  }
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
828
228k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
829
228k
    let this = self.access();
830
228k
    let prev = this.clear_bits(self.mask);
831
228k
    this.set_bits(self.mask & value);
832
228k
    prev & self.mask.into_inner()
833
228k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, _, _>>::store_value
834
835
  /// Inverts the value of each bit governed by the partial-element.
836
  ///
837
  /// ## Returns
838
  ///
839
  /// The previous value of the governed bits.
840
  #[inline]
841
  #[cfg(not(tarpaulin_include))]
842
0
  pub fn invert(&mut self) -> T::Mem {
843
0
    self.access().invert_bits(self.mask) & self.mask.into_inner()
844
0
  }
845
846
  /// Clears all bits governed by the partial-element to `0`.
847
  ///
848
  /// ## Returns
849
  ///
850
  /// The previous value of the governed bits.
851
  #[inline]
852
  #[cfg(not(tarpaulin_include))]
853
0
  pub fn clear(&mut self) -> T::Mem {
854
0
    self.access().clear_bits(self.mask) & self.mask.into_inner()
855
0
  }
856
857
  /// Sets all bits governed by the partial-element to `1`.
858
  ///
859
  /// ## Returns
860
  ///
861
  /// The previous value of the governed bits.
862
  #[inline]
863
  #[cfg(not(tarpaulin_include))]
864
0
  pub fn set(&mut self) -> T::Mem {
865
0
    self.access().set_bits(self.mask) & self.mask.into_inner()
866
0
  }
867
868
  /// Produces a reference capable of tolerating other handles viewing the
869
  /// same *memory element*.
870
  #[inline]
871
228k
  fn access(&self) -> &T::Access {
872
228k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
873
228k
  }
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
871
228k
  fn access(&self) -> &T::Access {
872
228k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
873
228k
  }
Unexecuted instantiation: <bitvec::domain::PartialElement<wyz::comu::Mut, _, _>>::access
874
}
875
876
impl<'a, M, T, O> PartialElement<'a, M, T, O>
877
where
878
  M: Mutability,
879
  O: BitOrder,
880
  T: 'a + BitStore + radium::Radium,
881
{
882
  /// Performs a store operation on a partial-element whose bits might be
883
  /// observed by another handle.
884
  #[inline]
885
0
  pub fn store_value_aliased(&self, value: T::Mem) -> T::Mem {
886
0
    let this = unsafe { &*self.elem.to_const().cast::<T::Access>() };
887
0
    let prev = this.clear_bits(self.mask);
888
0
    this.set_bits(self.mask & value);
889
0
    prev & self.mask.into_inner()
890
0
  }
891
}
892
893
#[cfg(not(tarpaulin_include))]
894
impl<'a, T, O> Clone for PartialElement<'a, Const, T, O>
895
where
896
  T: BitStore,
897
  O: BitOrder,
898
  Address<Const, T>: Referential<'a>,
899
{
900
  #[inline]
901
0
  fn clone(&self) -> Self {
902
0
    *self
903
0
  }
904
}
905
906
impl<'a, M, T, O> Debug for PartialElement<'a, M, T, O>
907
where
908
  M: Mutability,
909
  T: 'a + BitStore,
910
  O: BitOrder,
911
{
912
  #[inline]
913
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
914
0
    write!(
915
0
      fmt,
916
0
      "PartialElement<{} {}, {}>",
917
      M::RENDER,
918
0
      any::type_name::<T>(),
919
0
      any::type_name::<O>(),
920
0
    )?;
921
0
    fmt.debug_struct("")
922
0
      .field("elem", &self.load_value())
923
0
      .field("mask", &self.mask.fmt_display())
924
0
      .field("head", &self.head.fmt_display())
925
0
      .field("tail", &self.tail.fmt_display())
926
0
      .finish()
927
0
  }
928
}
929
930
#[cfg(not(tarpaulin_include))]
931
impl<'a, M, T, O> Hash for PartialElement<'a, M, T, O>
932
where
933
  M: Mutability,
934
  T: 'a + BitStore,
935
  O: BitOrder,
936
{
937
  #[inline]
938
0
  fn hash<H>(&self, hasher: &mut H)
939
0
  where H: Hasher {
940
0
    self.load_value().hash(hasher);
941
0
    self.mask.hash(hasher);
942
0
    self.head.hash(hasher);
943
0
    self.tail.hash(hasher);
944
0
  }
945
}
946
947
impl<T, O> Copy for PartialElement<'_, Const, T, O>
948
where
949
  T: BitStore,
950
  O: BitOrder,
951
{
952
}
953
954
#[cfg(test)]
955
mod tests {
956
  use rand::random;
957
958
  use super::*;
959
  use crate::prelude::*;
960
961
  #[test]
962
  fn bit_domain() {
963
    let data = BitArray::<[u32; 3], Msb0>::new(random());
964
965
    let bd = data.bit_domain();
966
    assert!(bd.enclave().is_none());
967
    let (head, body, tail) = bd.region().unwrap();
968
    assert_eq!(data, body);
969
    assert!(head.is_empty());
970
    assert!(tail.is_empty());
971
972
    let bd = data[2 ..].bit_domain();
973
    let (head, body, tail) = bd.region().unwrap();
974
    assert_eq!(head, &data[2 .. 32]);
975
    assert_eq!(body, &data[32 ..]);
976
    assert!(tail.is_empty());
977
978
    let bd = data[.. 94].bit_domain();
979
    let (head, body, tail) = bd.region().unwrap();
980
    assert!(head.is_empty());
981
    assert_eq!(body, &data[.. 64]);
982
    assert_eq!(tail, &data[64 .. 94]);
983
984
    let bd = data[2 .. 94].bit_domain();
985
    let (head, body, tail) = bd.region().unwrap();
986
    assert_eq!(head, &data[2 .. 32]);
987
    assert_eq!(body, &data[32 .. 64]);
988
    assert_eq!(tail, &data[64 .. 94]);
989
990
    let bd = data[34 .. 62].bit_domain();
991
    assert!(bd.region().is_none());
992
    assert_eq!(bd.enclave().unwrap(), data[34 .. 62]);
993
994
    let (head, body, tail) =
995
      BitDomain::<Const, usize, Lsb0>::default().region().unwrap();
996
    assert!(head.is_empty());
997
    assert!(body.is_empty());
998
    assert!(tail.is_empty());
999
  }
1000
1001
  #[test]
1002
  fn domain() {
1003
    let data: [u32; 3] = random();
1004
    let bits = data.view_bits::<Msb0>();
1005
1006
    let d = bits.domain();
1007
    assert!(d.enclave().is_none());
1008
    let (head, body, tail) = d.region().unwrap();
1009
    assert!(head.is_none());
1010
    assert!(tail.is_none());
1011
    assert_eq!(body, data);
1012
1013
    let d = bits[2 ..].domain();
1014
    let (head, body, tail) = d.region().unwrap();
1015
    assert_eq!(head.unwrap().load_value(), (data[0] << 2) >> 2);
1016
    assert_eq!(body, &data[1 ..]);
1017
    assert!(tail.is_none());
1018
1019
    let d = bits[.. 94].domain();
1020
    let (head, body, tail) = d.region().unwrap();
1021
    assert!(head.is_none());
1022
    assert_eq!(body, &data[.. 2]);
1023
    assert_eq!(tail.unwrap().load_value(), (data[2] >> 2) << 2);
1024
1025
    let d = bits[2 .. 94].domain();
1026
    let (head, body, tail) = d.region().unwrap();
1027
    assert_eq!(head.unwrap().load_value(), (data[0] << 2) >> 2);
1028
    assert_eq!(body, &data[1 .. 2]);
1029
    assert_eq!(tail.unwrap().load_value(), (data[2] >> 2) << 2);
1030
1031
    let d = bits[34 .. 62].domain();
1032
    assert!(d.region().is_none());
1033
    assert_eq!(
1034
      d.enclave().unwrap().load_value(),
1035
      ((data[1] << 2) >> 4) << 2,
1036
    );
1037
1038
    assert!(matches!(bits![].domain(), Domain::Region {
1039
      head: None,
1040
      body: &[],
1041
      tail: None,
1042
    }));
1043
1044
    assert!(matches!(
1045
      Domain::<Const, usize, Lsb0>::default(),
1046
      Domain::Region {
1047
        head: None,
1048
        body: &[],
1049
        tail: None,
1050
      },
1051
    ));
1052
1053
    let data = core::cell::Cell::new(0u8);
1054
    let partial =
1055
      data.view_bits::<Lsb0>()[2 .. 6].domain().enclave().unwrap();
1056
    assert_eq!(partial.store_value_aliased(!0), 0);
1057
    assert_eq!(data.get(), 0b00_1111_00);
1058
  }
1059
1060
  #[test]
1061
  fn iter() {
1062
    let bits = [0x12u8, 0x34, 0x56].view_bits::<Lsb0>();
1063
    let mut domain = bits[4 .. 12].domain();
1064
    assert_eq!(domain.len(), 2);
1065
    assert_eq!(domain.next().unwrap(), 0x10);
1066
    assert_eq!(domain.next_back().unwrap(), 0x04);
1067
1068
    assert!(domain.next().is_none());
1069
    assert!(domain.next_back().is_none());
1070
1071
    assert_eq!(bits[2 .. 6].domain().len(), 1);
1072
    assert_eq!(bits[18 .. 22].domain().next_back().unwrap(), 0b00_0101_00);
1073
1074
    let mut domain = bits[4 .. 20].domain();
1075
    assert_eq!(domain.next_back().unwrap(), 0x06);
1076
    assert_eq!(domain.next_back().unwrap(), 0x34);
1077
    assert_eq!(domain.next_back().unwrap(), 0x10);
1078
  }
1079
1080
  #[test]
1081
  #[cfg(feature = "alloc")]
1082
  fn render() {
1083
    #[cfg(not(feature = "std"))]
1084
    use alloc::format;
1085
1086
    let data = BitArray::<u32, Msb0>::new(random());
1087
1088
    let render = format!("{:?}", data.bit_domain());
1089
    let expected = format!(
1090
      "BitDomain::<*const u32, {}>::Region {{ head: {:?}, body: {:?}, \
1091
       tail: {:?} }}",
1092
      any::type_name::<Msb0>(),
1093
      BitSlice::<u32, Msb0>::empty(),
1094
      data.as_bitslice(),
1095
      BitSlice::<u32, Msb0>::empty(),
1096
    );
1097
    assert_eq!(render, expected);
1098
1099
    let render = format!("{:?}", data[2 .. 30].bit_domain());
1100
    let expected = format!(
1101
      "BitDomain::<*const u32, {}>::Enclave({:?})",
1102
      any::type_name::<Msb0>(),
1103
      &data[2 .. 30],
1104
    );
1105
    assert_eq!(render, expected);
1106
1107
    let render = format!("{:?}", data.domain());
1108
    let expected = format!(
1109
      "Domain::<*const u32, {}>::Region {{ head: None, body: {:?}, tail: \
1110
       None }}",
1111
      any::type_name::<Msb0>(),
1112
      data.as_raw_slice(),
1113
    );
1114
    assert_eq!(render, expected);
1115
1116
    let render = format!("{:?}", data[2 .. 30].domain());
1117
    let expected = format!(
1118
      "Domain::<*const u32, {}>::Enclave",
1119
      any::type_name::<Msb0>(),
1120
    );
1121
    assert!(render.starts_with(&expected));
1122
1123
    let partial = 0x3Cu8.view_bits::<Lsb0>()[2 .. 6]
1124
      .domain()
1125
      .enclave()
1126
      .unwrap();
1127
    let render = format!("{:?}", partial);
1128
    assert_eq!(
1129
      render,
1130
      format!(
1131
        "PartialElement<*const u8, {}> {{ elem: 60, mask: {}, head: \
1132
         {}, tail: {} }}",
1133
        any::type_name::<Lsb0>(),
1134
        partial.mask,
1135
        partial.head,
1136
        partial.tail,
1137
      ),
1138
    );
1139
  }
1140
}