avian2d/data_structures/
bit_vec.rs1use core::ops::BitOrAssign;
6use core::slice;
7
8use bevy::reflect::Reflect;
9#[cfg(feature = "serialize")]
10use bevy::reflect::{ReflectDeserialize, ReflectSerialize};
11
12#[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 #[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 #[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 #[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 #[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 #[inline]
95 pub fn grow(&mut self, new_block_count: usize) {
96 if new_block_count > self.block_capacity {
97 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 #[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 #[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 #[inline]
139 pub fn block_capacity(&self) -> usize {
140 self.block_capacity
141 }
142
143 #[inline]
145 pub fn block_count(&self) -> usize {
146 self.block_count
147 }
148
149 #[inline]
151 pub fn count_ones(&self) -> usize {
152 self.blocks.iter().map(|&b| b.count_ones() as usize).sum()
153 }
154
155 #[inline]
157 pub fn count_zeros(&self) -> usize {
158 self.block_count * 64 - self.count_ones()
159 }
160
161 #[inline]
163 pub fn clear(&mut self) {
164 self.blocks.iter_mut().for_each(|b| *b = 0);
165 }
166
167 #[inline]
169 pub fn blocks(&self) -> Blocks<'_> {
170 Blocks {
171 iter: self.blocks.iter(),
172 }
173 }
174
175 #[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#[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<'_> {}