Coverage Report

Created: 2026-01-10 06:06

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
503k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
503k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
503k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
503k
    let (head, elts, tail) =
381
503k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
503k
    let base = bitspan.address();
383
503k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
503k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
503k
      (h, _, t) if h == min && t == max => Self::spanning,
387
333k
      (_, _, t) if t == max => Self::partial_head,
388
138k
      (h, ..) if h == min => Self::partial_tail,
389
12.6k
      (_, 1, _) => Self::minor,
390
118k
      _ => Self::major,
391
    };
392
503k
    ctor(base, elts, head, tail)
393
503k
  }
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
281k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
281k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
281k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
281k
    let (head, elts, tail) =
381
281k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
281k
    let base = bitspan.address();
383
281k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
281k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
281k
      (h, _, t) if h == min && t == max => Self::spanning,
387
164k
      (_, _, t) if t == max => Self::partial_head,
388
83.0k
      (h, ..) if h == min => Self::partial_tail,
389
6.92k
      (_, 1, _) => Self::minor,
390
76.1k
      _ => Self::major,
391
    };
392
281k
    ctor(base, elts, head, tail)
393
281k
  }
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
222k
  pub(crate) fn new(bits: Reference<'a, M, BitSlice<T, O>>) -> Self
378
222k
  where BitSpan<M, T, O>: From<Reference<'a, M, BitSlice<T, O>>> {
379
222k
    let bitspan = bits.conv::<BitSpan<M, T, O>>();
380
222k
    let (head, elts, tail) =
381
222k
      (bitspan.head(), bitspan.elements(), bitspan.tail());
382
222k
    let base = bitspan.address();
383
222k
    let (min, max) = (BitIdx::<T::Mem>::MIN, BitEnd::<T::Mem>::MAX);
384
222k
    let ctor = match (head, elts, tail) {
385
0
      (_, 0, _) => Self::empty,
386
222k
      (h, _, t) if h == min && t == max => Self::spanning,
387
169k
      (_, _, t) if t == max => Self::partial_head,
388
54.9k
      (h, ..) if h == min => Self::partial_tail,
389
5.72k
      (_, 1, _) => Self::minor,
390
41.8k
      _ => Self::major,
391
    };
392
222k
    ctor(base, elts, head, tail)
393
222k
  }
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
118k
  fn major(
410
118k
    addr: Address<M, T>,
411
118k
    elts: usize,
412
118k
    head: BitIdx<T::Mem>,
413
118k
    tail: BitEnd<T::Mem>,
414
118k
  ) -> Self {
415
118k
    let h_elem = addr;
416
118k
    let t_elem = unsafe { addr.add(elts - 1) };
417
118k
    let body = unsafe {
418
118k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
118k
        addr.add(1).cast::<T::Unalias>(),
420
118k
        elts - 2,
421
      )
422
    };
423
118k
    Self::Region {
424
118k
      head: Some(PartialElement::new(h_elem, head, None)),
425
118k
      body,
426
118k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
118k
    }
428
118k
  }
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
76.1k
  fn major(
410
76.1k
    addr: Address<M, T>,
411
76.1k
    elts: usize,
412
76.1k
    head: BitIdx<T::Mem>,
413
76.1k
    tail: BitEnd<T::Mem>,
414
76.1k
  ) -> Self {
415
76.1k
    let h_elem = addr;
416
76.1k
    let t_elem = unsafe { addr.add(elts - 1) };
417
76.1k
    let body = unsafe {
418
76.1k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
76.1k
        addr.add(1).cast::<T::Unalias>(),
420
76.1k
        elts - 2,
421
      )
422
    };
423
76.1k
    Self::Region {
424
76.1k
      head: Some(PartialElement::new(h_elem, head, None)),
425
76.1k
      body,
426
76.1k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
76.1k
    }
428
76.1k
  }
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
41.8k
  fn major(
410
41.8k
    addr: Address<M, T>,
411
41.8k
    elts: usize,
412
41.8k
    head: BitIdx<T::Mem>,
413
41.8k
    tail: BitEnd<T::Mem>,
414
41.8k
  ) -> Self {
415
41.8k
    let h_elem = addr;
416
41.8k
    let t_elem = unsafe { addr.add(elts - 1) };
417
41.8k
    let body = unsafe {
418
41.8k
      Address::<M, [T::Unalias]>::from_raw_parts(
419
41.8k
        addr.add(1).cast::<T::Unalias>(),
420
41.8k
        elts - 2,
421
      )
422
    };
423
41.8k
    Self::Region {
424
41.8k
      head: Some(PartialElement::new(h_elem, head, None)),
425
41.8k
      body,
426
41.8k
      tail: Some(PartialElement::new(t_elem, None, tail)),
427
41.8k
    }
428
41.8k
  }
