odem_rs_util/random/
rayon_support.rs1use super::{RngGen, RngStream};
7use rayon::iter::{
8 IndexedParallelIterator, IntoParallelIterator, ParallelIterator,
9 plumbing::{Consumer, Producer, ProducerCallback, UnindexedConsumer, bridge},
10};
11
12pub struct RngStreamParIter<R: RngGen> {
43 stream: RngStream<R>,
44 reruns: usize,
48}
49
50impl<R: RngGen> RngStreamParIter<R> {
51 pub(super) fn new(stream: RngStream<R>) -> Self {
53 Self {
54 stream,
55 reruns: usize::MAX,
56 }
57 }
58}
59
60impl<R> ParallelIterator for RngStreamParIter<R>
61where
62 R: RngGen + Send,
63 R::State: Send,
64{
65 type Item = RngStream<R>;
66
67 fn drive_unindexed<C>(self, consumer: C) -> C::Result
68 where
69 C: UnindexedConsumer<Self::Item>,
70 {
71 bridge(self, consumer)
72 }
73
74 fn opt_len(&self) -> Option<usize> {
75 Some(self.reruns)
76 }
77}
78
79impl<R> IndexedParallelIterator for RngStreamParIter<R>
80where
81 R: RngGen + Send,
82 R::State: Send,
83{
84 fn len(&self) -> usize {
85 self.reruns
86 }
87
88 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result {
89 bridge(self, consumer)
90 }
91
92 fn with_producer<CB>(self, callback: CB) -> CB::Output
93 where
94 CB: ProducerCallback<Self::Item>,
95 {
96 let producer = StreamProducer(self);
97 callback.callback(producer)
98 }
99}
100
101impl<R> IntoParallelIterator for RngStream<R>
102where
103 R: RngGen + Send,
104 R::State: Send,
105{
106 type Iter = RngStreamParIter<R>;
107 type Item = RngStream<R>;
108
109 fn into_par_iter(self) -> Self::Iter {
110 RngStreamParIter::new(self)
111 }
112}
113
114impl<R: RngGen> Clone for RngStreamParIter<R>
115where
116 R::State: Clone,
117{
118 fn clone(&self) -> Self {
119 Self {
120 stream: self.stream.clone(),
121 reruns: self.reruns,
122 }
123 }
124}
125
126struct StreamProducer<R: RngGen>(RngStreamParIter<R>);
133
134impl<R: RngGen + Send> Producer for StreamProducer<R>
135where
136 R::State: Send,
137{
138 type Item = RngStream<R>;
139 type IntoIter = StreamIter<R>;
140
141 fn into_iter(self) -> Self::IntoIter {
142 StreamIter(self.0)
143 }
144
145 fn split_at(mut self, index: usize) -> (Self, Self) {
146 let left_stream_state = R::split_at(self.0.stream.0.get_mut(), index);
148
149 let left_iter = RngStreamParIter {
150 stream: RngStream::new(left_stream_state),
151 reruns: index,
152 };
153
154 self.0.reruns -= index;
156
157 (Self(left_iter), self)
158 }
159}
160
161struct StreamIter<R: RngGen>(RngStreamParIter<R>);
164
165impl<R: RngGen> Iterator for StreamIter<R> {
166 type Item = RngStream<R>;
167
168 fn next(&mut self) -> Option<Self::Item> {
169 if self.0.reruns > 0 {
170 self.0.reruns -= 1;
171
172 Some(RngStream::new(R::split_at(self.0.stream.0.get_mut(), 1)))
174 } else {
175 None
176 }
177 }
178
179 fn size_hint(&self) -> (usize, Option<usize>) {
180 (self.0.reruns, Some(self.0.reruns))
181 }
182
183 fn nth(&mut self, n: usize) -> Option<Self::Item> {
184 if self.0.reruns > n {
185 self.0.reruns -= n + 1;
186
187 let _left_state = R::split_at(self.0.stream.0.get_mut(), n);
189 Some(RngStream::new(R::split_at(self.0.stream.0.get_mut(), 1)))
190 } else {
191 self.0.reruns = 0;
192 None
193 }
194 }
195}
196
197impl<R: RngGen> DoubleEndedIterator for StreamIter<R> {
198 fn next_back(&mut self) -> Option<Self::Item> {
199 use core::mem::replace;
200 if self.0.reruns == 0 {
201 return None;
202 }
203
204 let new_state = self.0.stream.0.get_mut();
207 let old_state = R::split_at(new_state, self.0.reruns - 1);
208
209 let result_state = replace(new_state, old_state);
212
213 self.0.reruns -= 1;
214 Some(RngStream::new(result_state))
215 }
216}
217
218impl<R: RngGen> ExactSizeIterator for StreamIter<R> {}