1#[cfg(test)] extern crate bit_vec;
7extern crate rand;
8
9pub use iter::ShuffledIterGen;
10
11use std::num::Wrapping;
12use rand::Rng;
13
14mod iter;
15
16#[allow(non_camel_case_types)]
17type w32 = Wrapping<u32>;
18
19#[inline(always)]
20fn w32(u: u32) -> w32 {
21 Wrapping(u)
22}
23
24#[inline(always)]
25fn shl_ignore(slf: u32, rhs: u32) -> u32 {
26 if rhs >= 32 { 0 } else { slf << rhs }
27}
28
29#[inline(always)]
33fn gen_factor<R: Rng>(rng: &mut R) -> w32 {
34 w32((rng.next_u32() << 1) | 1)
35}
36
37#[inline(always)]
39fn gen_xor_op<R: Rng>(rng: &mut R) -> w32 {
40 w32(rng.next_u32())
41}
42
43#[derive(Copy, Clone, Debug)]
51pub struct ShuffledIter {
52 max: w32,
53 mask: w32,
54
55 index: w32,
56 count: w32,
57
58 f1: w32,
59 f2: w32,
60 x1: w32,
61 x2: w32,
62
63 done: bool,
64}
65
66impl ShuffledIter {
67 fn new<R: Rng>(max: u32, rng: &mut R) -> ShuffledIter {
68 let bits = 32 - max.leading_zeros();
69
70 let max = w32(max);
71
72 let mask = w32(shl_ignore(1, bits)) - w32(1);
73
74 ShuffledIter {
75 max: max,
76 mask: mask,
77
78 index: w32(rng.next_u32()),
79 count: w32(0),
80
81 f1: gen_factor(rng),
82 f2: gen_factor(rng),
83 x1: gen_xor_op(rng),
84 x2: gen_xor_op(rng),
85
86 done: false,
87 }
88 }
89
90 #[inline(always)]
91 fn next_value(&mut self) -> u32 {
92 self.index = self.index + w32(1);
93 self.count = self.count + w32(1);
94
95 let mut val = self.calc(self.index);
96
97 while val > self.max {
98 self.index = self.index + w32(1);
99 val = self.calc(self.index);
100 }
101
102 val.0
103 }
104
105 #[inline(always)]
106 fn calc(&self, val: w32) -> w32 {
107 ((((val * self.f1) ^ self.x1) * self.f2) ^ self.x2) & self.mask
108 }
109}
110
111impl Iterator for ShuffledIter {
112 type Item = u32;
113
114 #[inline]
115 fn next(&mut self) -> Option<u32> {
116 if self.count < self.max {
117 Some(self.next_value())
118 } else if self.done {
119 None
120 } else {
121 self.done = true;
122 self.count = self.count - w32(1);
123 Some(self.next_value())
125 }
126 }
127}
128
129#[test]
130fn gen_1_1024() {
131 use bit_vec::BitVec;
132 use rand::XorShiftRng;
133
134 let mut rng = XorShiftRng::new_unseeded();
135
136 for i in 0u32 .. 1025 {
137 let mut bv = BitVec::from_elem(i as usize + 1, false);
138
139 let it = ShuffledIter::new(i, &mut rng);
140
141 for j in it {
142 assert!(bv.get(j as usize) == Some(false));
143 bv.set(j as usize, true);
144 }
145
146 assert!(bv.all());
147 }
148}
149
150#[test]
151fn max_u32_max() {
152 use std::u32;
153 use rand::XorShiftRng;
154
155 let mut rng = XorShiftRng::new_unseeded();
156
157 let mut it = ShuffledIter::new(u32::MAX, &mut rng);
158
159 for _ in 0 .. 10 {
160 assert!(it.next().is_some());
161 }
162
163 it.count = w32(u32::MAX - 9);
164 for _ in 0 .. 10 {
167 assert!(it.next().is_some());
168 }
169
170 println!("{}", it.count.0);
171
172 assert!(it.next().is_none());
173}