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