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!(usize);
93int_bitset!(i8);
94int_bitset!(i16);
95int_bitset!(i32);
96int_bitset!(i64);
97int_bitset!(isize);
98
99#[cfg(feature = "bit-set")]
100#[cfg_attr(docsrs, doc(cfg(feature = "bit-set")))]
101impl BitSetLike for BitSet {
102 fn new_bitset(max: usize) -> Self {
103 BitSet::with_capacity(max)
104 }
105
106 fn len(&self) -> usize {
107 self.capacity()
108 }
109
110 fn test(&self, bit: usize) -> bool {
111 self.contains(bit)
112 }
113
114 fn set(&mut self, bit: usize) {
115 self.insert(bit);
116 }
117
118 fn clear(&mut self, bit: usize) {
119 self.remove(bit);
120 }
121
122 fn count(&self) -> usize {
123 self.len()
124 }
125}
126
127impl BitSetLike for Vec<bool> {
128 fn new_bitset(max: usize) -> Self {
129 vec![false; max]
130 }
131
132 fn len(&self) -> usize {
133 self.len()
134 }
135
136 fn test(&self, bit: usize) -> bool {
137 if bit >= self.len() {
138 false
139 } else {
140 self[bit]
141 }
142 }
143
144 fn set(&mut self, bit: usize) {
145 if bit >= self.len() {
146 self.resize(bit + 1, false);
147 }
148
149 self[bit] = true;
150 }
151
152 fn clear(&mut self, bit: usize) {
153 if bit < self.len() {
154 self[bit] = false;
155 }
156 }
157
158 fn count(&self) -> usize {
159 self.iter().filter(|&&b| b).count()
160 }
161}
162
163#[must_use = "strategies do nothing unless used"]
168#[derive(Clone, Copy, Debug)]
169pub struct BitSetStrategy<T: BitSetLike> {
170 min: usize,
171 max: usize,
172 mask: Option<T>,
173}
174
175impl<T: BitSetLike> BitSetStrategy<T> {
176 pub fn new(min: usize, max: usize) -> Self {
182 BitSetStrategy {
183 min,
184 max,
185 mask: None,
186 }
187 }
188
189 pub fn masked(mask: T) -> Self {
192 BitSetStrategy {
193 min: 0,
194 max: mask.len(),
195 mask: Some(mask),
196 }
197 }
198}
199
200impl<T: BitSetLike> Strategy for BitSetStrategy<T> {
201 type Tree = BitSetValueTree<T>;
202 type Value = T;
203
204 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
205 let mut inner = T::new_bitset(self.max);
206 for bit in self.min..self.max {
207 if self.mask.as_ref().map_or(true, |mask| mask.test(bit))
208 && runner.rng().gen()
209 {
210 inner.set(bit);
211 }
212 }
213
214 Ok(BitSetValueTree {
215 inner,
216 shrink: self.min,
217 prev_shrink: None,
218 min_count: 0,
219 })
220 }
221}
222
223#[derive(Clone, Debug)]
231#[must_use = "strategies do nothing unless used"]
232pub struct SampledBitSetStrategy<T: BitSetLike> {
233 size: SizeRange,
234 bits: SizeRange,
235 _marker: PhantomData<T>,
236}
237
238impl<T: BitSetLike> SampledBitSetStrategy<T> {
239 pub fn new(size: impl Into<SizeRange>, bits: impl Into<SizeRange>) -> Self {
251 let size = size.into();
252 let bits = bits.into();
253 size.assert_nonempty();
254
255 let available_bits = bits.end_excl() - bits.start();
256 assert!(
257 size.end_excl() <= available_bits + 1,
258 "Illegal SampledBitSetStrategy: have {} bits available, \
259 but requested size is {}..{}",
260 available_bits,
261 size.start(),
262 size.end_excl()
263 );
264 SampledBitSetStrategy {
265 size,
266 bits,
267 _marker: PhantomData,
268 }
269 }
270}
271
272impl<T: BitSetLike> Strategy for SampledBitSetStrategy<T> {
273 type Tree = BitSetValueTree<T>;
274 type Value = T;
275
276 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
277 let mut bits = T::new_bitset(self.bits.end_excl());
278 let count = sample_uniform_incl(
279 runner,
280 self.size.start(),
281 self.size.end_incl(),
282 );
283 if bits.len() < count {
284 panic!("not enough bits to sample");
285 }
286
287 for bit in self.bits.iter().choose_multiple(runner.rng(), count) {
288 bits.set(bit);
289 }
290
291 Ok(BitSetValueTree {
292 inner: bits,
293 shrink: self.bits.start(),
294 prev_shrink: None,
295 min_count: self.size.start(),
296 })
297 }
298}
299
300#[derive(Clone, Copy, Debug)]
302pub struct BitSetValueTree<T: BitSetLike> {
303 inner: T,
304 shrink: usize,
305 prev_shrink: Option<usize>,
306 min_count: usize,
307}
308
309impl<T: BitSetLike> ValueTree for BitSetValueTree<T> {
310 type Value = T;
311
312 fn current(&self) -> T {
313 self.inner.clone()
314 }
315
316 fn simplify(&mut self) -> bool {
317 if self.inner.count() <= self.min_count {
318 return false;
319 }
320
321 while self.shrink < self.inner.len() && !self.inner.test(self.shrink) {
322 self.shrink += 1;
323 }
324
325 if self.shrink >= self.inner.len() {
326 self.prev_shrink = None;
327 false
328 } else {
329 self.prev_shrink = Some(self.shrink);
330 self.inner.clear(self.shrink);
331 self.shrink += 1;
332 true
333 }
334 }
335
336 fn complicate(&mut self) -> bool {
337 if let Some(bit) = self.prev_shrink.take() {
338 self.inner.set(bit);
339 true
340 } else {
341 false
342 }
343 }
344}
345
346macro_rules! int_api {
347 ($typ:ident, $max:expr) => {
348 #[allow(missing_docs)]
349 pub mod $typ {
350 use super::*;
351
352 pub const ANY: BitSetStrategy<$typ> = BitSetStrategy {
354 min: 0,
355 max: $max,
356 mask: None,
357 };
358
359 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
362 BitSetStrategy::new(min, max)
363 }
364
365 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
368 BitSetStrategy::masked(mask)
369 }
370
371 pub fn sampled(
380 size: impl Into<SizeRange>,
381 bits: impl Into<SizeRange>,
382 ) -> SampledBitSetStrategy<$typ> {
383 SampledBitSetStrategy::new(size, bits)
384 }
385 }
386 };
387}
388
389int_api!(u8, 8);
390int_api!(u16, 16);
391int_api!(u32, 32);
392int_api!(u64, 64);
393int_api!(i8, 8);
394int_api!(i16, 16);
395int_api!(i32, 32);
396int_api!(i64, 64);
397
398macro_rules! minimal_api {
399 ($md:ident, $typ:ty) => {
400 #[allow(missing_docs)]
401 pub mod $md {
402 use super::*;
403
404 pub fn between(min: usize, max: usize) -> BitSetStrategy<$typ> {
407 BitSetStrategy::new(min, max)
408 }
409
410 pub fn masked(mask: $typ) -> BitSetStrategy<$typ> {
413 BitSetStrategy::masked(mask)
414 }
415
416 pub fn sampled(
425 size: impl Into<SizeRange>,
426 bits: impl Into<SizeRange>,
427 ) -> SampledBitSetStrategy<$typ> {
428 SampledBitSetStrategy::new(size, bits)
429 }
430 }
431 };
432}
433minimal_api!(usize, usize);
434minimal_api!(isize, isize);
435#[cfg(feature = "bit-set")]
436#[cfg_attr(docsrs, doc(cfg(feature = "bit-set")))]
437minimal_api!(bitset, BitSet);
438minimal_api!(bool_vec, Vec<bool>);
439
440pub(crate) mod varsize {
441 use super::*;
442 use core::iter::FromIterator;
443
444 #[cfg(feature = "bit-set")]
445 type Inner = BitSet;
446 #[cfg(not(feature = "bit-set"))]
447 type Inner = Vec<bool>;
448
449 #[derive(Debug, Clone)]
451 pub struct VarBitSet(Inner);
452
453 impl VarBitSet {
454 #[cfg(not(feature = "bit-set"))]
456 pub fn saturated(len: usize) -> Self {
457 Self(vec![true; len])
458 }
459
460 #[cfg(feature = "bit-set")]
462 pub fn saturated(len: usize) -> Self {
463 Self(BitSet::from_bit_vec(BitVec::from_elem(len, true)))
464 }
465
466 #[cfg(not(feature = "bit-set"))]
467 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
468 (0..self.len()).into_iter().filter(move |&ix| self.test(ix))
469 }
470
471 #[cfg(feature = "bit-set")]
472 pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
473 self.0.iter()
474 }
475 }
476
477 impl BitSetLike for VarBitSet {
478 fn new_bitset(max: usize) -> Self {
479 VarBitSet(Inner::new_bitset(max))
480 }
481
482 fn len(&self) -> usize {
483 BitSetLike::len(&self.0)
484 }
485
486 fn test(&self, bit: usize) -> bool {
487 BitSetLike::test(&self.0, bit)
488 }
489
490 fn set(&mut self, bit: usize) {
491 BitSetLike::set(&mut self.0, bit);
492 }
493
494 fn clear(&mut self, bit: usize) {
495 BitSetLike::clear(&mut self.0, bit);
496 }
497
498 fn count(&self) -> usize {
499 BitSetLike::count(&self.0)
500 }
501 }
502
503 impl FromIterator<usize> for VarBitSet {
504 fn from_iter<T: IntoIterator<Item = usize>>(into_iter: T) -> Self {
505 let iter = into_iter.into_iter();
506 let lower_bound = iter.size_hint().0;
507 let mut bits = VarBitSet::new_bitset(lower_bound);
508 for bit in iter {
509 bits.set(bit);
510 }
511 bits
512 }
513 }
514
515 pub(crate) fn sampled(
526 size: impl Into<SizeRange>,
527 bits: impl Into<SizeRange>,
528 ) -> SampledBitSetStrategy<VarBitSet> {
529 SampledBitSetStrategy::new(size, bits)
530 }
531}
532
533pub use self::varsize::VarBitSet;
534
535#[cfg(test)]
536mod test {
537 use super::*;
538
539 #[test]
540 fn generates_values_in_range() {
541 let input = u32::between(4, 8);
542
543 let mut runner = TestRunner::default();
544 for _ in 0..256 {
545 let value = input.new_tree(&mut runner).unwrap().current();
546 assert!(0 == value & !0xF0u32, "Generate value {}", value);
547 }
548 }
549
550 #[test]
551 fn generates_values_in_mask() {
552 let mut accum = 0;
553
554 let mut runner = TestRunner::deterministic();
555 let input = u32::masked(0xdeadbeef);
556 for _ in 0..1024 {
557 accum |= input.new_tree(&mut runner).unwrap().current();
558 }
559
560 assert_eq!(0xdeadbeef, accum);
561 }
562
563 #[cfg(feature = "bit-set")]
564 #[test]
565 fn mask_bounds_for_bitset_correct() {
566 let mut seen_0 = false;
567 let mut seen_2 = false;
568
569 let mut mask = BitSet::new();
570 mask.insert(0);
571 mask.insert(2);
572
573 let mut runner = TestRunner::deterministic();
574 let input = bitset::masked(mask);
575 for _ in 0..32 {
576 let v = input.new_tree(&mut runner).unwrap().current();
577 seen_0 |= v.contains(0);
578 seen_2 |= v.contains(2);
579 }
580
581 assert!(seen_0);
582 assert!(seen_2);
583 }
584
585 #[test]
586 fn mask_bounds_for_vecbool_correct() {
587 let mut seen_0 = false;
588 let mut seen_2 = false;
589
590 let mask = vec![true, false, true, false];
591
592 let mut runner = TestRunner::deterministic();
593 let input = bool_vec::masked(mask);
594 for _ in 0..32 {
595 let v = input.new_tree(&mut runner).unwrap().current();
596 assert_eq!(4, v.len());
597 seen_0 |= v[0];
598 seen_2 |= v[2];
599 }
600
601 assert!(seen_0);
602 assert!(seen_2);
603 }
604
605 #[test]
606 fn shrinks_to_zero() {
607 let input = u32::between(4, 24);
608
609 let mut runner = TestRunner::default();
610 for _ in 0..256 {
611 let mut value = input.new_tree(&mut runner).unwrap();
612 let mut prev = value.current();
613 while value.simplify() {
614 let v = value.current();
615 assert!(
616 1 == (prev & !v).count_ones(),
617 "Shrank from {} to {}",
618 prev,
619 v
620 );
621 prev = v;
622 }
623
624 assert_eq!(0, value.current());
625 }
626 }
627
628 #[test]
629 fn complicates_to_previous() {
630 let input = u32::between(4, 24);
631
632 let mut runner = TestRunner::default();
633 for _ in 0..256 {
634 let mut value = input.new_tree(&mut runner).unwrap();
635 let orig = value.current();
636 if value.simplify() {
637 assert!(value.complicate());
638 assert_eq!(orig, value.current());
639 }
640 }
641 }
642
643 #[test]
644 fn sampled_selects_correct_sizes_and_bits() {
645 let input = u32::sampled(4..8, 10..20);
646 let mut seen_counts = [0; 32];
647 let mut seen_bits = [0; 32];
648
649 let mut runner = TestRunner::deterministic();
650 for _ in 0..2048 {
651 let value = input.new_tree(&mut runner).unwrap().current();
652 let count = value.count_ones() as usize;
653 assert!(count >= 4 && count < 8);
654 seen_counts[count] += 1;
655
656 for bit in 0..32 {
657 if 0 != value & (1 << bit) {
658 assert!(bit >= 10 && bit < 20);
659 seen_bits[bit] += value;
660 }
661 }
662 }
663
664 for i in 4..8 {
665 assert!(seen_counts[i] >= 256 && seen_counts[i] < 1024);
666 }
667
668 let least_seen_bit_count =
669 seen_bits[10..20].iter().cloned().min().unwrap();
670 let most_seen_bit_count =
671 seen_bits[10..20].iter().cloned().max().unwrap();
672 assert_eq!(1, most_seen_bit_count / least_seen_bit_count);
673 }
674
675 #[test]
676 fn sampled_doesnt_shrink_below_min_size() {
677 let input = u32::sampled(4..8, 10..20);
678
679 let mut runner = TestRunner::default();
680 for _ in 0..256 {
681 let mut value = input.new_tree(&mut runner).unwrap();
682 while value.simplify() {}
683
684 assert_eq!(4, value.current().count_ones());
685 }
686 }
687
688 #[test]
689 fn test_sanity() {
690 check_strategy_sanity(u32::masked(0xdeadbeef), None);
691 }
692}