1#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
2
3use core::ops::Range;
4
5use num_traits::sign::Unsigned;
6pub use quickcheck::*;
7
8pub trait GenRange {
9 fn gen_range<T: Unsigned + Arbitrary + Copy>(&mut self, _range: Range<T>) -> T;
10
11 fn gen_index(&mut self, ubound: usize) -> usize {
12 if ubound <= (u32::MAX as usize) {
13 self.gen_range(0..ubound as u32) as usize
14 } else {
15 self.gen_range(0..ubound)
16 }
17 }
18}
19
20impl GenRange for Gen {
21 fn gen_range<T: Unsigned + Arbitrary + Copy>(&mut self, range: Range<T>) -> T {
22 <T as Arbitrary>::arbitrary(self) % (range.end - range.start) + range.start
23 }
24}
25
26pub trait SliceRandom {
27 fn shuffle<T>(&mut self, arr: &mut [T]);
28 fn choose_multiple<'a, T>(
29 &mut self,
30 arr: &'a [T],
31 amount: usize,
32 ) -> std::iter::Take<std::vec::IntoIter<&'a T>> {
33 let mut v: Vec<&T> = arr.iter().collect();
34 self.shuffle(&mut v);
35 v.into_iter().take(amount)
36 }
37}
38
39impl SliceRandom for Gen {
40 fn shuffle<T>(&mut self, arr: &mut [T]) {
41 for i in (1..arr.len()).rev() {
42 arr.swap(i, self.gen_index(i + 1));
44 }
45 }
46}