Skip to content

Commit 8f7b37e

Browse files
committed
Feat: Add generators for type isize
1 parent ff60c1c commit 8f7b37e

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

src/gens.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod float_parts;
99
mod from_fn;
1010
mod int_bounds;
1111
mod integer;
12+
pub mod isize;
1213
mod map;
1314
mod mix;
1415
mod other_shrink;

src/gens/isize.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//! Generators for values of type `isize`.
2+
3+
// Please note! This module does not use the integer_module macro, since the
4+
// underlying rand library does not support isize directly. For details, see:
5+
// https://rust-random.github.io/book/update-0.9.html
6+
//
7+
// The code here should be similar to what the macro would have generated, but
8+
// is piggybacking on the generators for type `i64` and just maps to type
9+
// `isize`.
10+
11+
use super::int_bounds;
12+
use crate::BoxGen;
13+
use crate::*;
14+
use core::panic;
15+
use std::ops::{RangeBounds, RangeInclusive};
16+
17+
/// Roughly uniformly distributed unbound range of values, with
18+
/// some overwheight to extremes (min and max).
19+
pub fn any() -> BoxGen<isize> {
20+
ranged(..)
21+
}
22+
23+
/// Roughly uniformly distributed range of values, with some
24+
/// overwheight to extremes (min and max) of given bounds.
25+
pub fn ranged<B>(bounds: B) -> BoxGen<isize>
26+
where
27+
B: RangeBounds<isize>,
28+
{
29+
assert_lib_supports_isize_bit_width();
30+
let i64_bounds = map_to_i64_bounds(&bounds);
31+
map_to_isize_gen(super::i64::ranged(i64_bounds))
32+
}
33+
34+
/// Int generator with completely random distribution. This
35+
/// function has a long name, since `ranged` should be preferred.
36+
pub fn completely_random<B>(bounds: B) -> BoxGen<isize>
37+
where
38+
B: RangeBounds<isize>,
39+
{
40+
assert_lib_supports_isize_bit_width();
41+
let i64_bounds = map_to_i64_bounds(&bounds);
42+
map_to_isize_gen(super::i64::completely_random(i64_bounds))
43+
}
44+
45+
/// Maps isize bounds to i64 bounds.
46+
fn map_to_i64_bounds<B>(i_bounds: &B) -> RangeInclusive<i64>
47+
where
48+
B: RangeBounds<isize>,
49+
{
50+
let start: isize = int_bounds::start(i_bounds);
51+
let end: isize = int_bounds::end(i_bounds);
52+
(start as i64)..=(end as i64)
53+
}
54+
55+
/// Maps `i64` generator to a `isize` generator.
56+
fn map_to_isize_gen(gen: BoxGen<i64>) -> BoxGen<isize> {
57+
gen.map(|i| i as isize, |j| j as i64)
58+
}
59+
60+
/// Ensure that the library supports the bit width of isize on this platform.
61+
fn assert_lib_supports_isize_bit_width() {
62+
if isize::BITS > i64::BITS {
63+
panic!(
64+
"Generators for isize only support platforms where isize is at most \
65+
64 bits wide. \
66+
Please contact the library author for support for wider isize types.");
67+
}
68+
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use crate::testing::distribution::assert_generator_has_distribution_within_percent;
73+
use crate::testing::distribution::distribution_from_pairs;
74+
75+
/// Generator values should be evenly distributed within range.
76+
#[test]
77+
fn random_inclusive_has_uniform_distribution() {
78+
assert_generator_has_distribution_within_percent(
79+
super::completely_random(-10isize..=10isize),
80+
distribution_from_pairs(&[
81+
(1, -10isize),
82+
(1, -9isize),
83+
(1, -8isize),
84+
(1, -7isize),
85+
(1, -6isize),
86+
(1, -5isize),
87+
(1, -4isize),
88+
(1, -3isize),
89+
(1, -2isize),
90+
(1, -1isize),
91+
(1, 0isize),
92+
(1, 1isize),
93+
(1, 2isize),
94+
(1, 3isize),
95+
(1, 4isize),
96+
(1, 5isize),
97+
(1, 6isize),
98+
(1, 7isize),
99+
(1, 8isize),
100+
(1, 9isize),
101+
(1, 10isize),
102+
]),
103+
2.0, // 2% tolerance
104+
);
105+
}
106+
}

0 commit comments

Comments
 (0)