1use crate::std_facade::{fmt, Vec};
20use core::marker::PhantomData;
21use core::mem;
22
23#[cfg(feature = "bit-set")]
24use bit_set::BitSet;
25use rand::{self, seq::IteratorRandom, Rng};
26
27use crate::collection::SizeRange;
28use crate::num::sample_uniform_incl;
29use crate::strategy::*;
30use crate::test_runner::*;
31
32#[cfg_attr(feature = "cargo-clippy", allow(len_without_is_empty))]
34pub trait BitSetLike: Clone + fmt::Debug {
35 fn new_bitset(max: usize) -> Self;
38 fn len(&self) -> usize;
40 fn test(&self, ix: usize) -> bool;
42 fn set(&mut self, ix: usize);
44 fn clear(&mut self, ix: usize);
46 fn count(&self) -> usize {
52 let mut n = 0;
53 for i in 0..self.len() {
54 if self.test(i) {
55 n += 1;
56 }
57 }
58 n
59 }
60}
61
62macro_rules! int_bitset {
63 ($typ:ty) => {
64 impl BitSetLike for $typ {
65 fn new_bitset(_: usize) -> Self {
66 0
67 }
68 fn len(&self) -> usize {
69 mem::size_of::<$typ>() * 8
70 }
71 fn test(&self, ix: usize) -> bool {
72 0 != (*self & ((1 as $typ) << ix))
73 }
74 fn set(&mut self, ix: usize) {
75 *self |= (1 as $typ) << ix;
76 }
77 fn clear(&mut self, ix: usize) {
78 *self &= !((1 as $typ) << ix);
79 }
80 fn count(&self) -> usize {
81 self.count_ones() as usize
82 }
83 }
84 };
85}
86int_bitset!(u8);
87int_bitset!(u16);
88int_bitset!(u32);
89int_bitset!(u64);
90int_bitset!(usize);
91int_bitset!(i8);
92int_bitset!(i16);
93int_bitset!(i32);
94int_bitset!(i64);
95int_bitset!(isize);
96
97#[cfg(feature = "bit-set")]
98impl BitSetLike for BitSet {
99 fn new_bitset(max: usize) -> Self {
100 BitSet::with_capacity(max)
101 }
102
103 fn len(&self) -> usize {
104 self.capacity()
105 }
106
107 fn test(&self, bit: usize) -> bool {
108 self.contains(bit)
109 }
110
111 fn set(&mut self, bit: usize) {
112 self.insert(bit);
113 }
114
115 fn clear(&mut self, bit: usize) {
116 self.remove(bit);
117 }
118
119 fn count(&self) -> usize {
120 self.len()
121 }
122}
123
124impl BitSetLike for Vec<bool> {
125 fn new_bitset(max: usize) -> Self {
126 vec![false; max]
127 }
128
129 fn len(&self) -> usize {
130 self.len()
131 }
132
133 fn test(&self, bit: usize) -> bool {
134 if bit >= self.len() {
135 false
136 } else {
137 self[bit]
138 }
139 }
140
141 fn set(&mut self, bit: usize) {
142 if bit >= self.len() {
143 self.resize(bit + 1, false);
144 }
145
146 self[bit] = true;
147 }
148
149 fn clear(&mut self, bit: usize) {
150 if bit < self.len() {
151 self[bit] = false;
152 }
153 }
154
155 fn count(&self) -> usize {
156 self.iter().filter(|&&b| b).count()
157 }
158}
159
160#[must_use = "strategies do nothing unless used"]
165#[derive(Clone, Copy, Debug)]
166pub struct BitSetStrategy<T: BitSetLike> {
167 min: usize,
168 max: usize,
169 mask: Option<T>,
170}
171
172impl<T: BitSetLike> BitSetStrategy<T> {
173 pub fn new(min: usize, max: usize) -> Self {
179 BitSetStrategy {
180 min,
181 max,
182 mask: None,
183 }
184 }
185
186 pub fn masked(mask: T) -> Self {
189 BitSetStrategy {
190 min: 0,
191 max: mask.len(),
192 mask: Some(mask),
193 }
194 }
195}
196
197impl<T: BitSetLike> Strategy for BitSetStrategy<T> {
198 type Tree = BitSetValueTree<T>;
199 type Value = T;
200
201 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
202 let mut inner = T::new_bitset(self.max);
203 for bit in self.min..self.max {
204 if self.mask.as_ref().map_or(true, |mask| mask.test(bit))
205 && runner.rng().gen()
206 {
207 inner.set(bit);
208 }
209 }
210
211 Ok(BitSetValueTree {
212 inner,
213 shrink: self.min,
214 prev_shrink: None,
215 min_count: 0,
216 })
217 }
218}
219
220#[derive(Clone, Debug)]
228#[must_use = "strategies do nothing unless used"]
229pub struct SampledBitSetStrategy<T: BitSetLike> {
230 size: SizeRange,
231 bits: SizeRange,
232 _marker: PhantomData<T>,
233}
234
235impl<T: BitSetLike> SampledBitSetStrategy<T> {
236 pub fn new(size: impl Into<SizeRange>, bits: impl Into<SizeRange>) -> Self {
248 let size = size.into();
249 let bits = bits.into();
250 size.assert_nonempty();
251
252 let available_bits = bits.end_excl() - bits.start();
253 assert!(
254 size.end_excl() <= available_bits + 1,
255 "Illegal SampledBitSetStrategy: have {} bits available, \
256 but requested size is {}..{}",
257 available_bits,
258 size.start(),
259 size.end_excl()
260 );
261 SampledBitSetStrategy {
262 size,
263 bits,
264 _marker: PhantomData,
265 }
266 }
267}
268
269impl<T: BitSetLike> Strategy for SampledBitSetStrategy<T> {
270 type Tree = BitSetValueTree<T>;
271 type Value = T;
272
273 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
274 let mut bits = T::new_bitset(self.bits.end_excl());
275 let count = sample_uniform_incl(
276 runner,
277 self.size.start(),
278 self.size.end_incl(),
279 );
280 if bits.len() < count {
281 panic!("not enough bits to sample");
282 }
283
284 for bit in self.bits.iter().choose_multiple(runner.rng(), count) {
285 bits.set(bit);
286 }
287
288 Ok(BitSetValueTree {
289 inner: bits,
290 shrink: self.bits.start(),
291 prev_shrink: None,
292 min_count: self.size.start(),
293 })
294 }
295}
296
297#[derive(Clone, Copy, Debug)]
299pub struct BitSetValueTree<T: BitSetLike> {
300 inner: T,
301 shrink: usize,
302 prev_shrink: Option<usize>,
303 min_count: usize,
304}
305
306impl<T: BitSetLike> ValueTree for BitSetValueTree<T> {
307 type Value = T;
308
309 fn current(&self) -> T {
310 self.inner.clone()
311 }
312
313 fn simplify(&mut self) -> bool {
314 if self.inner.count() <= self.min_count {
315 return false;
316 }
317
318 while self.shrink < self.inner.len() && !self.inner.test(self.shrink) {
319 self.shrink += 1;
320 }
321
322 if self.shrink >= self.inner.len() {
323 self.prev_shrink = None;
324 false
325 } else {
326 self.prev_shrink = Some(self.shrink);
327 self.inner.clear(self.shrink);
328 self.shrink += 1;
329 true
330 }
331 }
332
333 fn complicate(&mut self) -> bool {
334 if let Some(bit) = self.prev_shrink.take() {
335 self.inner.set(bit);
336 true
337 } else {
338 false
339 }
340 }
341}
342
343macro_rules! int_api {
344 ($typ:ident, $max:expr) => {
345 #[allow(missing_docs)]
346 pub mod $typ {
347 use super::*;
348
349 pub const ANY: BitSetStrategy<$typ> = BitSetStrategy {
351 min: 0,
352 max: $max,
353 mask: None,
354 };
355
356 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
359 BitSetStrategy::new(min, max)
360 }
361
362 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
365 BitSetStrategy::masked(mask)
366 }
367
368 pub fn sampled(
377 size: impl Into<SizeRange>,
378 bits: impl Into<SizeRange>,
379 ) -> SampledBitSetStrategy<$typ> {
380 SampledBitSetStrategy::new(size, bits)
381 }
382 }
383 };
384}
385
386int_api!(u8, 8);
387int_api!(u16, 16);
388int_api!(u32, 32);
389int_api!(u64, 64);
390int_api!(i8, 8);
391int_api!(i16, 16);
392int_api!(i32, 32);
393int_api!(i64, 64);
394
395macro_rules! minimal_api {
396 ($md:ident, $typ:ty) => {
397 #[allow(missing_docs)]
398 pub mod $md {
399 use super::*;
400
401 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
404 BitSetStrategy::new(min, max)
405 }
406
407 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
410 BitSetStrategy::masked(mask)
411 }
412
413 pub fn sampled(
422 size: impl Into<SizeRange>,
423 bits: impl Into<SizeRange>,
424 ) -> SampledBitSetStrategy<$typ> {
425 SampledBitSetStrategy::new(size, bits)
426 }
427 }
428 };
429}
430minimal_api!(usize, usize);
431minimal_api!(isize, isize);
432#[cfg(feature = "bit-set")]
433minimal_api!(bitset, BitSet);
434minimal_api!(bool_vec, Vec<bool>);
435
436pub(crate) mod varsize {
437 use super::*;
438 use core::iter::FromIterator;
439
440 #[cfg(feature = "bit-set")]
441 type Inner = BitSet;
442 #[cfg(not(feature = "bit-set"))]
443 type Inner = Vec<bool>;
444
445 #[derive(Debug, Clone)]
446 pub(crate) struct VarBitSet(Inner);
447
448 impl VarBitSet {
449 pub(crate) fn saturated(len: usize) -> Self {
450 (0..len).collect::<VarBitSet>()
451 }
452
453 #[cfg(not(feature = "bit-set"))]
454 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
455 (0..self.len()).into_iter().filter(move |&ix| self.test(ix))
456 }
457
458 #[cfg(feature = "bit-set")]
459 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
460 self.0.iter()
461 }
462 }
463
464 impl BitSetLike for VarBitSet {
465 fn new_bitset(max: usize) -> Self {
466 VarBitSet(Inner::new_bitset(max))
467 }
468
469 fn len(&self) -> usize {
470 BitSetLike::len(&self.0)
471 }
472
473 fn test(&self, bit: usize) -> bool {
474 BitSetLike::test(&self.0, bit)
475 }
476
477 fn set(&mut self, bit: usize) {
478 BitSetLike::set(&mut self.0, bit);
479 }
480
481 fn clear(&mut self, bit: usize) {
482 BitSetLike::clear(&mut self.0, bit);
483 }
484
485 fn count(&self) -> usize {
486 BitSetLike::count(&self.0)
487 }
488 }
489
490 impl FromIterator<usize> for VarBitSet {
491 fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
492 let mut bits = VarBitSet::new_bitset(0);
493 for bit in iter {
494 bits.set(bit);
495 }
496 bits
497 }
498 }
499
500 pub(crate) fn sampled(
511 size: impl Into<SizeRange>,
512 bits: impl Into<SizeRange>,
513 ) -> SampledBitSetStrategy<VarBitSet> {
514 SampledBitSetStrategy::new(size, bits)
515 }
516}
517
518pub(crate) use self::varsize::VarBitSet;
519
520#[cfg(test)]
521mod test {
522 use super::*;
523
524 #[test]
525 fn generates_values_in_range() {
526 let input = u32::between(4, 8);
527
528 let mut runner = TestRunner::default();
529 for _ in 0..256 {
530 let value = input.new_tree(&mut runner).unwrap().current();
531 assert!(0 == value & !0xF0u32, "Generate value {}", value);
532 }
533 }
534
535 #[test]
536 fn generates_values_in_mask() {
537 let mut accum = 0;
538
539 let mut runner = TestRunner::deterministic();
540 let input = u32::masked(0xdeadbeef);
541 for _ in 0..1024 {
542 accum |= input.new_tree(&mut runner).unwrap().current();
543 }
544
545 assert_eq!(0xdeadbeef, accum);
546 }
547
548 #[cfg(feature = "bit-set")]
549 #[test]
550 fn mask_bounds_for_bitset_correct() {
551 let mut seen_0 = false;
552 let mut seen_2 = false;
553
554 let mut mask = BitSet::new();
555 mask.insert(0);
556 mask.insert(2);
557
558 let mut runner = TestRunner::deterministic();
559 let input = bitset::masked(mask);
560 for _ in 0..32 {
561 let v = input.new_tree(&mut runner).unwrap().current();
562 seen_0 |= v.contains(0);
563 seen_2 |= v.contains(2);
564 }
565
566 assert!(seen_0);
567 assert!(seen_2);
568 }
569
570 #[test]
571 fn mask_bounds_for_vecbool_correct() {
572 let mut seen_0 = false;
573 let mut seen_2 = false;
574
575 let mask = vec![true, false, true, false];
576
577 let mut runner = TestRunner::deterministic();
578 let input = bool_vec::masked(mask);
579 for _ in 0..32 {
580 let v = input.new_tree(&mut runner).unwrap().current();
581 assert_eq!(4, v.len());
582 seen_0 |= v[0];
583 seen_2 |= v[2];
584 }
585
586 assert!(seen_0);
587 assert!(seen_2);
588 }
589
590 #[test]
591 fn shrinks_to_zero() {
592 let input = u32::between(4, 24);
593
594 let mut runner = TestRunner::default();
595 for _ in 0..256 {
596 let mut value = input.new_tree(&mut runner).unwrap();
597 let mut prev = value.current();
598 while value.simplify() {
599 let v = value.current();
600 assert!(
601 1 == (prev & !v).count_ones(),
602 "Shrank from {} to {}",
603 prev,
604 v
605 );
606 prev = v;
607 }
608
609 assert_eq!(0, value.current());
610 }
611 }
612
613 #[test]
614 fn complicates_to_previous() {
615 let input = u32::between(4, 24);
616
617 let mut runner = TestRunner::default();
618 for _ in 0..256 {
619 let mut value = input.new_tree(&mut runner).unwrap();
620 let orig = value.current();
621 if value.simplify() {
622 assert!(value.complicate());
623 assert_eq!(orig, value.current());
624 }
625 }
626 }
627
628 #[test]
629 fn sampled_selects_correct_sizes_and_bits() {
630 let input = u32::sampled(4..8, 10..20);
631 let mut seen_counts = [0; 32];
632 let mut seen_bits = [0; 32];
633
634 let mut runner = TestRunner::deterministic();
635 for _ in 0..2048 {
636 let value = input.new_tree(&mut runner).unwrap().current();
637 let count = value.count_ones() as usize;
638 assert!(count >= 4 && count < 8);
639 seen_counts[count] += 1;
640
641 for bit in 0..32 {
642 if 0 != value & (1 << bit) {
643 assert!(bit >= 10 && bit < 20);
644 seen_bits[bit] += value;
645 }
646 }
647 }
648
649 for i in 4..8 {
650 assert!(seen_counts[i] >= 256 && seen_counts[i] < 1024);
651 }
652
653 let least_seen_bit_count =
654 seen_bits[10..20].iter().cloned().min().unwrap();
655 let most_seen_bit_count =
656 seen_bits[10..20].iter().cloned().max().unwrap();
657 assert_eq!(1, most_seen_bit_count / least_seen_bit_count);
658 }
659
660 #[test]
661 fn sampled_doesnt_shrink_below_min_size() {
662 let input = u32::sampled(4..8, 10..20);
663
664 let mut runner = TestRunner::default();
665 for _ in 0..256 {
666 let mut value = input.new_tree(&mut runner).unwrap();
667 while value.simplify() {}
668
669 assert_eq!(4, value.current().count_ones());
670 }
671 }
672
673 #[test]
674 fn test_sanity() {
675 check_strategy_sanity(u32::masked(0xdeadbeef), None);
676 }
677}