/rust/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/bitset.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Small Bitset |
2 | | //! |
3 | | //! This module defines a struct `BitSet<T>` encapsulating a bitset built over the type T. |
4 | | //! T is intended to be a primitive unsigned type. Currently it can be any type between u8 and u32 |
5 | | //! |
6 | | //! If you would like to add support for larger bitsets in the future, you need to change the trait |
7 | | //! bound `Into<u32>` and the `u32` in the implementation of `max_bits()`. |
8 | | |
9 | | use core::convert::{From, Into}; |
10 | | use core::mem::size_of; |
11 | | use core::ops::{Add, BitOr, Shl, Sub}; |
12 | | |
13 | | /// A small bitset built on a single primitive integer type |
14 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
15 | | #[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))] |
16 | | pub struct BitSet<T>(pub T); |
17 | | |
18 | | impl<T> BitSet<T> |
19 | | where |
20 | | T: Into<u32> |
21 | | + From<u8> |
22 | | + BitOr<T, Output = T> |
23 | | + Shl<u8, Output = T> |
24 | | + Sub<T, Output = T> |
25 | | + Add<T, Output = T> |
26 | | + PartialEq |
27 | | + Copy, |
28 | | { |
29 | | /// Maximum number of bits supported by this BitSet instance |
30 | 0 | pub fn bits() -> usize { |
31 | 0 | size_of::<T>() * 8 |
32 | 0 | } |
33 | | |
34 | | /// Maximum number of bits supported by any bitset instance atm. |
35 | 0 | pub fn max_bits() -> usize { |
36 | 0 | size_of::<u32>() * 8 |
37 | 0 | } |
38 | | |
39 | | /// Check if this BitSet contains the number num |
40 | 37.5M | pub fn contains(&self, num: u32) -> bool { |
41 | 37.5M | debug_assert!((num as usize) < Self::bits()); |
42 | 37.5M | debug_assert!((num as usize) < Self::max_bits()); |
43 | 37.5M | self.0.into() & (1 << num) != 0 |
44 | 37.5M | } <cranelift_codegen::bitset::BitSet<u8>>::contains Line | Count | Source | 40 | 18.7M | pub fn contains(&self, num: u32) -> bool { | 41 | 18.7M | debug_assert!((num as usize) < Self::bits()); | 42 | 18.7M | debug_assert!((num as usize) < Self::max_bits()); | 43 | 18.7M | self.0.into() & (1 << num) != 0 | 44 | 18.7M | } |
Unexecuted instantiation: <cranelift_codegen::bitset::BitSet<u32>>::contains <cranelift_codegen::bitset::BitSet<u16>>::contains Line | Count | Source | 40 | 18.7M | pub fn contains(&self, num: u32) -> bool { | 41 | 18.7M | debug_assert!((num as usize) < Self::bits()); | 42 | 18.7M | debug_assert!((num as usize) < Self::max_bits()); | 43 | 18.7M | self.0.into() & (1 << num) != 0 | 44 | 18.7M | } |
|
45 | | |
46 | | /// Return the smallest number contained in the bitset or None if empty |
47 | 0 | pub fn min(&self) -> Option<u8> { |
48 | 0 | if self.0.into() == 0 { |
49 | 0 | None |
50 | | } else { |
51 | 0 | Some(self.0.into().trailing_zeros() as u8) |
52 | | } |
53 | 0 | } |
54 | | |
55 | | /// Return the largest number contained in the bitset or None if empty |
56 | 0 | pub fn max(&self) -> Option<u8> { |
57 | 0 | if self.0.into() == 0 { |
58 | 0 | None |
59 | | } else { |
60 | 0 | let leading_zeroes = self.0.into().leading_zeros() as usize; |
61 | 0 | Some((Self::max_bits() - leading_zeroes - 1) as u8) |
62 | | } |
63 | 0 | } |
64 | | |
65 | | /// Construct a BitSet with the half-open range [lo,hi) filled in |
66 | 0 | pub fn from_range(lo: u8, hi: u8) -> Self { |
67 | 0 | debug_assert!(lo <= hi); |
68 | 0 | debug_assert!((hi as usize) <= Self::bits()); |
69 | 0 | let one: T = T::from(1); |
70 | | // I can't just do (one << hi) - one here as the shift may overflow |
71 | 0 | let hi_rng = if hi >= 1 { |
72 | 0 | (one << (hi - 1)) + ((one << (hi - 1)) - one) |
73 | | } else { |
74 | 0 | T::from(0) |
75 | | }; |
76 | | |
77 | 0 | let lo_rng = (one << lo) - one; |
78 | 0 |
|
79 | 0 | Self(hi_rng - lo_rng) |
80 | 0 | } |
81 | | } |
82 | | |
83 | | #[cfg(test)] |
84 | | mod tests { |
85 | | use super::*; |
86 | | |
87 | | #[test] |
88 | | fn contains() { |
89 | | let s = BitSet::<u8>(255); |
90 | | for i in 0..7 { |
91 | | assert!(s.contains(i)); |
92 | | } |
93 | | |
94 | | let s1 = BitSet::<u8>(0); |
95 | | for i in 0..7 { |
96 | | assert!(!s1.contains(i)); |
97 | | } |
98 | | |
99 | | let s2 = BitSet::<u8>(127); |
100 | | for i in 0..6 { |
101 | | assert!(s2.contains(i)); |
102 | | } |
103 | | assert!(!s2.contains(7)); |
104 | | |
105 | | let s3 = BitSet::<u8>(2 | 4 | 64); |
106 | | assert!(!s3.contains(0) && !s3.contains(3) && !s3.contains(4)); |
107 | | assert!(!s3.contains(5) && !s3.contains(7)); |
108 | | assert!(s3.contains(1) && s3.contains(2) && s3.contains(6)); |
109 | | |
110 | | let s4 = BitSet::<u16>(4 | 8 | 256 | 1024); |
111 | | assert!( |
112 | | !s4.contains(0) |
113 | | && !s4.contains(1) |
114 | | && !s4.contains(4) |
115 | | && !s4.contains(5) |
116 | | && !s4.contains(6) |
117 | | && !s4.contains(7) |
118 | | && !s4.contains(9) |
119 | | && !s4.contains(11) |
120 | | ); |
121 | | assert!(s4.contains(2) && s4.contains(3) && s4.contains(8) && s4.contains(10)); |
122 | | } |
123 | | |
124 | | #[test] |
125 | | fn minmax() { |
126 | | let s = BitSet::<u8>(255); |
127 | | assert_eq!(s.min(), Some(0)); |
128 | | assert_eq!(s.max(), Some(7)); |
129 | | assert!(s.min() == Some(0) && s.max() == Some(7)); |
130 | | let s1 = BitSet::<u8>(0); |
131 | | assert!(s1.min() == None && s1.max() == None); |
132 | | let s2 = BitSet::<u8>(127); |
133 | | assert!(s2.min() == Some(0) && s2.max() == Some(6)); |
134 | | let s3 = BitSet::<u8>(2 | 4 | 64); |
135 | | assert!(s3.min() == Some(1) && s3.max() == Some(6)); |
136 | | let s4 = BitSet::<u16>(4 | 8 | 256 | 1024); |
137 | | assert!(s4.min() == Some(2) && s4.max() == Some(10)); |
138 | | } |
139 | | |
140 | | #[test] |
141 | | fn from_range() { |
142 | | let s = BitSet::<u8>::from_range(5, 5); |
143 | | assert!(s.0 == 0); |
144 | | |
145 | | let s = BitSet::<u8>::from_range(0, 8); |
146 | | assert!(s.0 == 255); |
147 | | |
148 | | let s = BitSet::<u16>::from_range(0, 8); |
149 | | assert!(s.0 == 255u16); |
150 | | |
151 | | let s = BitSet::<u16>::from_range(0, 16); |
152 | | assert!(s.0 == 65535u16); |
153 | | |
154 | | let s = BitSet::<u8>::from_range(5, 6); |
155 | | assert!(s.0 == 32u8); |
156 | | |
157 | | let s = BitSet::<u8>::from_range(3, 7); |
158 | | assert!(s.0 == 8 | 16 | 32 | 64); |
159 | | |
160 | | let s = BitSet::<u16>::from_range(5, 11); |
161 | | assert!(s.0 == 32 | 64 | 128 | 256 | 512 | 1024); |
162 | | } |
163 | | } |