cranelift_bitset/scalar.rs
1//! Scalar bitsets.
2
3use core::mem::size_of;
4use core::ops::{Add, BitAnd, BitOr, Not, Shl, Shr, Sub};
5
6/// A small bitset built on top of a single primitive integer type.
7///
8/// # Example
9///
10/// ```
11/// use cranelift_bitset::ScalarBitSet;
12///
13/// // Create a new bitset backed with a `u32`.
14/// let mut bitset = ScalarBitSet::<u32>::new();
15///
16/// // Bitsets are initially empty.
17/// assert!(bitset.is_empty());
18/// assert_eq!(bitset.len(), 0);
19///
20/// // Insert into the bitset.
21/// bitset.insert(4);
22/// bitset.insert(5);
23/// bitset.insert(6);
24///
25/// // Now the bitset is not empty.
26/// assert_eq!(bitset.len(), 3);
27/// assert!(!bitset.is_empty());
28/// assert!(bitset.contains(4));
29/// assert!(bitset.contains(5));
30/// assert!(bitset.contains(6));
31///
32/// // Remove an element from the bitset.
33/// let was_present = bitset.remove(6);
34/// assert!(was_present);
35/// assert!(!bitset.contains(6));
36/// assert_eq!(bitset.len(), 2);
37///
38/// // Can iterate over the elements in the set.
39/// let elems: Vec<_> = bitset.iter().collect();
40/// assert_eq!(elems, [4, 5]);
41/// ```
42#[derive(Clone, Copy, PartialEq, Eq)]
43#[cfg_attr(
44 feature = "enable-serde",
45 derive(serde_derive::Serialize, serde_derive::Deserialize)
46)]
47pub struct ScalarBitSet<T>(pub T);
48
49impl<T> core::fmt::Debug for ScalarBitSet<T>
50where
51 T: ScalarBitSetStorage,
52{
53 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54 let mut s = f.debug_struct(core::any::type_name::<Self>());
55 for i in 0..Self::capacity() {
56 use alloc::string::ToString;
57 let i = u8::try_from(i).unwrap();
58 s.field(&i.to_string(), &self.contains(i));
59 }
60 s.finish()
61 }
62}
63
64impl<T> Default for ScalarBitSet<T>
65where
66 T: ScalarBitSetStorage,
67{
68 #[inline]
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74impl<T> ScalarBitSet<T>
75where
76 T: ScalarBitSetStorage,
77{
78 /// Create a new, empty bitset.
79 ///
80 /// # Example
81 ///
82 /// ```
83 /// use cranelift_bitset::ScalarBitSet;
84 ///
85 /// let bitset = ScalarBitSet::<u64>::new();
86 ///
87 /// assert!(bitset.is_empty());
88 /// ```
89 #[inline]
90 pub fn new() -> Self {
91 Self(T::from(0))
92 }
93
94 /// Construct a bitset with the half-open range `[lo, hi)` inserted.
95 ///
96 /// # Example
97 ///
98 /// ```
99 /// use cranelift_bitset::ScalarBitSet;
100 ///
101 /// let bitset = ScalarBitSet::<u64>::from_range(3, 6);
102 ///
103 /// assert_eq!(bitset.len(), 3);
104 ///
105 /// assert!(bitset.contains(3));
106 /// assert!(bitset.contains(4));
107 /// assert!(bitset.contains(5));
108 /// ```
109 ///
110 /// # Panics
111 ///
112 /// Panics if `lo > hi` or if `hi > Self::capacity()`.
113 ///
114 /// ```should_panic
115 /// use cranelift_bitset::ScalarBitSet;
116 ///
117 /// // The lower bound may not be larger than the upper bound.
118 /// let bitset = ScalarBitSet::<u64>::from_range(6, 3);
119 /// ```
120 ///
121 /// ```should_panic
122 /// use cranelift_bitset::ScalarBitSet;
123 ///
124 /// // The bounds must fit within the backing scalar type.
125 /// let bitset = ScalarBitSet::<u64>::from_range(3, 69);
126 /// ```
127 #[inline]
128 pub fn from_range(lo: u8, hi: u8) -> Self {
129 assert!(lo <= hi);
130 assert!(hi <= Self::capacity());
131
132 let one = T::from(1);
133
134 // We can't just do (one << hi) - one here as the shift may overflow
135 let hi_rng = if hi >= 1 {
136 (one << (hi - 1)) + ((one << (hi - 1)) - one)
137 } else {
138 T::from(0)
139 };
140
141 let lo_rng = (one << lo) - one;
142
143 Self(hi_rng - lo_rng)
144 }
145
146 /// The maximum number of bits that can be stored in this bitset.
147 ///
148 /// If you need more bits than this, use a
149 /// [`CompoundBitSet`][crate::CompoundBitSet] instead of a `ScalarBitSet`.
150 ///
151 /// # Example
152 ///
153 /// ```
154 /// use cranelift_bitset::ScalarBitSet;
155 ///
156 /// assert_eq!(ScalarBitSet::<u8>::capacity(), 8);
157 /// assert_eq!(ScalarBitSet::<u64>::capacity(), 64);
158 /// ```
159 #[inline]
160 pub fn capacity() -> u8 {
161 u8::try_from(size_of::<T>()).unwrap() * 8
162 }
163
164 /// Get the number of elements in this set.
165 ///
166 /// # Example
167 ///
168 /// ```
169 /// use cranelift_bitset::ScalarBitSet;
170 ///
171 /// let mut bitset = ScalarBitSet::<u64>::new();
172 ///
173 /// assert_eq!(bitset.len(), 0);
174 ///
175 /// bitset.insert(24);
176 /// bitset.insert(13);
177 /// bitset.insert(36);
178 ///
179 /// assert_eq!(bitset.len(), 3);
180 /// ```
181 #[inline]
182 pub fn len(&self) -> u8 {
183 self.0.count_ones()
184 }
185
186 /// Is this bitset empty?
187 ///
188 /// # Example
189 ///
190 /// ```
191 /// use cranelift_bitset::ScalarBitSet;
192 ///
193 /// let mut bitset = ScalarBitSet::<u16>::new();
194 ///
195 /// assert!(bitset.is_empty());
196 ///
197 /// bitset.insert(10);
198 ///
199 /// assert!(!bitset.is_empty());
200 /// ```
201 #[inline]
202 pub fn is_empty(&self) -> bool {
203 self.0 == T::from(0)
204 }
205
206 /// Check whether this bitset contains `i`.
207 ///
208 /// # Example
209 ///
210 /// ```
211 /// use cranelift_bitset::ScalarBitSet;
212 ///
213 /// let mut bitset = ScalarBitSet::<u8>::new();
214 ///
215 /// assert!(!bitset.contains(7));
216 ///
217 /// bitset.insert(7);
218 ///
219 /// assert!(bitset.contains(7));
220 /// ```
221 ///
222 /// # Panics
223 ///
224 /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
225 ///
226 /// ```should_panic
227 /// use cranelift_bitset::ScalarBitSet;
228 ///
229 /// let mut bitset = ScalarBitSet::<u8>::new();
230 ///
231 /// // A `ScalarBitSet<u8>` can only hold the elements `0..=7`, so `8` is
232 /// // out of bounds and will trigger a panic.
233 /// bitset.contains(8);
234 /// ```
235 #[inline]
236 pub fn contains(&self, i: u8) -> bool {
237 assert!(i < Self::capacity());
238 self.0 & (T::from(1) << i) != T::from(0)
239 }
240
241 /// Insert `i` into this bitset.
242 ///
243 /// Returns whether the value was newly inserted. That is:
244 ///
245 /// * If the set did not previously contain `i` then `true` is returned.
246 ///
247 /// * If the set already contained `i` then `false` is returned.
248 ///
249 /// # Example
250 ///
251 /// ```
252 /// use cranelift_bitset::ScalarBitSet;
253 ///
254 /// let mut bitset = ScalarBitSet::<u8>::new();
255 ///
256 /// // When an element is inserted that was not already present in the set,
257 /// // then `true` is returned.
258 /// let is_new = bitset.insert(7);
259 /// assert!(is_new);
260 ///
261 /// // The element is now present in the set.
262 /// assert!(bitset.contains(7));
263 ///
264 /// // And when the element is already in the set, `false` is returned from
265 /// // `insert`.
266 /// let is_new = bitset.insert(7);
267 /// assert!(!is_new);
268 /// ```
269 ///
270 /// # Panics
271 ///
272 /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
273 ///
274 /// ```should_panic
275 /// use cranelift_bitset::ScalarBitSet;
276 ///
277 /// let mut bitset = ScalarBitSet::<u32>::new();
278 ///
279 /// // A `ScalarBitSet<u32>` can only hold the elements `0..=31`, so `42` is
280 /// // out of bounds and will trigger a panic.
281 /// bitset.insert(42);
282 /// ```
283 #[inline]
284 pub fn insert(&mut self, i: u8) -> bool {
285 let is_new = !self.contains(i);
286 self.0 = self.0 | (T::from(1) << i);
287 is_new
288 }
289
290 /// Remove `i` from this bitset.
291 ///
292 /// Returns whether `i` was previously in this set or not.
293 ///
294 /// # Example
295 ///
296 /// ```
297 /// use cranelift_bitset::ScalarBitSet;
298 ///
299 /// let mut bitset = ScalarBitSet::<u128>::new();
300 ///
301 /// // Removing an element that was not present in the set returns `false`.
302 /// let was_present = bitset.remove(100);
303 /// assert!(!was_present);
304 ///
305 /// // And when the element was in the set, `true` is returned.
306 /// bitset.insert(100);
307 /// let was_present = bitset.remove(100);
308 /// assert!(was_present);
309 /// ```
310 ///
311 /// # Panics
312 ///
313 /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
314 ///
315 /// ```should_panic
316 /// use cranelift_bitset::ScalarBitSet;
317 ///
318 /// let mut bitset = ScalarBitSet::<u16>::new();
319 ///
320 /// // A `ScalarBitSet<u16>` can only hold the elements `0..=15`, so `20` is
321 /// // out of bounds and will trigger a panic.
322 /// bitset.remove(20);
323 /// ```
324 #[inline]
325 pub fn remove(&mut self, i: u8) -> bool {
326 let was_present = self.contains(i);
327 self.0 = self.0 & !(T::from(1) << i);
328 was_present
329 }
330
331 /// Remove all entries from this bitset.
332 ///
333 /// # Example
334 ///
335 /// ```
336 /// use cranelift_bitset::ScalarBitSet;
337 ///
338 /// let mut bitset = ScalarBitSet::<u32>::new();
339 ///
340 /// bitset.insert(10);
341 /// bitset.insert(20);
342 /// bitset.insert(30);
343 ///
344 /// bitset.clear();
345 ///
346 /// assert!(bitset.is_empty());
347 /// ```
348 #[inline]
349 pub fn clear(&mut self) {
350 self.0 = T::from(0);
351 }
352
353 /// Remove and return the largest value in the bitset.
354 ///
355 /// # Example
356 ///
357 /// ```
358 /// use cranelift_bitset::ScalarBitSet;
359 ///
360 /// let mut bitset = ScalarBitSet::<u64>::new();
361 ///
362 /// bitset.insert(0);
363 /// bitset.insert(24);
364 /// bitset.insert(13);
365 /// bitset.insert(36);
366 ///
367 /// assert_eq!(bitset.pop(), Some(36));
368 /// assert_eq!(bitset.pop(), Some(24));
369 /// assert_eq!(bitset.pop(), Some(13));
370 /// assert_eq!(bitset.pop(), Some(0));
371 /// assert_eq!(bitset.pop(), None);
372 /// ```
373 #[inline]
374 pub fn pop(&mut self) -> Option<u8> {
375 let max = self.max()?;
376 self.remove(max);
377 Some(max)
378 }
379
380 /// Return the smallest number contained in this bitset or `None` if this
381 /// bitset is empty.
382 ///
383 /// # Example
384 ///
385 /// ```
386 /// use cranelift_bitset::ScalarBitSet;
387 ///
388 /// let mut bitset = ScalarBitSet::<u64>::new();
389 ///
390 /// // When the bitset is empty, `min` returns `None`.
391 /// assert_eq!(bitset.min(), None);
392 ///
393 /// bitset.insert(28);
394 /// bitset.insert(1);
395 /// bitset.insert(63);
396 ///
397 /// // When the bitset is not empty, it returns the smallest element.
398 /// assert_eq!(bitset.min(), Some(1));
399 /// ```
400 #[inline]
401 pub fn min(&self) -> Option<u8> {
402 if self.0 == T::from(0) {
403 None
404 } else {
405 Some(self.0.trailing_zeros())
406 }
407 }
408
409 /// Return the largest number contained in the bitset or None if this bitset
410 /// is empty
411 ///
412 /// # Example
413 ///
414 /// ```
415 /// use cranelift_bitset::ScalarBitSet;
416 ///
417 /// let mut bitset = ScalarBitSet::<u64>::new();
418 ///
419 /// // When the bitset is empty, `max` returns `None`.
420 /// assert_eq!(bitset.max(), None);
421 ///
422 /// bitset.insert(0);
423 /// bitset.insert(36);
424 /// bitset.insert(49);
425 ///
426 /// // When the bitset is not empty, it returns the smallest element.
427 /// assert_eq!(bitset.max(), Some(49));
428 /// ```
429 #[inline]
430 pub fn max(&self) -> Option<u8> {
431 if self.0 == T::from(0) {
432 None
433 } else {
434 let leading_zeroes = self.0.leading_zeros();
435 Some(Self::capacity() - leading_zeroes - 1)
436 }
437 }
438
439 /// Iterate over the items in this set.
440 ///
441 /// Items are always yielded in sorted order.
442 ///
443 /// # Example
444 ///
445 /// ```
446 /// use cranelift_bitset::ScalarBitSet;
447 ///
448 /// let mut bitset = ScalarBitSet::<u64>::new();
449 ///
450 /// bitset.insert(19);
451 /// bitset.insert(3);
452 /// bitset.insert(63);
453 /// bitset.insert(0);
454 ///
455 /// assert_eq!(
456 /// bitset.iter().collect::<Vec<_>>(),
457 /// [0, 3, 19, 63],
458 /// );
459 /// ```
460 #[inline]
461 pub fn iter(&self) -> Iter<T> {
462 Iter {
463 value: self.0,
464 index: 0,
465 }
466 }
467}
468
469impl<T> IntoIterator for ScalarBitSet<T>
470where
471 T: ScalarBitSetStorage,
472{
473 type Item = u8;
474
475 type IntoIter = Iter<T>;
476
477 #[inline]
478 fn into_iter(self) -> Self::IntoIter {
479 self.iter()
480 }
481}
482
483impl<'a, T> IntoIterator for &'a ScalarBitSet<T>
484where
485 T: ScalarBitSetStorage,
486{
487 type Item = u8;
488
489 type IntoIter = Iter<T>;
490
491 #[inline]
492 fn into_iter(self) -> Self::IntoIter {
493 self.iter()
494 }
495}
496
497/// A trait implemented by all integers that can be used as the backing storage
498/// for a [`ScalarBitSet`].
499///
500/// You shouldn't have to implement this yourself, it is already implemented for
501/// `u{8,16,32,64,128}` and if you need more bits than that, then use
502/// [`CompoundBitSet`][crate::CompoundBitSet] instead.
503pub trait ScalarBitSetStorage:
504 Default
505 + From<u8>
506 + Shl<u8, Output = Self>
507 + Shr<u8, Output = Self>
508 + BitAnd<Output = Self>
509 + BitOr<Output = Self>
510 + Not<Output = Self>
511 + Sub<Output = Self>
512 + Add<Output = Self>
513 + PartialEq
514 + Copy
515{
516 /// Count the number of leading zeros.
517 fn leading_zeros(self) -> u8;
518
519 /// Count the number of trailing zeros.
520 fn trailing_zeros(self) -> u8;
521
522 /// Count the number of bits set in this integer.
523 fn count_ones(self) -> u8;
524}
525
526macro_rules! impl_storage {
527 ( $int:ty ) => {
528 impl ScalarBitSetStorage for $int {
529 fn leading_zeros(self) -> u8 {
530 u8::try_from(self.leading_zeros()).unwrap()
531 }
532
533 fn trailing_zeros(self) -> u8 {
534 u8::try_from(self.trailing_zeros()).unwrap()
535 }
536
537 fn count_ones(self) -> u8 {
538 u8::try_from(self.count_ones()).unwrap()
539 }
540 }
541 };
542}
543
544impl_storage!(u8);
545impl_storage!(u16);
546impl_storage!(u32);
547impl_storage!(u64);
548impl_storage!(u128);
549impl_storage!(usize);
550
551/// An iterator over the elements in a [`ScalarBitSet`].
552pub struct Iter<T> {
553 value: T,
554 index: u8,
555}
556
557impl<T> Iterator for Iter<T>
558where
559 T: ScalarBitSetStorage,
560{
561 type Item = u8;
562
563 #[inline]
564 fn next(&mut self) -> Option<u8> {
565 if self.value == T::from(0) {
566 None
567 } else {
568 let trailing_zeros = self.value.trailing_zeros();
569 let elem = self.index + trailing_zeros;
570 self.index += trailing_zeros + 1;
571 self.value = self.value >> (trailing_zeros + 1);
572 Some(elem)
573 }
574 }
575}