Coverage Report

Created: 2025-07-01 06:28

/rust/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/mem.rs
Line
Count
Source (jump to first uncovered line)
1
#![doc = include_str!("../doc/mem.md")]
2
3
use core::{
4
  cell::Cell,
5
  mem,
6
};
7
8
use funty::Unsigned;
9
use radium::marker::BitOps;
10
11
#[doc = include_str!("../doc/mem/BitRegister.md")]
12
pub trait BitRegister: Unsigned + BitOps {
13
  /// The number of bits required to store an index in the range `0 .. BITS`.
14
  const INDX: u8 = bits_of::<Self>().trailing_zeros() as u8;
15
  /// A mask over all bits that can be used as an index within the element.
16
  /// This is the value with the least significant `INDX`-many bits set high.
17
  const MASK: u8 = bits_of::<Self>() as u8 - 1;
18
  /// The literal `!0`.
19
  const ALL: Self;
20
}
21
22
/// Marks certain fundamentals as processor registers.
23
macro_rules! register {
24
  ($($t:ty),+ $(,)?) => { $(
25
    impl BitRegister for $t {
26
      const ALL: Self = !0;
27
    }
28
  )+ };
29
}
30
31
register!(u8, u16, u32);
32
33
/** `u64` can only be used as a register on processors whose word size is at
34
least 64 bits.
35
36
This implementation is not present on targets with 32-bit processor words.
37
**/
38
#[cfg(target_pointer_width = "64")]
39
impl BitRegister for u64 {
40
  const ALL: Self = !0;
41
}
42
43
register!(usize);
44
45
/// Counts the number of bits in a value of type `T`.
46
3.75M
pub const fn bits_of<T>() -> usize {
47
3.75M
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
3.75M
}
bitvec::mem::bits_of::<u8>
Line
Count
Source
46
2.15M
pub const fn bits_of<T>() -> usize {
47
2.15M
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
2.15M
}
bitvec::mem::bits_of::<usize>
Line
Count
Source
46
599k
pub const fn bits_of<T>() -> usize {
47
599k
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
599k
}
bitvec::mem::bits_of::<u128>
Line
Count
Source
46
942k
pub const fn bits_of<T>() -> usize {
47
942k
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
942k
}
bitvec::mem::bits_of::<i16>
Line
Count
Source
46
46.1k
pub const fn bits_of<T>() -> usize {
47
46.1k
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
46.1k
}
bitvec::mem::bits_of::<u16>
Line
Count
Source
46
3.46k
pub const fn bits_of<T>() -> usize {
47
3.46k
  core::mem::size_of::<T>().saturating_mul(<u8>::BITS as usize)
48
3.46k
}
Unexecuted instantiation: bitvec::mem::bits_of::<_>
49
50
#[doc = include_str!("../doc/mem/elts.md")]
51
212k
pub const fn elts<T>(bits: usize) -> usize {
52
212k
  let width = bits_of::<T>();
53
212k
  if width == 0 {
54
0
    return 0;
55
212k
  }
56
212k
  bits / width + (bits % width != 0) as usize
57
212k
}
bitvec::mem::elts::<u8>
Line
Count
Source
51
212k
pub const fn elts<T>(bits: usize) -> usize {
52
212k
  let width = bits_of::<T>();
53
212k
  if width == 0 {
54
0
    return 0;
55
212k
  }
56
212k
  bits / width + (bits % width != 0) as usize
57
212k
}
Unexecuted instantiation: bitvec::mem::elts::<_>
58
59
/// Tests if a type has alignment equal to its size.
60
#[doc(hidden)]
61
#[cfg(not(tarpaulin_include))]
62
0
pub const fn aligned_to_size<T>() -> bool {
63
0
  mem::align_of::<T>() == mem::size_of::<T>()
64
0
}
65
66
/// Tests if two types have identical layouts (size and alignment are equal).
67
#[doc(hidden)]
68
#[cfg(not(tarpaulin_include))]
69
0
pub const fn layout_eq<T, U>() -> bool {
70
0
  mem::align_of::<T>() == mem::align_of::<U>()
71
0
    && mem::size_of::<T>() == mem::size_of::<U>()
72
0
}
73
74
#[doc(hidden)]
75
#[repr(transparent)]
76
#[doc = include_str!("../doc/mem/BitElement.md")]
77
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
78
pub struct BitElement<T = usize> {
79
  pub elem: T,
80
}
81
82
/// Creates a `BitElement` implementation for an integer and its atomic/cell
83
/// variants.
84
macro_rules! element {
85
  ($($size:tt, $bare:ty => $atom:ident);+ $(;)?) => { $(
86
    impl BitElement<$bare> {
87
      /// Creates a new element wrapper from a raw integer.
88
2.43k
      pub const fn new(elem: $bare) -> Self {
89
2.43k
        Self {
90
2.43k
          elem,
91
2.43k
        }
92
2.43k
      }
<bitvec::mem::BitElement<u8>>::new
Line
Count
Source
88
2.43k
      pub const fn new(elem: $bare) -> Self {
89
2.43k
        Self {
90
2.43k
          elem,
91
2.43k
        }
92
2.43k
      }
Unexecuted instantiation: <bitvec::mem::BitElement<u16>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<u32>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<u64>>::new
Unexecuted instantiation: <bitvec::mem::BitElement>::new
93
    }
94
95
    impl BitElement<Cell<$bare>> {
96
      /// Creates a new element wrapper from a raw integer.
97
0
      pub const fn new(elem: $bare) -> Self {
98
0
        Self {
99
0
          elem: Cell::new(elem),
100
0
        }
101
0
      }
Unexecuted instantiation: <bitvec::mem::BitElement<core::cell::Cell<u8>>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::cell::Cell<u16>>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::cell::Cell<u32>>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::cell::Cell<u64>>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::cell::Cell<usize>>>::new
102
    }
103
104
    radium::if_atomic!( if atomic($size) {
105
      use core::sync::atomic::$atom;
106
      impl BitElement<$atom> {
107
        /// Creates a new element wrapper from a raw integer.
108
0
        pub const fn new(elem: $bare) -> Self {
109
0
          Self {
110
0
            elem: <$atom>::new(elem),
111
0
          }
112
0
        }
Unexecuted instantiation: <bitvec::mem::BitElement<core::sync::atomic::AtomicU8>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::sync::atomic::AtomicU16>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::sync::atomic::AtomicU32>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::sync::atomic::AtomicU64>>::new
Unexecuted instantiation: <bitvec::mem::BitElement<core::sync::atomic::AtomicUsize>>::new
113
      }
114
    });
115
  )+ };
116
}
117
118
element! {
119
  8, u8 => AtomicU8;
120
  16, u16 => AtomicU16;
121
  32, u32 => AtomicU32;
122
}
123
124
#[cfg(target_pointer_width = "64")]
125
element!(64, u64 => AtomicU64);
126
127
element!(size, usize => AtomicUsize);
128
129
#[cfg(test)]
130
mod tests {
131
  use super::*;
132
  use crate::access::*;
133
134
  #[test]
135
  fn integer_properties() {
136
    assert!(aligned_to_size::<u8>());
137
    assert!(aligned_to_size::<BitSafeU8>());
138
    assert!(layout_eq::<u8, BitSafeU8>());
139
140
    assert!(aligned_to_size::<u16>());
141
    assert!(aligned_to_size::<BitSafeU16>());
142
    assert!(layout_eq::<u16, BitSafeU16>());
143
144
    assert!(aligned_to_size::<u32>());
145
    assert!(aligned_to_size::<BitSafeU32>());
146
    assert!(layout_eq::<u32, BitSafeU32>());
147
148
    assert!(aligned_to_size::<usize>());
149
    assert!(aligned_to_size::<BitSafeUsize>());
150
    assert!(layout_eq::<usize, BitSafeUsize>());
151
152
    #[cfg(target_pointer_width = "64")]
153
    {
154
      assert!(aligned_to_size::<u64>());
155
      assert!(aligned_to_size::<BitSafeU64>());
156
      assert!(layout_eq::<u64, BitSafeU64>());
157
    }
158
  }
159
}