Unexecuted instantiation: <bitvec::domain::Domain<_, _, _>>::major
429
430
  /// Produces a `Domain::Enclave`.
431
  #[inline]
432
12.6k
  fn minor(
433
12.6k
    addr: Address<M, T>,
434
12.6k
    _: usize,
435
12.6k
    head: BitIdx<T::Mem>,
436
12.6k
    tail: BitEnd<T::Mem>,
437
12.6k
  ) -> Self {
438
12.6k
    let elem = addr;
439
12.6k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
12.6k
  }
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
6.92k
  fn minor(
433
6.92k
    addr: Address<M, T>,
434
6.92k
    _: usize,
435
6.92k
    head: BitIdx<T::Mem>,
436
6.92k
    tail: BitEnd<T::Mem>,
437
6.92k
  ) -> Self {
438
6.92k
    let elem = addr;
439
6.92k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
6.92k
  }
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
5.72k
  fn minor(
433
5.72k
    addr: Address<M, T>,
434
5.72k
    _: usize,
435
5.72k
    head: BitIdx<T::Mem>,
436
5.72k
    tail: BitEnd<T::Mem>,
437
5.72k
  ) -> Self {
438
5.72k
    let elem = addr;
439
5.72k
    Self::Enclave(PartialElement::new(elem, head, tail))
440
5.72k
  }
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
195k
  fn partial_head(
446
195k
    addr: Address<M, T>,
447
195k
    elts: usize,
448
195k
    head: BitIdx<T::Mem>,
449
195k
    _: BitEnd<T::Mem>,
450
195k
  ) -> Self {
451
195k
    let elem = addr;
452
195k
    let body = unsafe {
453
195k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
195k
        addr.add(1).cast::<T::Unalias>(),
455
195k
        elts - 1,
456
      )
457
    };
458
195k
    Self::Region {
459
195k
      head: Some(PartialElement::new(elem, head, None)),
460
195k
      body,
461
195k
      tail: None,
462
195k
    }
463
195k
  }
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
81.0k
  fn partial_head(
446
81.0k
    addr: Address<M, T>,
447
81.0k
    elts: usize,
448
81.0k
    head: BitIdx<T::Mem>,
449
81.0k
    _: BitEnd<T::Mem>,
450
81.0k
  ) -> Self {
451
81.0k
    let elem = addr;
452
81.0k
    let body = unsafe {
453
81.0k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
81.0k
        addr.add(1).cast::<T::Unalias>(),
455
81.0k
        elts - 1,
456
      )
457
    };
458
81.0k
    Self::Region {
459
81.0k
      head: Some(PartialElement::new(elem, head, None)),
460
81.0k
      body,
461
81.0k
      tail: None,
462
81.0k
    }
463
81.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
114k
  fn partial_head(
446
114k
    addr: Address<M, T>,
447
114k
    elts: usize,
448
114k
    head: BitIdx<T::Mem>,
449
114k
    _: BitEnd<T::Mem>,
450
114k
  ) -> Self {
451
114k
    let elem = addr;
452
114k
    let body = unsafe {
453
114k
      Address::<M, [T::Unalias]>::from_raw_parts(
454
114k
        addr.add(1).cast::<T::Unalias>(),
455
114k
        elts - 1,
456
      )
457
    };
458
114k
    Self::Region {
459
114k
      head: Some(PartialElement::new(elem, head, None)),
460
114k
      body,
461
114k
      tail: None,
462
114k
    }
463
114k
  }
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
7.37k
  fn partial_tail(
469
7.37k
    addr: Address<M, T>,
470
7.37k
    elts: usize,
471
7.37k
    _: BitIdx<T::Mem>,
472
7.37k
    tail: BitEnd<T::Mem>,
473
7.37k
  ) -> Self {
474
7.37k
    let elem = unsafe { addr.add(elts - 1) };
475
7.37k
    let body = unsafe {
476
7.37k
      Address::<M, [T::Unalias]>::from_raw_parts(
477
7.37k
        addr.cast::<T::Unalias>(),
478
7.37k
        elts - 1,
479
      )
480
    };
481
7.37k
    Self::Region {
482
7.37k
      head: None,
483
7.37k
      body,
484
7.37k
      tail: Some(PartialElement::new(elem, None, tail)),
485
7.37k
    }
486
7.37k
  }
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
7.37k
  fn partial_tail(
469
7.37k
    addr: Address<M, T>,
470
7.37k
    elts: usize,
471
7.37k
    _: BitIdx<T::Mem>,
472
7.37k
    tail: BitEnd<T::Mem>,
473
7.37k
  ) -> Self {
474
7.37k
    let elem = unsafe { addr.add(elts - 1) };
475
7.37k
    let body = unsafe {
476
7.37k
      Address::<M, [T::Unalias]>::from_raw_parts(
477
7.37k
        addr.cast::<T::Unalias>(),
478
7.37k
        elts - 1,
479
      )
480
    };
481
7.37k
    Self::Region {
482
7.37k
      head: None,
483
7.37k
      body,
484
7.37k
      tail: Some(PartialElement::new(elem, None, tail)),
485
7.37k
    }
486
7.37k
  }
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
169k
  fn spanning(
492
169k
    addr: Address<M, T>,
493
169k
    elts: usize,
494
169k
    _: BitIdx<T::Mem>,
495
169k
    _: BitEnd<T::Mem>,
496
169k
  ) -> Self {
497
169k
    Self::Region {
498
169k
      head: None,
499
169k
      body: unsafe {
500
169k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
169k
          addr.cast::<T::Unalias>(),
502
169k
          elts,
503
169k
        )
504
169k
      },
505
169k
      tail: None,
506
169k
    }
