1use crate::iter::plumbing::*;
2use crate::iter::*;
3
4#[derive(Debug)]
6pub struct Windows<'data, T> {
7 window_size: usize,
8 slice: &'data [T],
9}
10
11impl<'data, T> Windows<'data, T> {
12 pub(super) fn new(window_size: usize, slice: &'data [T]) -> Self {
13 Self { window_size, slice }
14 }
15}
16
17impl<T> Clone for Windows<'_, T> {
18 fn clone(&self) -> Self {
19 Windows { ..*self }
20 }
21}
22
23impl<'data, T: Sync> ParallelIterator for Windows<'data, T> {
24 type Item = &'data [T];
25
26 fn drive_unindexed<C>(self, consumer: C) -> C::Result
27 where
28 C: UnindexedConsumer<Self::Item>,
29 {
30 bridge(self, consumer)
31 }
32
33 fn opt_len(&self) -> Option<usize> {
34 Some(self.len())
35 }
36}
37
38impl<T: Sync> IndexedParallelIterator for Windows<'_, T> {
39 fn drive<C>(self, consumer: C) -> C::Result
40 where
41 C: Consumer<Self::Item>,
42 {
43 bridge(self, consumer)
44 }
45
46 fn len(&self) -> usize {
47 assert!(self.window_size >= 1);
48 self.slice.len().saturating_sub(self.window_size - 1)
49 }
50
51 fn with_producer<CB>(self, callback: CB) -> CB::Output
52 where
53 CB: ProducerCallback<Self::Item>,
54 {
55 callback.callback(WindowsProducer {
56 window_size: self.window_size,
57 slice: self.slice,
58 })
59 }
60}
61
62struct WindowsProducer<'data, T: Sync> {
63 window_size: usize,
64 slice: &'data [T],
65}
66
67impl<'data, T: Sync> Producer for WindowsProducer<'data, T> {
68 type Item = &'data [T];
69 type IntoIter = ::std::slice::Windows<'data, T>;
70
71 fn into_iter(self) -> Self::IntoIter {
72 self.slice.windows(self.window_size)
73 }
74
75 fn split_at(self, index: usize) -> (Self, Self) {
76 let left_index = Ord::min(self.slice.len(), index + (self.window_size - 1));
77 let left = &self.slice[..left_index];
78 let right = &self.slice[index..];
79 (
80 WindowsProducer {
81 window_size: self.window_size,
82 slice: left,
83 },
84 WindowsProducer {
85 window_size: self.window_size,
86 slice: right,
87 },
88 )
89 }
90}
91
92#[derive(Debug)]
94pub struct ArrayWindows<'data, T: Sync, const N: usize> {
95 slice: &'data [T],
96}
97
98impl<'data, T: Sync, const N: usize> ArrayWindows<'data, T, N> {
99 pub(super) fn new(slice: &'data [T]) -> Self {
100 ArrayWindows { slice }
101 }
102}
103
104impl<T: Sync, const N: usize> Clone for ArrayWindows<'_, T, N> {
105 fn clone(&self) -> Self {
106 ArrayWindows { ..*self }
107 }
108}
109
110impl<'data, T: Sync, const N: usize> ParallelIterator for ArrayWindows<'data, T, N> {
111 type Item = &'data [T; N];
112
113 fn drive_unindexed<C>(self, consumer: C) -> C::Result
114 where
115 C: UnindexedConsumer<Self::Item>,
116 {
117 bridge(self, consumer)
118 }
119
120 fn opt_len(&self) -> Option<usize> {
121 Some(self.len())
122 }
123}
124
125impl<T: Sync, const N: usize> IndexedParallelIterator for ArrayWindows<'_, T, N> {
126 fn drive<C>(self, consumer: C) -> C::Result
127 where
128 C: Consumer<Self::Item>,
129 {
130 bridge(self, consumer)
131 }
132
133 fn len(&self) -> usize {
134 assert!(N >= 1);
135 self.slice.len().saturating_sub(const { N - 1 })
136 }
137
138 fn with_producer<CB>(self, callback: CB) -> CB::Output
139 where
140 CB: ProducerCallback<Self::Item>,
141 {
142 Windows::new(N, self.slice)
144 .map(|slice| slice.try_into().unwrap())
145 .with_producer(callback)
146 }
147}