1#![cfg(feature = "bitvec")]
2use crate::HeaplessBitVec;
9use bitvec::prelude::{BitOrder, BitSlice, BitVec, Lsb0};
10use core::mem::ManuallyDrop;
11use core::ops::{Deref, DerefMut};
12use core::ptr;
13use std::borrow::{Borrow, BorrowMut};
14
15pub trait AnyBitVec {
17 fn len(&self) -> usize;
19
20 fn is_empty(&self) -> bool {
22 self.len() == 0
23 }
24
25 fn get(&self, index: usize) -> Option<bool>;
27}
28
29impl<O: BitOrder> AnyBitVec for BitVec<u8, O> {
30 fn len(&self) -> usize {
31 self.as_bitslice().len()
32 }
33 fn get(&self, index: usize) -> Option<bool> {
34 self.as_bitslice().get(index).map(|b| *b)
35 }
36}
37
38pub struct SmallBitVec<const N: usize, O: BitOrder = Lsb0> {
60 on_stack: bool,
61 data: BitData<N, O>,
62}
63
64union BitData<const N: usize, O: BitOrder> {
66 stack: ManuallyDrop<HeaplessBitVec<N, O>>,
67 heap: ManuallyDrop<BitVec<u8, O>>,
69}
70
71impl<const N: usize, O: BitOrder> SmallBitVec<N, O> {
72 pub fn new() -> Self {
78 const {
79 assert!(
80 std::mem::size_of::<Self>() <= 16 * 1024,
81 "SmallBitVec is too large! Reduce N."
82 );
83 }
84 Self {
85 on_stack: true,
86 data: BitData {
87 stack: ManuallyDrop::new(HeaplessBitVec::new()),
88 },
89 }
90 }
91
92 #[inline(always)]
94 pub fn len(&self) -> usize {
95 unsafe {
96 if self.on_stack {
97 self.data.stack.len()
98 } else {
99 self.data.heap.len()
100 }
101 }
102 }
103
104 #[inline(always)]
106 pub fn is_empty(&self) -> bool {
107 self.len() == 0
108 }
109
110 #[inline(always)]
112 pub fn is_on_stack(&self) -> bool {
113 self.on_stack
114 }
115
116 #[inline(always)]
120 pub fn push(&mut self, value: bool) {
121 unsafe {
122 if self.on_stack {
123 let stack = &mut *self.data.stack;
124 if let Err(_) = stack.push(value) {
126 self.spill_to_heap();
128 (*self.data.heap).push(value);
129 }
130 } else {
131 (*self.data.heap).push(value);
132 }
133 }
134 }
135
136 #[inline(always)]
138 pub fn pop(&mut self) -> Option<bool> {
139 unsafe {
140 if self.on_stack {
141 (*self.data.stack).pop()
142 } else {
143 (*self.data.heap).pop()
144 }
145 }
146 }
147
148 #[inline(always)]
150 pub fn get(&self, index: usize) -> Option<bool> {
151 unsafe {
152 if self.on_stack {
153 self.data.stack.get(index)
154 } else {
155 self.data.heap.get(index)
156 }
157 }
158 }
159
160 #[inline(always)]
165 pub fn set(&mut self, index: usize, value: bool) {
166 unsafe {
167 if self.on_stack {
168 (*self.data.stack).set(index, value);
169 } else {
170 (*self.data.heap).set(index, value);
171 }
172 }
173 }
174
175 pub fn as_bitslice(&self) -> &BitSlice<u8, O> {
177 unsafe {
178 if self.on_stack {
179 self.data.stack.as_bitslice()
180 } else {
181 self.data.heap.as_bitslice()
182 }
183 }
184 }
185
186 pub fn as_bitslice_mut(&mut self) -> &mut BitSlice<u8, O> {
188 unsafe {
189 if self.on_stack {
190 (*self.data.stack).as_bitslice_mut()
191 } else {
192 (*self.data.heap).as_mut_bitslice()
193 }
194 }
195 }
196
197 #[inline(never)]
200 unsafe fn spill_to_heap(&mut self) {
201 unsafe {
202 let stack = ManuallyDrop::take(&mut self.data.stack);
203
204 let mut heap_vec: BitVec<u8, O> = BitVec::from_slice(stack.as_raw_slice());
206
207 heap_vec.truncate(stack.len());
209
210 heap_vec.reserve(stack.len());
212
213 ptr::write(&mut self.data.heap, ManuallyDrop::new(heap_vec));
217 self.on_stack = false;
218 }
219 }
220}
221
222impl<const N: usize, O: BitOrder> Deref for SmallBitVec<N, O> {
223 type Target = BitSlice<u8, O>;
224
225 fn deref(&self) -> &Self::Target {
226 self.as_bitslice()
227 }
228}
229
230impl<const N: usize, O: BitOrder> DerefMut for SmallBitVec<N, O> {
231 fn deref_mut(&mut self) -> &mut Self::Target {
232 self.as_bitslice_mut()
233 }
234}
235
236impl<const N: usize, O: BitOrder> Borrow<BitSlice<u8, O>> for SmallBitVec<N, O> {
237 fn borrow(&self) -> &BitSlice<u8, O> {
238 self.as_bitslice()
239 }
240}
241
242impl<const N: usize, O: BitOrder> BorrowMut<BitSlice<u8, O>> for SmallBitVec<N, O> {
243 fn borrow_mut(&mut self) -> &mut BitSlice<u8, O> {
244 self.as_bitslice_mut()
245 }
246}
247
248impl<const N: usize, O: BitOrder> AnyBitVec for SmallBitVec<N, O> {
251 fn len(&self) -> usize {
252 self.len()
253 }
254
255 fn get(&self, index: usize) -> Option<bool> {
256 self.get(index)
257 }
258}
259
260impl<const N: usize, O: BitOrder> Drop for SmallBitVec<N, O> {
261 fn drop(&mut self) {
262 unsafe {
263 if self.on_stack {
264 ManuallyDrop::drop(&mut self.data.stack);
265 } else {
266 ManuallyDrop::drop(&mut self.data.heap);
267 }
268 }
269 }
270}
271
272impl<const N: usize, O: BitOrder> Clone for SmallBitVec<N, O> {
273 fn clone(&self) -> Self {
274 unsafe {
275 if self.on_stack {
276 SmallBitVec {
277 on_stack: true,
278 data: BitData {
279 stack: self.data.stack.clone(),
280 },
281 }
282 } else {
283 SmallBitVec {
284 on_stack: false,
285 data: BitData {
286 heap: self.data.heap.clone(),
287 },
288 }
289 }
290 }
291 }
292}
293
294impl<const N: usize, O: BitOrder> core::fmt::Debug for SmallBitVec<N, O> {
295 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
296 f.write_str("SmallBitVec [")?;
297 for i in 0..self.len() {
298 if self.get(i).unwrap_or(false) {
299 f.write_str("1")?;
300 } else {
301 f.write_str("0")?;
302 }
303 if (i + 1) % 8 == 0 && i + 1 != self.len() {
304 f.write_str("_")?;
305 }
306 }
307 f.write_str("]")
308 }
309}
310
311impl<const N: usize, O: BitOrder> Default for SmallBitVec<N, O> {
312 fn default() -> Self {
313 Self::new()
314 }
315}
316
317#[cfg(test)]
318mod bitvec_basic_tests {
319 use super::*;
320 use bitvec::prelude::{Lsb0, Msb0};
321
322 #[test]
323 fn test_bitvec_traits_bitslice() {
324 use std::borrow::BorrowMut;
325 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
326 sbv.push(true);
327 sbv.push(false);
328
329 let slice: &bitvec::slice::BitSlice<u8, Lsb0> = &sbv;
331 assert_eq!(slice.len(), 2);
332
333 let slice_mut: &mut bitvec::slice::BitSlice<u8, Lsb0> = sbv.borrow_mut();
335 slice_mut.set(1, true);
336 assert_eq!(sbv.get(1), Some(true));
337
338 for _ in 0..10 {
340 sbv.push(true);
341 }
342 assert!(!sbv.is_on_stack());
343
344 let slice_heap: &bitvec::slice::BitSlice<u8, Lsb0> = &sbv;
345 assert_eq!(slice_heap.len(), 12);
346 }
347
348 #[test]
349 fn test_bitvec_spill_trigger_lsb0() {
350 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
351 for _ in 0..8 {
352 sbv.push(true);
353 }
354 assert!(sbv.is_on_stack());
355 assert_eq!(sbv.len(), 8);
356
357 sbv.push(false); assert!(!sbv.is_on_stack());
359 assert_eq!(sbv.len(), 9);
360 assert_eq!(sbv.get(0), Some(true));
361 assert_eq!(sbv.get(8), Some(false));
362 }
363
364 #[test]
365 fn test_bitvec_spill_trigger_msb0() {
366 let mut sbv: SmallBitVec<1, Msb0> = SmallBitVec::new();
367 sbv.push(true); sbv.push(false); for _ in 0..6 {
370 sbv.push(true);
371 }
372 assert!(sbv.is_on_stack());
373
374 sbv.push(true); assert!(!sbv.is_on_stack());
376 assert_eq!(sbv.get(0), Some(true));
377 assert_eq!(sbv.get(1), Some(false));
378 }
379
380 #[test]
381 fn test_bitvec_any_storage_pop_set() {
382 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
383 sbv.push(true);
384 sbv.push(false);
385 assert_eq!(sbv.pop(), Some(false));
386 sbv.set(0, false);
387 assert_eq!(sbv.get(0), Some(false));
388
389 for _ in 0..10 {
390 sbv.push(true);
391 }
392 assert!(!sbv.is_on_stack());
393 sbv.set(10, false);
394 assert_eq!(sbv.get(10), Some(false));
395 assert_eq!(sbv.pop(), Some(false));
396 }
397
398 #[test]
399 fn test_bitvec_traits_debug_default() {
400 let sbv: SmallBitVec<1, Lsb0> = SmallBitVec::default();
401 assert!(sbv.is_empty());
402
403 let mut sbv2 = SmallBitVec::<1, Lsb0>::new();
404 sbv2.push(true);
405 sbv2.push(false);
406 let debug = format!("{:?}", sbv2);
407 assert!(debug.contains("10"));
408 }
409
410 #[test]
411 fn test_bitvec_any_storage_pop_empty() {
412 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
413 assert_eq!(sbv.pop(), None);
414 }
415
416 #[test]
417 fn test_bitvec_any_storage_get_none() {
418 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
419 assert_eq!(sbv.get(10), None);
420
421 for _ in 0..10 {
422 sbv.push(true);
423 }
424 assert_eq!(sbv.get(100), None);
425 }
426
427 #[test]
428 fn test_bitvec_traits_debug_multi_byte() {
429 let mut sbv2: SmallBitVec<2, Lsb0> = SmallBitVec::new();
430 for _ in 0..16 {
431 sbv2.push(true);
432 }
433 let debug = format!("{:?}", sbv2);
434 assert!(debug.contains("_"));
435 }
436
437 #[test]
438 fn test_bitvec_traits_any_bitvec_impl() {
439 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
440 sbv.push(true);
441 sbv.push(false);
442
443 let any: &dyn AnyBitVec = &sbv;
444 assert_eq!(any.len(), 2);
445 assert_eq!(any.get(0), Some(true));
446 assert_eq!(any.get(1), Some(false));
447 }
448}
449
450#[cfg(test)]
451mod bitvec_coverage_tests {
452 use super::*;
453 use bitvec::prelude::Lsb0;
454
455 #[test]
456 fn test_any_bitvec_is_empty() {
457 struct MockAny;
458 impl AnyBitVec for MockAny {
459 fn len(&self) -> usize {
460 0
461 }
462 fn get(&self, _index: usize) -> Option<bool> {
463 None
464 }
465 }
466 let m = MockAny;
467 assert!(m.is_empty());
468
469 let mut b: BitVec<u8, Lsb0> = BitVec::new();
470 {
471 let any_b: &dyn AnyBitVec = &b;
472 assert_eq!(any_b.len(), 0);
473 }
474 b.push(true);
475 {
476 let any_b: &dyn AnyBitVec = &b;
477 assert_eq!(any_b.get(0), Some(true));
478 }
479 }
480
481 #[test]
482 fn test_small_bitvec_traits_and_heap() {
483 use core::ops::DerefMut;
484 use std::borrow::Borrow;
485
486 let mut sbv: SmallBitVec<1, Lsb0> = SmallBitVec::new();
487 sbv.push(true);
488
489 let any: &dyn AnyBitVec = &sbv;
491 assert_eq!(any.len(), 1);
492 assert_eq!(any.get(0), Some(true));
493
494 let borrowed: &bitvec::slice::BitSlice<u8, Lsb0> = sbv.borrow();
496 assert_eq!(borrowed.len(), 1);
497
498 let cloned_stack = sbv.clone();
500 assert_eq!(cloned_stack.len(), 1);
501
502 for _ in 0..10 {
504 sbv.push(false);
505 }
506 let mut_slice = sbv.deref_mut();
507 mut_slice.set(1, true);
508
509 let cloned_heap = sbv.clone();
511 assert_eq!(cloned_heap.len(), 11);
512 }
513}