507
169k
  }
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
117k
  fn spanning(
492
117k
    addr: Address<M, T>,
493
117k
    elts: usize,
494
117k
    _: BitIdx<T::Mem>,
495
117k
    _: BitEnd<T::Mem>,
496
117k
  ) -> Self {
497
117k
    Self::Region {
498
117k
      head: None,
499
117k
      body: unsafe {
500
117k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
117k
          addr.cast::<T::Unalias>(),
502
117k
          elts,
503
117k
        )
504
117k
      },
505
117k
      tail: None,
506
117k
    }
507
117k
  }
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
52.2k
  fn spanning(
492
52.2k
    addr: Address<M, T>,
493
52.2k
    elts: usize,
494
52.2k
    _: BitIdx<T::Mem>,
495
52.2k
    _: BitEnd<T::Mem>,
496
52.2k
  ) -> Self {
497
52.2k
    Self::Region {
498
52.2k
      head: None,
499
52.2k
      body: unsafe {
500
52.2k
        <Address<M, [T::Unalias]> as SliceReferential>::from_raw_parts(
501
52.2k
          addr.cast::<T::Unalias>(),
502
52.2k
          elts,
503
52.2k
        )
504
52.2k
      },
505
52.2k
      tail: None,
506
52.2k
    }
507
52.2k
  }
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
451k
  fn new(
731
451k
    elem: Address<M, T>,
732
451k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
451k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
451k
  ) -> Self {
735
451k
    let (head, tail) = (
736
451k
      head.into().unwrap_or(BitIdx::MIN),
737
451k
      tail.into().unwrap_or(BitEnd::MAX),
738
451k
    );
739
451k
    Self {
740
451k
      elem,
741
451k
      mask: O::mask(head, tail),
742
451k
      head,
743
451k
      tail,
744
451k
      _ord: PhantomData,
745
451k
      _ref: PhantomData,
746
451k
    }
747
451k
  }
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
6.92k
  fn new(
731
6.92k
    elem: Address<M, T>,
732
6.92k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
6.92k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
6.92k
  ) -> Self {
735
6.92k
    let (head, tail) = (
736
6.92k
      head.into().unwrap_or(BitIdx::MIN),
737
6.92k
      tail.into().unwrap_or(BitEnd::MAX),
738
6.92k
    );
739
6.92k
    Self {
740
6.92k
      elem,
741
6.92k
      mask: O::mask(head, tail),
742
6.92k
      head,
743
6.92k
      tail,
744
6.92k
      _ord: PhantomData,
745
6.92k
      _ref: PhantomData,
746
6.92k
    }
747
6.92k
  }
<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
157k
  fn new(
731
157k
    elem: Address<M, T>,
732
157k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
157k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
157k
  ) -> Self {
735
157k
    let (head, tail) = (
736
157k
      head.into().unwrap_or(BitIdx::MIN),
737
157k
      tail.into().unwrap_or(BitEnd::MAX),
738
157k
    );
739
157k
    Self {
740
157k
      elem,
741
157k
      mask: O::mask(head, tail),
742
157k
      head,
743
157k
      tail,
744
157k
      _ord: PhantomData,
745
157k
      _ref: PhantomData,
746
157k
    }
747
157k
  }
