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