1use crate::std_facade::{fmt, Vec};
20use core::marker::PhantomData;
21use core::mem;
22
23#[cfg(feature = "bit-set")]
24use bit_set::BitSet;
25#[cfg(feature = "bit-set")]
26use bit_vec::BitVec;
27use rand::{self, seq::IteratorRandom, Rng};
28
29use crate::collection::SizeRange;
30use crate::num::sample_uniform_incl;
31use crate::strategy::*;
32use crate::test_runner::*;
33
34#[cfg_attr(clippy, allow(len_without_is_empty))]
36pub trait BitSetLike: Clone + fmt::Debug {
37 fn new_bitset(max: usize) -> Self;
40 fn len(&self) -> usize;
42 fn test(&self, ix: usize) -> bool;
44 fn set(&mut self, ix: usize);
46 fn clear(&mut self, ix: usize);
48 fn count(&self) -> usize {
54 let mut n = 0;
55 for i in 0..self.len() {
56 if self.test(i) {
57 n += 1;
58 }
59 }
60 n
61 }
62}
63
64macro_rules! int_bitset {
65 ($typ:ty) => {
66 impl BitSetLike for $typ {
67 fn new_bitset(_: usize) -> Self {
68 0
69 }
70 fn len(&self) -> usize {
71 mem::size_of::<$typ>() * 8
72 }
73 fn test(&self, ix: usize) -> bool {
74 0 != (*self & ((1 as $typ) << ix))
75 }
76 fn set(&mut self, ix: usize) {
77 *self |= (1 as $typ) << ix;
78 }
79 fn clear(&mut self, ix: usize) {
80 *self &= !((1 as $typ) << ix);
81 }
82 fn count(&self) -> usize {
83 self.count_ones() as usize
84 }
85 }
86 };
87}
88int_bitset!(u8);
89int_bitset!(u16);
90int_bitset!(u32);
91int_bitset!(u64);
92int_bitset!(u128);
93int_bitset!(usize);
94int_bitset!(i8);
95int_bitset!(i16);
96int_bitset!(i32);
97int_bitset!(i64);
98int_bitset!(i128);
99int_bitset!(isize);
100
101#[cfg(feature = "bit-set")]
102#[cfg_attr(docsrs, doc(cfg(feature = "bit-set")))]
103impl BitSetLike for BitSet {
104 fn new_bitset(max: usize) -> Self {
105 BitSet::with_capacity(max)
106 }
107
108 fn len(&self) -> usize {
109 self.capacity()
110 }
111
112 fn test(&self, bit: usize) -> bool {
113 self.contains(bit)
114 }
115
116 fn set(&mut self, bit: usize) {
117 self.insert(bit);
118 }
119
120 fn clear(&mut self, bit: usize) {
121 self.remove(bit);
122 }
123
124 fn count(&self) -> usize {
125 self.len()
126 }
127}
128
129impl BitSetLike for Vec<bool> {
130 fn new_bitset(max: usize) -> Self {
131 vec![false; max]
132 }
133
134 fn len(&self) -> usize {
135 self.len()
136 }
137
138 fn test(&self, bit: usize) -> bool {
139 if bit >= self.len() {
140 false
141 } else {
142 self[bit]
143 }
144 }
145
146 fn set(&mut self, bit: usize) {
147 if bit >= self.len() {
148 self.resize(bit + 1, false);
149 }
150
151 self[bit] = true;
152 }
153
154 fn clear(&mut self, bit: usize) {
155 if bit < self.len() {
156 self[bit] = false;
157 }
158 }
159
160 fn count(&self) -> usize {
161 self.iter().filter(|&&b| b).count()
162 }
163}
164
165#[must_use = "strategies do nothing unless used"]
170#[derive(Clone, Copy, Debug)]
171pub struct BitSetStrategy<T: BitSetLike> {
172 min: usize,
173 max: usize,
174 mask: Option<T>,
175}
176
177impl<T: BitSetLike> BitSetStrategy<T> {
178 pub fn new(min: usize, max: usize) -> Self {
184 BitSetStrategy {
185 min,
186 max,
187 mask: None,
188 }
189 }
190
191 pub fn masked(mask: T) -> Self {
194 BitSetStrategy {
195 min: 0,
196 max: mask.len(),
197 mask: Some(mask),
198 }
199 }
200}
201
202impl<T: BitSetLike> Strategy for BitSetStrategy<T> {
203 type Tree = BitSetValueTree<T>;
204 type Value = T;
205
206 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
207 let mut inner = T::new_bitset(self.max);
208 for bit in self.min..self.max {
209 if self.mask.as_ref().map_or(true, |mask| mask.test(bit))
210 && runner.rng().random()
211 {
212 inner.set(bit);
213 }
214 }
215
216 Ok(BitSetValueTree {
217 inner,
218 shrink: self.min,
219 prev_shrink: None,
220 min_count: 0,
221 })
222 }
223}
224
225#[derive(Clone, Debug)]
233#[must_use = "strategies do nothing unless used"]
234pub struct SampledBitSetStrategy<T: BitSetLike> {
235 size: SizeRange,
236 bits: SizeRange,
237 _marker: PhantomData<T>,
238}
239
240impl<T: BitSetLike> SampledBitSetStrategy<T> {
241 pub fn new(size: impl Into<SizeRange>, bits: impl Into<SizeRange>) -> Self {
253 let size = size.into();
254 let bits = bits.into();
255 size.assert_nonempty();
256
257 let available_bits = bits.end_excl() - bits.start();
258 assert!(
259 size.end_excl() <= available_bits + 1,
260 "Illegal SampledBitSetStrategy: have {} bits available, \
261 but requested size is {}..{}",
262 available_bits,
263 size.start(),
264 size.end_excl()
265 );
266 SampledBitSetStrategy {
267 size,
268 bits,
269 _marker: PhantomData,
270 }
271 }
272}
273
274impl<T: BitSetLike> Strategy for SampledBitSetStrategy<T> {
275 type Tree = BitSetValueTree<T>;
276 type Value = T;
277
278 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
279 let mut bits = T::new_bitset(self.bits.end_excl());
280 let count = sample_uniform_incl(
281 runner,
282 self.size.start(),
283 self.size.end_incl(),
284 );
285 if bits.len() < count {
286 panic!("not enough bits to sample");
287 }
288
289 for bit in self.bits.iter().choose_multiple(runner.rng(), count) {
290 bits.set(bit);
291 }
292
293 Ok(BitSetValueTree {
294 inner: bits,
295 shrink: self.bits.start(),
296 prev_shrink: None,
297 min_count: self.size.start(),
298 })
299 }
300}
301
302#[derive(Clone, Copy, Debug)]
304pub struct BitSetValueTree<T: BitSetLike> {
305 inner: T,
306 shrink: usize,
307 prev_shrink: Option<usize>,
308 min_count: usize,
309}
310
311impl<T: BitSetLike> ValueTree for BitSetValueTree<T> {
312 type Value = T;
313
314 fn current(&self) -> T {
315 self.inner.clone()
316 }
317
318 fn simplify(&mut self) -> bool {
319 if self.inner.count() <= self.min_count {
320 return false;
321 }
322
323 while self.shrink < self.inner.len() && !self.inner.test(self.shrink) {
324 self.shrink += 1;
325 }
326
327 if self.shrink >= self.inner.len() {
328 self.prev_shrink = None;
329 false
330 } else {
331 self.prev_shrink = Some(self.shrink);
332 self.inner.clear(self.shrink);
333 self.shrink += 1;
334 true
335 }
336 }
337
338 fn complicate(&mut self) -> bool {
339 if let Some(bit) = self.prev_shrink.take() {
340 self.inner.set(bit);
341 true
342 } else {
343 false
344 }
345 }
346}
347
348macro_rules! int_api {
349 ($typ:ident, $max:expr) => {
350 #[allow(missing_docs)]
351 pub mod $typ {
352 use super::*;
353
354 pub const ANY: BitSetStrategy<$typ> = BitSetStrategy {
356 min: 0,
357 max: $max,
358 mask: None,
359 };
360
361 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
364 BitSetStrategy::new(min, max)
365 }
366
367 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
370 BitSetStrategy::masked(mask)
371 }
372
373 pub fn sampled(
382 size: impl Into<SizeRange>,
383 bits: impl Into<SizeRange>,
384 ) -> SampledBitSetStrategy<$typ> {
385 SampledBitSetStrategy::new(size, bits)
386 }
387 }
388 };
389}
390
391int_api!(u8, 8);
392int_api!(u16, 16);
393int_api!(u32, 32);
394int_api!(u64, 64);
395int_api!(u128, 128);
396int_api!(i8, 8);
397int_api!(i16, 16);
398int_api!(i32, 32);
399int_api!(i64, 64);
400int_api!(i128, 128);
401
402macro_rules! minimal_api {
403 ($md:ident, $typ:ty) => {
404 #[allow(missing_docs)]
405 pub mod $md {
406 use super::*;
407
408 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
411 BitSetStrategy::new(min, max)
412 }
413
414 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
417 BitSetStrategy::masked(mask)
418 }
419
420 pub fn sampled(
429 size: impl Into<SizeRange>,
430 bits: impl Into<SizeRange>,
431 ) -> SampledBitSetStrategy<$typ> {
432 SampledBitSetStrategy::new(size, bits)
433 }
434 }
435 };
436}
437minimal_api!(usize, usize);
438minimal_api!(isize, isize);
439#[cfg(feature = "bit-set")]
440#[cfg_attr(docsrs, doc(cfg(feature = "bit-set")))]
441minimal_api!(bitset, BitSet);
442minimal_api!(bool_vec, Vec<bool>);
443
444pub(crate) mod varsize {
445 use super::*;
446 use core::iter::FromIterator;
447
448 #[cfg(feature = "bit-set")]
449 type Inner = BitSet;
450 #[cfg(not(feature = "bit-set"))]
451 type Inner = Vec<bool>;
452
453 #[derive(Debug, Clone)]
455 pub struct VarBitSet(Inner);
456
457 impl VarBitSet {
458 #[cfg(not(feature = "bit-set"))]
460 pub fn saturated(len: usize) -> Self {
461 Self(vec![true; len])
462 }
463
464 #[cfg(feature = "bit-set")]
466 pub fn saturated(len: usize) -> Self {
467 Self(BitSet::from_bit_vec(BitVec::from_elem(len, true)))
468 }
469
470 #[cfg(not(feature = "bit-set"))]
471 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
472 (0..self.len()).into_iter().filter(move |&ix| self.test(ix))
473 }
474
475 #[cfg(feature = "bit-set")]
476 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
477 self.0.iter()
478 }
479 }
480
481 impl BitSetLike for VarBitSet {
482 fn new_bitset(max: usize) -> Self {
483 VarBitSet(Inner::new_bitset(max))
484 }
485
486 fn len(&self) -> usize {
487 BitSetLike::len(&self.0)
488 }
489
490 fn test(&self, bit: usize) -> bool {
491 BitSetLike::test(&self.0, bit)
492 }
493
494 fn set(&mut self, bit: usize) {
495 BitSetLike::set(&mut self.0, bit);
496 }
497
498 fn clear(&mut self, bit: usize) {
499 BitSetLike::clear(&mut self.0, bit);
500 }
501
502 fn count(&self) -> usize {
503 BitSetLike::count(&self.0)
504 }
505 }
506
507 impl FromIterator<usize> for VarBitSet {
508 fn from_iter<T: IntoIterator<Item = usize>>(into_iter: T) -> Self {
509 let iter = into_iter.into_iter();
510 let lower_bound = iter.size_hint().0;
511 let mut bits = VarBitSet::new_bitset(lower_bound);
512 for bit in iter {
513 bits.set(bit);
514 }
515 bits
516 }
517 }
518
519 pub(crate) fn sampled(
530 size: impl Into<SizeRange>,
531 bits: impl Into<SizeRange>,
532 ) -> SampledBitSetStrategy<VarBitSet> {
533 SampledBitSetStrategy::new(size, bits)
534 }
535}
536
537pub use self::varsize::VarBitSet;
538
539#[cfg(test)]
540mod test {
541 use super::*;
542
543 #[test]
544 fn generates_values_in_range() {
545 let input = u32::between(4, 8);
546
547 let mut runner = TestRunner::default();
548 for _ in 0..256 {
549 let value = input.new_tree(&mut runner).unwrap().current();
550 assert!(0 == value & !0xF0u32, "Generate value {}", value);
551 }
552 }
553
554 #[test]
555 fn generates_values_in_mask() {
556 let mut accum = 0;
557
558 let mut runner = TestRunner::deterministic();
559 let input = u32::masked(0xdeadbeef);
560 for _ in 0..1024 {
561 accum |= input.new_tree(&mut runner).unwrap().current();
562 }
563
564 assert_eq!(0xdeadbeef, accum);
565 }
566
567 #[cfg(feature = "bit-set")]
568 #[test]
569 fn mask_bounds_for_bitset_correct() {
570 let mut seen_0 = false;
571 let mut seen_2 = false;
572
573 let mut mask = BitSet::new();
574 mask.insert(0);
575 mask.insert(2);
576
577 let mut runner = TestRunner::deterministic();
578 let input = bitset::masked(mask);
579 for _ in 0..32 {
580 let v = input.new_tree(&mut runner).unwrap().current();
581 seen_0 |= v.contains(0);
582 seen_2 |= v.contains(2);
583 }
584
585 assert!(seen_0);
586 assert!(seen_2);
587 }
588
589 #[test]
590 fn mask_bounds_for_vecbool_correct() {
591 let mut seen_0 = false;
592 let mut seen_2 = false;
593
594 let mask = vec![true, false, true, false];
595
596 let mut runner = TestRunner::deterministic();
597 let input = bool_vec::masked(mask);
598 for _ in 0..32 {
599 let v = input.new_tree(&mut runner).unwrap().current();
600 assert_eq!(4, v.len());
601 seen_0 |= v[0];
602 seen_2 |= v[2];
603 }
604
605 assert!(seen_0);
606 assert!(seen_2);
607 }
608
609 #[test]
610 fn shrinks_to_zero() {
611 let input = u32::between(4, 24);
612
613 let mut runner = TestRunner::default();
614 for _ in 0..256 {
615 let mut value = input.new_tree(&mut runner).unwrap();
616 let mut prev = value.current();
617 while value.simplify() {
618 let v = value.current();
619 assert!(
620 1 == (prev & !v).count_ones(),
621 "Shrank from {} to {}",
622 prev,
623 v
624 );
625 prev = v;
626 }
627
628 assert_eq!(0, value.current());
629 }
630 }
631
632 #[test]
633 fn complicates_to_previous() {
634 let input = u32::between(4, 24);
635
636 let mut runner = TestRunner::default();
637 for _ in 0..256 {
638 let mut value = input.new_tree(&mut runner).unwrap();
639 let orig = value.current();
640 if value.simplify() {
641 assert!(value.complicate());
642 assert_eq!(orig, value.current());
643 }
644 }
645 }
646
647 #[test]
648 fn sampled_selects_correct_sizes_and_bits() {
649 let input = u32::sampled(4..8, 10..20);
650 let mut seen_counts = [0; 32];
651 let mut seen_bits = [0; 32];
652
653 let mut runner = TestRunner::deterministic();
654 for _ in 0..2048 {
655 let value = input.new_tree(&mut runner).unwrap().current();
656 let count = value.count_ones() as usize;
657 assert!(count >= 4 && count < 8);
658 seen_counts[count] += 1;
659
660 for bit in 0..32 {
661 if 0 != value & (1 << bit) {
662 assert!(bit >= 10 && bit < 20);
663 seen_bits[bit] += value;
664 }
665 }
666 }
667
668 for i in 4..8 {
669 assert!(seen_counts[i] >= 256 && seen_counts[i] < 1024);
670 }
671
672 let least_seen_bit_count =
673 seen_bits[10..20].iter().cloned().min().unwrap();
674 let most_seen_bit_count =
675 seen_bits[10..20].iter().cloned().max().unwrap();
676 assert_eq!(1, most_seen_bit_count / least_seen_bit_count);
677 }
678
679 #[test]
680 fn sampled_doesnt_shrink_below_min_size() {
681 let input = u32::sampled(4..8, 10..20);
682
683 let mut runner = TestRunner::default();
684 for _ in 0..256 {
685 let mut value = input.new_tree(&mut runner).unwrap();
686 while value.simplify() {}
687
688 assert_eq!(4, value.current().count_ones());
689 }
690 }
691
692 #[test]
693 fn test_sanity() {
694 check_strategy_sanity(u32::masked(0xdeadbeef), None);
695 }
696
697 #[test]
698 fn u128_generates_values_in_range() {
699 let input = u128::between(64, 128);
700
701 let mut runner = TestRunner::default();
702 for _ in 0..256 {
703 let value = input.new_tree(&mut runner).unwrap().current();
704 assert!(
706 0 == value & ((1u128 << 64) - 1),
707 "Generated value has low bits set: {}",
708 value
709 );
710 }
711 }
712
713 #[test]
714 fn u128_shrinks_to_zero() {
715 let input = u128::between(64, 128);
716
717 let mut runner = TestRunner::default();
718 for _ in 0..256 {
719 let mut value = input.new_tree(&mut runner).unwrap();
720 while value.simplify() {}
721 assert_eq!(0, value.current());
722 }
723 }
724
725 #[test]
726 fn i128_generates_values_in_mask() {
727 let mut accum: i128 = 0;
728 let mask: i128 = 0x0123_4567_89ab_cdef_0123_4567_89ab_cdef;
729
730 let mut runner = TestRunner::deterministic();
731 let input = i128::masked(mask);
732 for _ in 0..1024 {
733 accum |= input.new_tree(&mut runner).unwrap().current();
734 }
735
736 assert_eq!(mask, accum);
737 }
738
739 #[test]
740 fn u128_test_sanity() {
741 check_strategy_sanity(
742 u128::masked(0xdeadbeef_cafebabe_12345678_9abcdef0),
743 None,
744 );
745 }
746}