int_interval_stack/int_co_stack/
impls_for_windows.rs1use int_interval::traits::{COStartLenConstruct, IntPrimitive};
2use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
3
4use super::*;
5
6#[inline]
7fn window_count<I>(from: I::CoordType, to: I::CoordType, len: I::MeasureType) -> Option<usize>
8where
9 I: IntCO + COStartLenConstruct,
10 I::MeasureType: TryInto<usize>,
11{
12 if len == I::MeasureType::zero() {
13 return None;
14 }
15
16 let domain = I::try_new(from, to)?;
17 let remaining = domain.len().checked_sub(len)?;
18 let count = remaining.checked_add(I::MeasureType::one())?;
19
20 count.try_into().ok()
21}
22
23#[inline]
24fn start_at<I>(from: I::CoordType, index: usize) -> Option<I::CoordType>
25where
26 I: IntCO + COStartLenConstruct,
27{
28 if index == 0 {
29 return Some(from);
30 }
31
32 let offset = I::MeasureType::checked_from(index)?;
33
34 I::checked_from_start_len(from, offset).map(|interval| interval.end_excl())
35}
36
37#[inline]
38fn window_at<'a, I>(
39 stack: &'a IntCOStack<I>,
40 from: I::CoordType,
41 len: I::MeasureType,
42 index: usize,
43) -> Option<StackWindow<'a, I>>
44where
45 I: IntCO + COStartLenConstruct + Copy,
46{
47 let start = start_at::<I>(from, index)?;
48 let interval = I::checked_from_start_len(start, len)?;
49
50 Some(StackWindow::new(stack, interval))
51}
52
53impl<I> IntCOStack<I>
54where
55 I: IntCO + COStartLenConstruct + Copy,
56 I::MeasureType: TryInto<usize>,
57{
58 #[inline]
75 pub fn iter_windows(
76 &self,
77 from: I::CoordType,
78 to: I::CoordType,
79 len: I::MeasureType,
80 ) -> impl DoubleEndedIterator<Item = StackWindow<'_, I>> + ExactSizeIterator {
81 let count = window_count::<I>(from, to, len).unwrap_or(0);
82
83 (0..count).map(move |index| {
84 window_at(self, from, len, index)
85 .expect("validated window index must produce a representable window")
86 })
87 }
88
89 #[inline]
96 pub fn par_iter_windows(
97 &self,
98 from: I::CoordType,
99 to: I::CoordType,
100 len: I::MeasureType,
101 ) -> impl IndexedParallelIterator<Item = StackWindow<'_, I>>
102 where
103 I: Send + Sync,
104 {
105 let count = window_count::<I>(from, to, len).unwrap_or(0);
106
107 (0..count).into_par_iter().map(move |index| {
108 window_at(self, from, len, index)
109 .expect("validated window index must produce a representable window")
110 })
111 }
112}
113
114#[cfg(test)]
115mod test_support;
116
117#[cfg(test)]
118mod tests_for_window_count;
119
120#[cfg(test)]
121mod tests_for_start_at;
122
123#[cfg(test)]
124mod tests_for_window_at;
125
126#[cfg(test)]
127mod tests_for_iter_windows;