avian2d/data_structures/
bit_vec.rs

1//! A minimalistic dynamically sized compact bit vector with a fixed block size of 64 bits.
2//!
3//! Only a very limited set of operations are supported.
4
5use core::ops::BitOrAssign;
6use core::slice;
7
8use bevy::reflect::Reflect;
9#[cfg(feature = "serialize")]
10use bevy::reflect::{ReflectDeserialize, ReflectSerialize};
11
12/// A dynamically sized compact bit vector with a fixed block size of 64 bits.
13#[derive(Clone, Debug, Default, Reflect)]
14#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
15#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
16#[reflect(Debug)]
17pub struct BitVec {
18    blocks: Vec<u64>,
19    block_capacity: usize,
20    block_count: usize,
21}
22
23#[inline]
24fn bits_to_blocks(bits: usize) -> usize {
25    bits.div_ceil(u64::BITS as usize)
26}
27
28impl BitVec {
29    /// Creates a new [`BitVec`] with the specified bit capacity.
30    #[inline]
31    pub fn new(bit_capacity: usize) -> Self {
32        let block_capacity = bits_to_blocks(bit_capacity);
33
34        Self {
35            blocks: vec![0; block_capacity * size_of::<u64>()],
36            block_capacity,
37            block_count: 0,
38        }
39    }
40
41    /// Sets the bit count of the [`BitVec`] and clears all bits.
42    ///
43    /// If the new bit count exceeds the current block capacity, the block capacity is increased.
44    #[inline]
45    pub fn set_bit_count_and_clear(&mut self, bit_count: usize) {
46        let block_count = bits_to_blocks(bit_count);
47
48        if self.block_capacity < block_count {
49            let new_bit_capacity = bit_count + (bit_count >> 1);
50            *self = Self::new(new_bit_capacity);
51        }
52
53        self.block_count = block_count;
54        self.blocks.iter_mut().for_each(|b| *b = 0);
55    }
56
57    /// Sets the bit at the specified index.
58    ///
59    /// # Panics
60    ///
61    /// Panics if the new bit count exceeds the current block capacity with `debug_assertions` enabled.
62    #[inline]
63    pub fn set(&mut self, index: usize) {
64        let block_index = index / 64;
65        debug_assert!(
66            block_index < self.block_count,
67            "block index out of bounds for `BitVec::set` ({} >= {})",
68            block_index,
69            self.block_count
70        );
71        let bit_index = index % 64;
72        let mask = 1 << bit_index;
73        self.blocks[block_index] |= mask;
74    }
75
76    /// Sets the specified bit and grows the [`BitVec`] if necessary.
77    #[inline]
78    pub fn set_and_grow(&mut self, index: usize) {
79        let block_index = index / 64;
80
81        if block_index >= self.block_count {
82            self.grow(block_index + 1);
83        }
84
85        let bit_index = index % 64;
86        let mask = 1 << bit_index;
87        self.blocks[block_index] |= mask;
88    }
89
90    /// Resizes the [`BitVec`] to the specified number of blocks.
91    ///
92    /// If the new block count exceeds the current capacity, the capacity is increased by half.
93    /// The blocks are not cleared.
94    #[inline]
95    pub fn grow(&mut self, new_block_count: usize) {
96        if new_block_count > self.block_capacity {
97            // Increase the block capacity by half if the new block count
98            // exceeds the current capacity.
99            let new_block_capacity = new_block_count + new_block_count / 2;
100            self.blocks.resize(new_block_capacity, 0);
101            self.block_capacity = new_block_capacity;
102        }
103
104        self.block_count = new_block_count;
105    }
106
107    /// Unsets the bit at the specified index.
108    #[inline]
109    pub fn unset(&mut self, index: usize) {
110        let block_index = index / 64;
111
112        if block_index >= self.block_count {
113            return;
114        }
115
116        let bit_index = index % 64;
117        let mask = 1 << bit_index;
118        self.blocks[block_index] &= !mask;
119    }
120
121    /// Gets the bit at the specified index.
122    ///
123    /// Returns `false` if the index is out of bounds or the bit is unset.
124    #[inline]
125    pub fn get(&self, index: usize) -> bool {
126        let block_index = index / 64;
127
128        if block_index >= self.block_count {
129            return false;
130        }
131
132        let bit_index = index % 64;
133        let mask = 1 << bit_index;
134        (self.blocks[block_index] & mask) != 0
135    }
136
137    /// Returns the block capacity of the [`BitVec`].
138    #[inline]
139    pub fn block_capacity(&self) -> usize {
140        self.block_capacity
141    }
142
143    /// Returns the block count of the [`BitVec`].
144    #[inline]
145    pub fn block_count(&self) -> usize {
146        self.block_count
147    }
148
149    /// Returns the number of set bits in the [`BitVec`].
150    #[inline]
151    pub fn count_ones(&self) -> usize {
152        self.blocks.iter().map(|&b| b.count_ones() as usize).sum()
153    }
154
155    /// Returns the number of unset bits in the [`BitVec`].
156    #[inline]
157    pub fn count_zeros(&self) -> usize {
158        self.block_count * 64 - self.count_ones()
159    }
160
161    /// Clears all bits in the [`BitVec`].
162    #[inline]
163    pub fn clear(&mut self) {
164        self.blocks.iter_mut().for_each(|b| *b = 0);
165    }
166
167    /// Returns an iterator over the blocks of the [`BitVec`].
168    #[inline]
169    pub fn blocks(&self) -> Blocks<'_> {
170        Blocks {
171            iter: self.blocks.iter(),
172        }
173    }
174
175    /// Performs an in-place bitwise OR operation with another [`BitVec`].
176    #[inline]
177    pub fn or(&mut self, other: &Self) {
178        debug_assert!(
179            self.block_count == other.block_count,
180            "block counts do not match for `BitVec::or` ({} != {})",
181            self.block_count,
182            other.block_count
183        );
184
185        for i in 0..self.block_count {
186            self.blocks[i] |= other.blocks[i];
187        }
188    }
189}
190
191impl BitOrAssign<&BitVec> for BitVec {
192    #[inline]
193    fn bitor_assign(&mut self, rhs: &BitVec) {
194        self.or(rhs);
195    }
196}
197
198/// An iterator over the blocks of a [`BitVec`].
199#[derive(Clone)]
200pub struct Blocks<'a> {
201    iter: slice::Iter<'a, u64>,
202}
203
204impl Iterator for Blocks<'_> {
205    type Item = u64;
206
207    #[inline]
208    fn next(&mut self) -> Option<u64> {
209        self.iter.next().cloned()
210    }
211
212    #[inline]
213    fn size_hint(&self) -> (usize, Option<usize>) {
214        self.iter.size_hint()
215    }
216}
217
218impl DoubleEndedIterator for Blocks<'_> {
219    #[inline]
220    fn next_back(&mut self) -> Option<u64> {
221        self.iter.next_back().cloned()
222    }
223}
224
225impl ExactSizeIterator for Blocks<'_> {}