p3_maybe_rayon/
serial.rs

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    /// Returns a plain slice, which is used to implement the rest of the
67    /// parallel methods.
68    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    /// Returns a plain mutable slice, which is used to implement the rest of
107    /// the parallel methods.
108    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>
143    where
144        P: Fn(&Self::Item) -> bool + Sync + Send;
145
146    fn flat_map_iter<U, F>(self, map_op: F) -> FlatMap<Self, U, F>
147    where
148        Self: Sized,
149        U: IntoIterator,
150        F: Fn(Self::Item) -> U;
151}
152
153impl<T: Iterator> ParIterExt for T {
154    fn find_any<P>(mut self, predicate: P) -> Option<Self::Item>
155    where
156        P: Fn(&Self::Item) -> bool + Sync + Send,
157    {
158        self.find(predicate)
159    }
160
161    fn flat_map_iter<U, F>(self, map_op: F) -> FlatMap<Self, U, F>
162    where
163        Self: Sized,
164        U: IntoIterator,
165        F: Fn(Self::Item) -> U,
166    {
167        self.flat_map(map_op)
168    }
169}
170
171pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
172where
173    A: FnOnce() -> RA,
174    B: FnOnce() -> RB,
175{
176    let result_a = oper_a();
177    let result_b = oper_b();
178    (result_a, result_b)
179}
180
181pub const fn current_num_threads() -> usize {
182    1
183}