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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use super::*;
use init_with::InitWith;
use std::mem;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
From)]
pub struct ArrayParamMod<A: Clone>(fn(usize, A) -> A);
impl<A: Clone> Default for ArrayParamMod<A> {
fn default() -> Self {
fn identity<A>(_: usize, x: A) -> A { x }
ArrayParamMod(identity)
}
}
type ArrayParams<A> = product_type![A, ArrayParamMod<A>];
macro_rules! impl_array {
($($n: expr),*) => {
$(
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for [A; $n]
where
ParamsType<'a, A>: Clone
{
valuetree!();
type Parameters = ArrayParams<A::Parameters>;
type Strategy = [A::Strategy; $n];
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
let product_unpack![mut curr, apm] = args;
let mut i = 0;
<[A::Strategy; $n]>::init_with(|| {
let next = (apm.0)(i, curr.clone());
let new = mem::replace(&mut curr, next);
i += 1;
any_with::<A>(new)
})
}
}
)*
};
}
impl_array!(
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
);