p3_maybe_rayon/
serial.rs

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    /// Returns a plain slice, which is used to implement the rest of the
65    /// parallel methods.
66    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    /// Returns a plain mutable slice, which is used to implement the rest of
105    /// the parallel methods.
106    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}