1use core::iter::FlatMap;
2use core::slice::{
3 Chunks, ChunksExact, ChunksExactMut, ChunksMut, RChunks, RChunksExact, RChunksExactMut,
4 RChunksMut, Split, SplitMut, Windows,
5};
6
7pub trait IntoParallelIterator {
8 type Iter: Iterator<Item = Self::Item>;
9 type Item: Send;
10
11 fn into_par_iter(self) -> Self::Iter;
12}
13impl<T: IntoIterator> IntoParallelIterator for T
14where
15 T::Item: Send,
16{
17 type Iter = T::IntoIter;
18 type Item = T::Item;
19
20 fn into_par_iter(self) -> Self::Iter {
21 self.into_iter()
22 }
23}
24
25pub trait IntoParallelRefIterator<'data> {
26 type Iter: Iterator<Item = Self::Item>;
27 type Item: Send + 'data;
28
29 fn par_iter(&'data self) -> Self::Iter;
30}
31
32impl<'data, I: 'data + ?Sized> IntoParallelRefIterator<'data> for I
33where
34 &'data I: IntoParallelIterator,
35{
36 type Iter = <&'data I as IntoParallelIterator>::Iter;
37 type Item = <&'data I as IntoParallelIterator>::Item;
38
39 fn par_iter(&'data self) -> Self::Iter {
40 self.into_par_iter()
41 }
42}
43
44pub trait IntoParallelRefMutIterator<'data> {
45 type Iter: Iterator<Item = Self::Item>;
46 type Item: Send + 'data;
47
48 fn par_iter_mut(&'data mut self) -> Self::Iter;
49}
50
51impl<'data, I: 'data + ?Sized> IntoParallelRefMutIterator<'data> for I
52where
53 &'data mut I: IntoParallelIterator,
54{
55 type Iter = <&'data mut I as IntoParallelIterator>::Iter;
56 type Item = <&'data mut I as IntoParallelIterator>::Item;
57
58 fn par_iter_mut(&'data mut self) -> Self::Iter {
59 self.into_par_iter()
60 }
61}
62
63pub trait ParallelSlice<T: Sync> {
64 fn as_parallel_slice(&self) -> &[T];
67
68 fn par_split<P>(&self, separator: P) -> Split<'_, T, P>
69 where
70 P: Fn(&T) -> bool + Sync + Send,
71 {
72 self.as_parallel_slice().split(separator)
73 }
74
75 fn par_windows(&self, window_size: usize) -> Windows<'_, T> {
76 self.as_parallel_slice().windows(window_size)
77 }
78
79 fn par_chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
80 self.as_parallel_slice().chunks(chunk_size)
81 }
82
83 fn par_chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
84 self.as_parallel_slice().chunks_exact(chunk_size)
85 }
86
87 fn par_rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
88 self.as_parallel_slice().rchunks(chunk_size)
89 }
90
91 fn par_rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
92 self.as_parallel_slice().rchunks_exact(chunk_size)
93 }
94}
95
96impl<T: Sync> ParallelSlice<T> for [T] {
97 #[inline]
98 fn as_parallel_slice(&self) -> &[T] {
99 self
100 }
101}
102
103pub trait ParallelSliceMut<T: Send> {
104 fn as_parallel_slice_mut(&mut self) -> &mut [T];
107
108 fn par_split_mut<P>(&mut self, separator: P) -> SplitMut<'_, T, P>
109 where
110 P: Fn(&T) -> bool + Sync + Send,
111 {
112 self.as_parallel_slice_mut().split_mut(separator)
113 }
114
115 fn par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
116 self.as_parallel_slice_mut().chunks_mut(chunk_size)
117 }
118
119 fn par_chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
120 self.as_parallel_slice_mut().chunks_exact_mut(chunk_size)
121 }
122
123 fn par_rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
124 self.as_parallel_slice_mut().rchunks_mut(chunk_size)
125 }
126
127 fn par_rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
128 self.as_parallel_slice_mut().rchunks_exact_mut(chunk_size)
129 }
130}
131
132impl<T: Send> ParallelSliceMut<T> for [T] {
133 #[inline]
134 fn as_parallel_slice_mut(&mut self) -> &mut [T] {
135 self
136 }
137}
138
139pub trait ParIterExt: Iterator {
140 fn find_any<P>(self, predicate: P) -> Option<Self::Item>
141 where
142 P: Fn(&Self::Item) -> bool + Sync + Send;
143
144 fn flat_map_iter<U, F>(self, map_op: F) -> FlatMap<Self, U, F>
145 where
146 Self: Sized,
147 U: IntoIterator,
148 F: Fn(Self::Item) -> U;
149}
150
151impl<T: Iterator> ParIterExt for T {
152 fn find_any<P>(mut self, predicate: P) -> Option<Self::Item>
153 where
154 P: Fn(&Self::Item) -> bool + Sync + Send,
155 {
156 self.find(predicate)
157 }
158
159 fn flat_map_iter<U, F>(self, map_op: F) -> FlatMap<Self, U, F>
160 where
161 Self: Sized,
162 U: IntoIterator,
163 F: Fn(Self::Item) -> U,
164 {
165 self.flat_map(map_op)
166 }
167}
168
169pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
170where
171 A: FnOnce() -> RA,
172 B: FnOnce() -> RB,
173{
174 let result_a = oper_a();
175 let result_b = oper_b();
176 (result_a, result_b)
177}