Skip to content

Commit a077ade

Browse files
authored
Merge pull request #279 from proptest-rs/const-generics
const generic support
2 parents 57cf7da + 875be9f commit a077ade

File tree

4 files changed

+108
-139
lines changed

4 files changed

+108
-139
lines changed

.github/workflows/rust.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
include:
2424
- build: pinned
2525
os: ubuntu-18.04
26-
rust: 1.50.0
26+
rust: 1.60.0
2727
- build: stable
2828
os: ubuntu-18.04
2929
rust: stable

proptest/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### New Features
99

10+
- Add `Arbitrary` impls for arrays of all sizes using const generics
1011
- Add `Arbitrary` impls for `core::num::NonZero*`
1112

1213
## 1.0.0

proptest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ break-dead-code = []
5757

5858
[dependencies]
5959
bitflags = "1.0.1"
60+
unarray = "0.1.4"
6061

6162
# [dependencies.hashmap_core]
6263
# version = "0.1.5"

proptest/src/array.rs

Lines changed: 105 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,24 @@ pub struct ArrayValueTree<T> {
8080
last_shrinker: Option<usize>,
8181
}
8282

83+
/// Create a strategy to generate fixed-length arrays.
84+
///
85+
/// All values within the new strategy are generated using the given
86+
/// strategy.
87+
///
88+
/// See [`UniformArrayStrategy`](struct.UniformArrayStrategy.html) for
89+
/// example usage.
90+
pub fn uniform<S: Strategy, const N: usize>(
91+
strategy: S,
92+
) -> UniformArrayStrategy<S, [S::Value; N]> {
93+
UniformArrayStrategy {
94+
strategy,
95+
_marker: PhantomData,
96+
}
97+
}
98+
8399
macro_rules! small_array {
84-
($n:tt $uni:ident : $($ix:expr),*) => {
100+
($n:tt $uni:ident) => {
85101
/// Create a strategy to generate fixed-length arrays.
86102
///
87103
/// All values within the new strategy are generated using the given
@@ -90,160 +106,111 @@ macro_rules! small_array {
90106
///
91107
/// See [`UniformArrayStrategy`](struct.UniformArrayStrategy.html) for
92108
/// example usage.
93-
pub fn $uni<S : Strategy>
94-
(strategy: S) -> UniformArrayStrategy<S, [S::Value; $n]>
95-
{
109+
pub fn $uni<S: Strategy>(
110+
strategy: S,
111+
) -> UniformArrayStrategy<S, [S::Value; $n]> {
96112
UniformArrayStrategy {
97113
strategy,
98-
_marker: PhantomData
114+
_marker: PhantomData,
99115
}
100116
}
117+
};
118+
}
101119

102-
impl<S : Strategy> Strategy for [S; $n] {
103-
type Tree = ArrayValueTree<[S::Tree; $n]>;
104-
type Value = [S::Value; $n];
105-
106-
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
107-
Ok(ArrayValueTree {
108-
tree: [$(self[$ix].new_tree(runner)?,)*],
109-
shrinker: 0,
110-
last_shrinker: None,
111-
})
112-
}
113-
}
120+
impl<S: Strategy, const N: usize> Strategy for [S; N] {
121+
type Tree = ArrayValueTree<[S::Tree; N]>;
122+
type Value = [S::Value; N];
114123

115-
impl<S : Strategy> Strategy
116-
for UniformArrayStrategy<S, [S::Value; $n]> {
117-
type Tree = ArrayValueTree<[S::Tree; $n]>;
118-
type Value = [S::Value; $n];
124+
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
125+
Ok(ArrayValueTree {
126+
tree: unarray::build_array_result(|i| self[i].new_tree(runner))?,
127+
shrinker: 0,
128+
last_shrinker: None,
129+
})
130+
}
131+
}
132+
impl<S: Strategy, const N: usize> Strategy
133+
for UniformArrayStrategy<S, [S::Value; N]>
134+
{
135+
type Tree = ArrayValueTree<[S::Tree; N]>;
136+
type Value = [S::Value; N];
119137

120-
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
121-
Ok(ArrayValueTree {
122-
tree: [$({
123-
let _ = $ix;
124-
self.strategy.new_tree(runner)?
125-
},)*],
126-
shrinker: 0,
127-
last_shrinker: None,
128-
})
129-
}
130-
}
138+
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
139+
Ok(ArrayValueTree {
140+
tree: unarray::build_array_result(|_| {
141+
self.strategy.new_tree(runner)
142+
})?,
143+
shrinker: 0,
144+
last_shrinker: None,
145+
})
146+
}
147+
}
148+
impl<T: ValueTree, const N: usize> ValueTree for ArrayValueTree<[T; N]> {
149+
type Value = [T::Value; N];
131150

132-
impl<T : ValueTree> ValueTree for ArrayValueTree<[T;$n]> {
133-
type Value = [T::Value;$n];
151+
fn current(&self) -> [T::Value; N] {
152+
unarray::build_array(|i| self.tree[i].current())
153+
}
134154

135-
fn current(&self) -> [T::Value;$n] {
136-
[$(self.tree[$ix].current(),)*]
155+
fn simplify(&mut self) -> bool {
156+
while self.shrinker < N {
157+
if self.tree[self.shrinker].simplify() {
158+
self.last_shrinker = Some(self.shrinker);
159+
return true;
160+
} else {
161+
self.shrinker += 1;
137162
}
163+
}
164+
false
165+
}
138166

139-
fn simplify(&mut self) -> bool {
140-
while self.shrinker < $n {
141-
if self.tree[self.shrinker].simplify() {
142-
self.last_shrinker = Some(self.shrinker);
143-
return true;
144-
} else {
145-
self.shrinker += 1;
146-
}
147-
}
148-
167+
fn complicate(&mut self) -> bool {
168+
if let Some(shrinker) = self.last_shrinker {
169+
self.shrinker = shrinker;
170+
if self.tree[shrinker].complicate() {
171+
true
172+
} else {
173+
self.last_shrinker = None;
149174
false
150175
}
151-
152-
fn complicate(&mut self) -> bool {
153-
if let Some(shrinker) = self.last_shrinker {
154-
self.shrinker = shrinker;
155-
if self.tree[shrinker].complicate() {
156-
true
157-
} else {
158-
self.last_shrinker = None;
159-
false
160-
}
161-
} else {
162-
false
163-
}
164-
}
176+
} else {
177+
false
165178
}
166179
}
167180
}
168181

169-
small_array!(1 uniform1:
170-
0);
171-
small_array!(2 uniform2:
172-
0, 1);
173-
small_array!(3 uniform3:
174-
0, 1, 2);
175-
small_array!(4 uniform4:
176-
0, 1, 2, 3);
177-
small_array!(5 uniform5:
178-
0, 1, 2, 3, 4);
179-
small_array!(6 uniform6:
180-
0, 1, 2, 3, 4, 5);
181-
small_array!(7 uniform7:
182-
0, 1, 2, 3, 4, 5, 6);
183-
small_array!(8 uniform8:
184-
0, 1, 2, 3, 4, 5, 6, 7);
185-
small_array!(9 uniform9:
186-
0, 1, 2, 3, 4, 5, 6, 7, 8);
187-
small_array!(10 uniform10:
188-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
189-
small_array!(11 uniform11:
190-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
191-
small_array!(12 uniform12:
192-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
193-
small_array!(13 uniform13:
194-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
195-
small_array!(14 uniform14:
196-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
197-
small_array!(15 uniform15:
198-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
199-
small_array!(16 uniform16:
200-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
201-
small_array!(17 uniform17:
202-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
203-
small_array!(18 uniform18:
204-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
205-
small_array!(19 uniform19:
206-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
207-
18);
208-
small_array!(20 uniform20:
209-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
210-
18, 19);
211-
small_array!(21 uniform21:
212-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
213-
18, 19, 20);
214-
small_array!(22 uniform22:
215-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
216-
18, 19, 20, 21);
217-
small_array!(23 uniform23:
218-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
219-
18, 19, 20, 21, 22);
220-
small_array!(24 uniform24:
221-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
222-
18, 19, 20, 21, 22, 23);
223-
small_array!(25 uniform25:
224-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
225-
18, 19, 20, 21, 22, 23, 24);
226-
small_array!(26 uniform26:
227-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
228-
18, 19, 20, 21, 22, 23, 24, 25);
229-
small_array!(27 uniform27:
230-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
231-
18, 19, 20, 21, 22, 23, 24, 25, 26);
232-
small_array!(28 uniform28:
233-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
234-
18, 19, 20, 21, 22, 23, 24, 25, 26, 27);
235-
small_array!(29 uniform29:
236-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
237-
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28);
238-
small_array!(30 uniform30:
239-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
240-
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
241-
small_array!(31 uniform31:
242-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
243-
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30);
244-
small_array!(32 uniform32:
245-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
246-
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
182+
small_array!(1 uniform1);
183+
small_array!(2 uniform2);
184+
small_array!(3 uniform3);
185+
small_array!(4 uniform4);
186+
small_array!(5 uniform5);
187+
small_array!(6 uniform6);
188+
small_array!(7 uniform7);
189+
small_array!(8 uniform8);
190+
small_array!(9 uniform9);
191+
small_array!(10 uniform10);
192+
small_array!(11 uniform11);
193+
small_array!(12 uniform12);
194+
small_array!(13 uniform13);
195+
small_array!(14 uniform14);
196+
small_array!(15 uniform15);
197+
small_array!(16 uniform16);
198+
small_array!(17 uniform17);
199+
small_array!(18 uniform18);
200+
small_array!(19 uniform19);
201+
small_array!(20 uniform20);
202+
small_array!(21 uniform21);
203+
small_array!(22 uniform22);
204+
small_array!(23 uniform23);
205+
small_array!(24 uniform24);
206+
small_array!(25 uniform25);
207+
small_array!(26 uniform26);
208+
small_array!(27 uniform27);
209+
small_array!(28 uniform28);
210+
small_array!(29 uniform29);
211+
small_array!(30 uniform30);
212+
small_array!(31 uniform31);
213+
small_array!(32 uniform32);
247214

248215
#[cfg(test)]
249216
mod test {

0 commit comments

Comments
 (0)