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