paralight/iter/source/
range.rs1use super::{
10 ExactParallelSource, ExactSourceDescriptor, IntoExactParallelSource,
11 SimpleExactSourceDescriptor, SourceCleanup,
12};
13#[cfg(feature = "nightly")]
14use std::iter::Step;
15use std::ops::{Range, RangeInclusive};
16
17pub struct RangeSourceDescriptor<T> {
18 start: T,
19 len: usize,
20}
21
22impl<T> SourceCleanup for RangeSourceDescriptor<T> {
23 const NEEDS_CLEANUP: bool = false;
24
25 fn len(&self) -> usize {
26 self.len
27 }
28
29 unsafe fn cleanup_item_range(&self, _range: Range<usize>) {
30 }
32}
33
34#[cfg(feature = "nightly")]
35impl<T: Step + Copy + Send + Sync> SimpleExactSourceDescriptor for RangeSourceDescriptor<T> {
36 type Item = T;
37
38 unsafe fn simple_exact_fetch_item(&self, index: usize) -> Self::Item {
39 debug_assert!(index < self.len);
40 T::forward(self.start, index)
41 }
42}
43
44#[cfg(not(feature = "nightly"))]
45impl SimpleExactSourceDescriptor for RangeSourceDescriptor<usize> {
46 type Item = usize;
47
48 unsafe fn simple_exact_fetch_item(&self, index: usize) -> Self::Item {
49 debug_assert!(index < self.len);
50 self.start + index
51 }
52}
53
54#[must_use = "iterator adaptors are lazy"]
88pub struct RangeParallelSource<T> {
89 range: Range<T>,
90}
91
92#[cfg(feature = "nightly")]
93impl<T: Step + Copy + Send + Sync> IntoExactParallelSource for Range<T> {
94 type Item = T;
95 type Source = RangeParallelSource<T>;
96
97 fn into_par_iter(self) -> Self::Source {
98 RangeParallelSource { range: self }
99 }
100}
101
102#[cfg(feature = "nightly")]
103impl<T: Step + Copy + Send + Sync> ExactParallelSource for RangeParallelSource<T> {
104 type Item = T;
105
106 fn exact_descriptor(self) -> impl ExactSourceDescriptor<Item = Self::Item> + Sync {
107 let range = self.range;
108 let (len_hint, len) = T::steps_between(&range.start, &range.end);
109 let len = len.unwrap_or_else(|| {
110 if len_hint == 0 {
111 panic!("cannot iterate over a backward range");
112 } else {
113 panic!(
114 "cannot iterate over a range with more than usize::MAX items ({})",
115 usize::MAX
116 );
117 }
118 });
119 RangeSourceDescriptor {
120 start: range.start,
121 len,
122 }
123 }
124}
125
126#[cfg(not(feature = "nightly"))]
127impl IntoExactParallelSource for Range<usize> {
128 type Item = usize;
129 type Source = RangeParallelSource<usize>;
130
131 fn into_par_iter(self) -> Self::Source {
132 RangeParallelSource { range: self }
133 }
134}
135
136#[cfg(not(feature = "nightly"))]
137impl ExactParallelSource for RangeParallelSource<usize> {
138 type Item = usize;
139
140 fn exact_descriptor(self) -> impl ExactSourceDescriptor<Item = Self::Item> + Sync {
141 let range = self.range;
142 let len = range
143 .end
144 .checked_sub(range.start)
145 .expect("cannot iterate over a backward range");
146 RangeSourceDescriptor {
147 start: range.start,
148 len,
149 }
150 }
151}
152
153#[must_use = "iterator adaptors are lazy"]
187pub struct RangeInclusiveParallelSource<T> {
188 range: RangeInclusive<T>,
189}
190
191#[cfg(feature = "nightly")]
192impl<T: Step + Copy + Send + Sync> IntoExactParallelSource for RangeInclusive<T> {
193 type Item = T;
194 type Source = RangeInclusiveParallelSource<T>;
195
196 fn into_par_iter(self) -> Self::Source {
197 RangeInclusiveParallelSource { range: self }
198 }
199}
200
201#[cfg(feature = "nightly")]
202impl<T: Step + Copy + Send + Sync> ExactParallelSource for RangeInclusiveParallelSource<T> {
203 type Item = T;
204
205 fn exact_descriptor(self) -> impl ExactSourceDescriptor<Item = Self::Item> + Sync {
206 let (start, end) = self.range.into_inner();
207 let (len_hint, len) = T::steps_between(&start, &end);
208 let len = len.unwrap_or_else(|| {
209 if len_hint == 0 {
210 panic!("cannot iterate over a backward range");
211 } else {
212 panic!(
213 "cannot iterate over a range with more than usize::MAX items ({})",
214 usize::MAX
215 );
216 }
217 });
218 let len = len.checked_add(1).unwrap_or_else(|| {
219 panic!(
220 "cannot iterate over a range with more than usize::MAX items ({})",
221 usize::MAX
222 );
223 });
224 RangeSourceDescriptor { start, len }
225 }
226}
227
228#[cfg(not(feature = "nightly"))]
229impl IntoExactParallelSource for RangeInclusive<usize> {
230 type Item = usize;
231 type Source = RangeInclusiveParallelSource<usize>;
232
233 fn into_par_iter(self) -> Self::Source {
234 RangeInclusiveParallelSource { range: self }
235 }
236}
237
238#[cfg(not(feature = "nightly"))]
239impl ExactParallelSource for RangeInclusiveParallelSource<usize> {
240 type Item = usize;
241
242 fn exact_descriptor(self) -> impl ExactSourceDescriptor<Item = Self::Item> + Sync {
243 let (start, end) = self.range.into_inner();
244 let len = end
245 .checked_sub(start)
246 .expect("cannot iterate over a backward range");
247 let len = len.checked_add(1).unwrap_or_else(|| {
248 panic!(
249 "cannot iterate over a range with more than usize::MAX items ({})",
250 usize::MAX
251 );
252 });
253 RangeSourceDescriptor { start, len }
254 }
255}