input_linux/
bitmask.rs

1//! Bitmasks are a set of bits that can be indexed and queried by the values of
2//! various enum types.
3
4use std::fmt;
5use std::ops::{Deref, DerefMut};
6use crate::EventKind;
7use crate::enum_iterator::{IterableEnum, EnumIterator};
8
9/// A generic trait that can be used to index by a given type into a set of bits.
10pub trait BitmaskTrait {
11    /// The underlying array storage data type.
12    type Array: Sized;
13    /// The type that the bitmask can be indexed by.
14    type Index: Copy + IterableEnum;
15    /// Empty default data.
16    const ZERO: Self::Array;
17
18    /// The default empty state of the bitmask.
19    fn array_default() -> Self::Array;
20    /// A representation of the bitmask as a slice of bytes.
21    fn array_slice(array: &Self::Array) -> &[u8];
22    /// A mutable representation of the bitmask as a slice of bytes.
23    fn array_slice_mut(array: &mut Self::Array) -> &mut [u8];
24    /// Computes a normalized index value.
25    fn index(index: Self::Index) -> usize;
26    /// Validates whether a given index is valid and in range for the bitmask.
27    ///
28    /// Dynamically allocated bitmasks may not be large enough to contain all indices.
29    fn index_valid(_array: &Self::Array, _index: Self::Index) -> bool { true }
30}
31
32impl BitmaskTrait for Vec<u8> {
33    type Array = Self;
34    type Index = u16;
35    const ZERO: Self = Vec::new();
36
37    fn array_default() -> Self::Array { vec![0u8; 0x10] }
38    fn array_slice(array: &Self::Array) -> &[u8] { array }
39    fn array_slice_mut(array: &mut Self::Array) -> &mut [u8] { array }
40    fn index(index: Self::Index) -> usize { index as _ }
41    fn index_valid(array: &Self::Array, index: Self::Index) -> bool { array.len() > index as usize }
42}
43
44/// A dynamically allocated bitmask.
45pub type BitmaskVec = Bitmask<Vec<u8>>;
46
47impl Bitmask<Vec<u8>> {
48    /// Reallocate the bitmask to fit all valid code values for the given event
49    /// type.
50    pub fn resize(&mut self, kind: EventKind) {
51        self.data_mut().resize((kind.count_bits().unwrap_or(0x80) + 7) / 8, 0);
52    }
53}
54
55#[derive(Copy, Clone)]
56/// A set of bits that can be indexed by specific enum values.
57pub struct Bitmask<T: BitmaskTrait> {
58    mask: T::Array,
59}
60
61impl<T: BitmaskTrait> Default for Bitmask<T> {
62    fn default() -> Self {
63        Bitmask {
64            mask: T::array_default(),
65        }
66    }
67}
68
69impl<T: BitmaskTrait> Bitmask<T> {
70    /// A new empty bitmask.
71    pub const EMPTY: Self = Self {
72        mask: T::ZERO,
73    };
74
75    /// Extracts the underlying bitmask data.
76    pub fn into_inner(self) -> T::Array {
77        self.mask
78    }
79
80    /// Iterates over all set bits.
81    pub fn iter(&self) -> BitmaskIterator<T> {
82        self.into_iter()
83    }
84
85    /// Borrows the underlying bitmask data.
86    pub fn data(&self) -> &T::Array {
87        &self.mask
88    }
89
90    /// Mutably borrows the underlying bitmask data.
91    pub fn data_mut(&mut self) -> &mut T::Array {
92        &mut self.mask
93    }
94
95    fn slice(&self) -> &[u8] {
96        T::array_slice(&self.mask)
97    }
98
99    fn slice_mut(&mut self) -> &mut [u8] {
100        T::array_slice_mut(&mut self.mask)
101    }
102
103    fn index(index: T::Index) -> (usize, usize) {
104        let index = T::index(index);
105        (index / 8, index % 8)
106    }
107
108    fn index_valid(&self, index: T::Index) -> bool {
109        T::index_valid(&self.mask, index)
110    }
111
112    /// Unset all bits in the bitmask.
113    pub fn clear(&mut self) {
114        for b in self.slice_mut() {
115            *b = 0;
116        }
117    }
118
119    /// Gets the status of an index in the bitmask.
120    pub fn get(&self, index: T::Index) -> bool {
121        let (offset, shift) = Self::index(index);
122        (self.slice()[offset] & (1u8 << shift)) != 0
123    }
124
125    /// Sets the status of an index in the bitmask.
126    pub fn insert(&mut self, index: T::Index) {
127        let (offset, shift) = Self::index(index);
128        let v = &mut self.slice_mut()[offset];
129        *v |= 1u8 << shift;
130    }
131
132    /// Clears the status of an index in the bitmask.
133    pub fn remove(&mut self, index: T::Index) {
134        let (offset, shift) = Self::index(index);
135        let v = &mut self.slice_mut()[offset];
136        *v &= !(1u8 << shift);
137    }
138
139    /// Inverts the status of an index in the bitmask.
140    pub fn toggle(&mut self, index: T::Index) {
141        let (offset, shift) = Self::index(index);
142        self.slice_mut()[offset] ^= 1u8 << shift;
143    }
144
145    /// Merges the provided indices into the bitmask.
146    pub fn or<I: IntoIterator<Item=T::Index>>(&mut self, indices: I) {
147        for index in indices {
148            self.insert(index);
149        }
150    }
151}
152
153impl<'a, T: BitmaskTrait> IntoIterator for &'a Bitmask<T> {
154    type Item = T::Index;
155    type IntoIter = BitmaskIterator<'a, T>;
156
157    fn into_iter(self) -> Self::IntoIter {
158        BitmaskIterator {
159            mask: self,
160            iter: T::Index::iter(),
161        }
162    }
163}
164
165/// An iterator over the set bits of a bitmask.
166pub struct BitmaskIterator<'a, T: BitmaskTrait + 'a> {
167    mask: &'a Bitmask<T>,
168    iter: EnumIterator<T::Index>,
169}
170
171impl<'a, T: BitmaskTrait> Iterator for BitmaskIterator<'a, T> {
172    type Item = T::Index;
173
174    fn next(&mut self) -> Option<Self::Item> {
175        let mask = &self.mask;
176        self.iter.by_ref().take_while(|i| mask.index_valid(*i)).find(|i| mask.get(*i))
177    }
178}
179
180impl<T: BitmaskTrait> fmt::Debug for Bitmask<T> where T::Index: fmt::Debug {
181    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
182        f.debug_list().entries(self.into_iter()).finish()
183    }
184}
185
186impl<T: BitmaskTrait> Deref for Bitmask<T> {
187    type Target = [u8];
188
189    fn deref(&self) -> &Self::Target {
190        self.slice()
191    }
192}
193
194impl<T: BitmaskTrait> DerefMut for Bitmask<T> {
195    fn deref_mut(&mut self) -> &mut Self::Target {
196        self.slice_mut()
197    }
198}
199
200impl<T: BitmaskTrait> AsRef<[u8]> for Bitmask<T> {
201    fn as_ref(&self) -> &[u8] {
202        self.slice()
203    }
204}
205
206impl<T: BitmaskTrait> AsMut<[u8]> for Bitmask<T> {
207    fn as_mut(&mut self) -> &mut [u8] {
208        self.slice_mut()
209    }
210}