<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
76.1k
  fn new(
731
76.1k
    elem: Address<M, T>,
732
76.1k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
76.1k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
76.1k
  ) -> Self {
735
76.1k
    let (head, tail) = (
736
76.1k
      head.into().unwrap_or(BitIdx::MIN),
737
76.1k
      tail.into().unwrap_or(BitEnd::MAX),
738
76.1k
    );
739
76.1k
    Self {
740
76.1k
      elem,
741
76.1k
      mask: O::mask(head, tail),
742
76.1k
      head,
743
76.1k
      tail,
744
76.1k
      _ord: PhantomData,
745
76.1k
      _ref: PhantomData,
746
76.1k
    }
747
76.1k
  }
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
5.72k
  fn new(
731
5.72k
    elem: Address<M, T>,
732
5.72k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
5.72k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
5.72k
  ) -> Self {
735
5.72k
    let (head, tail) = (
736
5.72k
      head.into().unwrap_or(BitIdx::MIN),
737
5.72k
      tail.into().unwrap_or(BitEnd::MAX),
738
5.72k
    );
739
5.72k
    Self {
740
5.72k
      elem,
741
5.72k
      mask: O::mask(head, tail),
742
5.72k
      head,
743
5.72k
      tail,
744
5.72k
      _ord: PhantomData,
745
5.72k
      _ref: PhantomData,
746
5.72k
    }
747
5.72k
  }
<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
156k
  fn new(
731
156k
    elem: Address<M, T>,
732
156k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
156k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
156k
  ) -> Self {
735
156k
    let (head, tail) = (
736
156k
      head.into().unwrap_or(BitIdx::MIN),
737
156k
      tail.into().unwrap_or(BitEnd::MAX),
738
156k
    );
739
156k
    Self {
740
156k
      elem,
741
156k
      mask: O::mask(head, tail),
742
156k
      head,
743
156k
      tail,
744
156k
      _ord: PhantomData,
745
156k
      _ref: PhantomData,
746
156k
    }
747
156k
  }
<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
49.2k
  fn new(
731
49.2k
    elem: Address<M, T>,
732
49.2k
    head: impl Into<Option<BitIdx<T::Mem>>>,
733
49.2k
    tail: impl Into<Option<BitEnd<T::Mem>>>,
734
49.2k
  ) -> Self {
735
49.2k
    let (head, tail) = (
736
49.2k
      head.into().unwrap_or(BitIdx::MIN),
737
49.2k
      tail.into().unwrap_or(BitEnd::MAX),
738
49.2k
    );
739
49.2k
    Self {
740
49.2k
      elem,
741
49.2k
      mask: O::mask(head, tail),
742
49.2k
      head,
743
49.2k
      tail,
744
49.2k
      _ord: PhantomData,
745
49.2k
      _ref: PhantomData,
746
49.2k
    }
747
49.2k
  }
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
211k
  pub fn load_value(&self) -> T::Mem {
757
211k
    self.elem
758
211k
      .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
211k
      .pipe(|addr| unsafe { &*addr.to_const() })
Unexecuted instantiation: <bitvec::domain::PartialElement<_, _, _>>::load_value::{closure#0}
759
211k
      .load_value()
760
211k
      & self.mask.into_inner()
761
211k
  }
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
211k
  pub fn load_value(&self) -> T::Mem {
757
211k
    self.elem
758
211k
      .pipe(|addr| unsafe { &*addr.to_const() })
759
211k
      .load_value()
760
211k
      & self.mask.into_inner()
761
211k
  }
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
132k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
132k
    self.tail
775
132k
  }
<bitvec::domain::PartialElement<wyz::comu::Mut, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
773
83.0k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
83.0k
    self.tail
775
83.0k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::tail
Line
Count
Source
773
49.2k
  pub fn tail(&self) -> BitEnd<T::Mem> {
774
49.2k
    self.tail
775
49.2k
  }
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
5.72k
  pub fn mask(&self) -> BitMask<T::Mem> {
789
5.72k
    self.mask
790
5.72k
  }
<bitvec::domain::PartialElement<wyz::comu::Const, u8, bitvec::order::Msb0>>::mask
Line
Count
Source
788
5.72k
  pub fn mask(&self) -> BitMask<T::Mem> {
789
5.72k
    self.mask
790
5.72k
  }
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
240k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
828
240k
    let this = self.access();
829
240k
    let prev = this.clear_bits(self.mask);
830
240k
    this.set_bits(self.mask & value);
831
240k
    prev & self.mask.into_inner()
832
240k
  }
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
240k
  pub fn store_value(&mut self, value: T::Mem) -> T::Mem {
828
240k
    let this = self.access();
829
240k
    let prev = this.clear_bits(self.mask);
830
240k
    this.set_bits(self.mask & value);
831
240k
    prev & self.mask.into_inner()
832
240k
  }
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
240k
  fn access(&self) -> &T::Access {
871
240k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
872
240k
  }
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
240k
  fn access(&self) -> &T::Access {
871
240k
    unsafe { &*self.elem.to_const().cast::<T::Access>() }
872
240k
  }
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
}