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