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 smallest 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_min(), Some(0));
368 /// assert_eq!(bitset.pop_min(), Some(13));
369 /// assert_eq!(bitset.pop_min(), Some(24));
370 /// assert_eq!(bitset.pop_min(), Some(36));
371 /// assert_eq!(bitset.pop_min(), None);
372 /// ```
373 #[inline]
374 pub fn pop_min(&mut self) -> Option<u8> {
375 let min = self.min()?;
376 self.remove(min);
377 Some(min)
378 }
379
380 /// Remove and return the largest value in the bitset.
381 ///
382 /// # Example
383 ///
384 /// ```
385 /// use cranelift_bitset::ScalarBitSet;
386 ///
387 /// let mut bitset = ScalarBitSet::<u64>::new();
388 ///
389 /// bitset.insert(0);
390 /// bitset.insert(24);
391 /// bitset.insert(13);
392 /// bitset.insert(36);
393 ///
394 /// assert_eq!(bitset.pop_max(), Some(36));
395 /// assert_eq!(bitset.pop_max(), Some(24));
396 /// assert_eq!(bitset.pop_max(), Some(13));
397 /// assert_eq!(bitset.pop_max(), Some(0));
398 /// assert_eq!(bitset.pop_max(), None);
399 /// ```
400 #[inline]
401 pub fn pop_max(&mut self) -> Option<u8> {
402 let max = self.max()?;
403 self.remove(max);
404 Some(max)
405 }
406
407 /// Return the smallest number contained in this bitset or `None` if this
408 /// bitset is empty.
409 ///
410 /// # Example
411 ///
412 /// ```
413 /// use cranelift_bitset::ScalarBitSet;
414 ///
415 /// let mut bitset = ScalarBitSet::<u64>::new();
416 ///
417 /// // When the bitset is empty, `min` returns `None`.
418 /// assert_eq!(bitset.min(), None);
419 ///
420 /// bitset.insert(28);
421 /// bitset.insert(1);
422 /// bitset.insert(63);
423 ///
424 /// // When the bitset is not empty, it returns the smallest element.
425 /// assert_eq!(bitset.min(), Some(1));
426 /// ```
427 #[inline]
428 pub fn min(&self) -> Option<u8> {
429 if self.0 == T::from(0) {
430 None
431 } else {
432 Some(self.0.trailing_zeros())
433 }
434 }
435
436 /// Return the largest number contained in the bitset or None if this bitset
437 /// is empty
438 ///
439 /// # Example
440 ///
441 /// ```
442 /// use cranelift_bitset::ScalarBitSet;
443 ///
444 /// let mut bitset = ScalarBitSet::<u64>::new();
445 ///
446 /// // When the bitset is empty, `max` returns `None`.
447 /// assert_eq!(bitset.max(), None);
448 ///
449 /// bitset.insert(0);
450 /// bitset.insert(36);
451 /// bitset.insert(49);
452 ///
453 /// // When the bitset is not empty, it returns the smallest element.
454 /// assert_eq!(bitset.max(), Some(49));
455 /// ```
456 #[inline]
457 pub fn max(&self) -> Option<u8> {
458 if self.0 == T::from(0) {
459 None
460 } else {
461 let leading_zeroes = self.0.leading_zeros();
462 Some(Self::capacity() - leading_zeroes - 1)
463 }
464 }
465
466 /// Iterate over the items in this set.
467 ///
468 /// Items are always yielded in sorted order.
469 ///
470 /// # Example
471 ///
472 /// ```
473 /// use cranelift_bitset::ScalarBitSet;
474 ///
475 /// let mut bitset = ScalarBitSet::<u64>::new();
476 ///
477 /// bitset.insert(19);
478 /// bitset.insert(3);
479 /// bitset.insert(63);
480 /// bitset.insert(0);
481 ///
482 /// assert_eq!(
483 /// bitset.iter().collect::<Vec<_>>(),
484 /// [0, 3, 19, 63],
485 /// );
486 /// ```
487 #[inline]
488 pub fn iter(self) -> Iter<T> {
489 Iter { bitset: self }
490 }
491}
492
493impl<T> IntoIterator for ScalarBitSet<T>
494where
495 T: ScalarBitSetStorage,
496{
497 type Item = u8;
498
499 type IntoIter = Iter<T>;
500
501 #[inline]
502 fn into_iter(self) -> Self::IntoIter {
503 self.iter()
504 }
505}
506
507impl<'a, T> IntoIterator for &'a ScalarBitSet<T>
508where
509 T: ScalarBitSetStorage,
510{
511 type Item = u8;
512
513 type IntoIter = Iter<T>;
514
515 #[inline]
516 fn into_iter(self) -> Self::IntoIter {
517 self.iter()
518 }
519}
520
521impl<T: ScalarBitSetStorage> From<T> for ScalarBitSet<T> {
522 fn from(bits: T) -> Self {
523 Self(bits)
524 }
525}
526
527/// A trait implemented by all integers that can be used as the backing storage
528/// for a [`ScalarBitSet`].
529///
530/// You shouldn't have to implement this yourself, it is already implemented for
531/// `u{8,16,32,64,128}` and if you need more bits than that, then use
532/// [`CompoundBitSet`][crate::CompoundBitSet] instead.
533pub trait ScalarBitSetStorage:
534 Default
535 + From<u8>
536 + Shl<u8, Output = Self>
537 + Shr<u8, Output = Self>
538 + BitAnd<Output = Self>
539 + BitOr<Output = Self>
540 + Not<Output = Self>
541 + Sub<Output = Self>
542 + Add<Output = Self>
543 + PartialEq
544 + Copy
545{
546 /// Count the number of leading zeros.
547 fn leading_zeros(self) -> u8;
548
549 /// Count the number of trailing zeros.
550 fn trailing_zeros(self) -> u8;
551
552 /// Count the number of bits set in this integer.
553 fn count_ones(self) -> u8;
554}
555
556macro_rules! impl_storage {
557 ( $int:ty ) => {
558 impl ScalarBitSetStorage for $int {
559 #[inline]
560 fn leading_zeros(self) -> u8 {
561 u8::try_from(self.leading_zeros()).unwrap()
562 }
563
564 #[inline]
565 fn trailing_zeros(self) -> u8 {
566 u8::try_from(self.trailing_zeros()).unwrap()
567 }
568
569 #[inline]
570 fn count_ones(self) -> u8 {
571 u8::try_from(self.count_ones()).unwrap()
572 }
573 }
574 };
575}
576
577impl_storage!(u8);
578impl_storage!(u16);
579impl_storage!(u32);
580impl_storage!(u64);
581impl_storage!(u128);
582impl_storage!(usize);
583
584/// An iterator over the elements in a [`ScalarBitSet`].
585pub struct Iter<T> {
586 bitset: ScalarBitSet<T>,
587}
588
589impl<T> Iterator for Iter<T>
590where
591 T: ScalarBitSetStorage,
592{
593 type Item = u8;
594
595 #[inline]
596 fn next(&mut self) -> Option<u8> {
597 self.bitset.pop_min()
598 }
599}
600
601impl<T> DoubleEndedIterator for Iter<T>
602where
603 T: ScalarBitSetStorage,
604{
605 #[inline]
606 fn next_back(&mut self) -> Option<Self::Item> {
607 self.bitset.pop_max()
608 }
609}
610
611impl<T> ExactSizeIterator for Iter<T>
612where
613 T: ScalarBitSetStorage,
614{
615 #[inline]
616 fn len(&self) -> usize {
617 usize::from(self.bitset.len())
618 }
619}
620
621#[cfg(feature = "arbitrary")]
622impl<'a, T> arbitrary::Arbitrary<'a> for ScalarBitSet<T>
623where
624 T: ScalarBitSetStorage + arbitrary::Arbitrary<'a>,
625{
626 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
627 T::arbitrary(u).map(Self)
628 }
629}