maybe_rayon/
lib.rs
1#![warn(clippy::all)]
2
3cfg_if::cfg_if! {
4 if #[cfg(any(not(feature = "threads"), all(target_arch="wasm32", not(target_feature = "atomics"))))] {
5 #[derive(Default)]
6 pub struct ThreadPoolBuilder ();
7 impl ThreadPoolBuilder {
8 #[inline(always)]
9 pub fn new() -> ThreadPoolBuilder {
10 ThreadPoolBuilder()
11 }
12
13 #[inline(always)]
14 pub fn build(self) -> Result<ThreadPool, ::core::convert::Infallible> {
15 Ok(ThreadPool())
16 }
17
18 #[inline(always)]
19 pub fn num_threads(self, _num_threads: usize) -> ThreadPoolBuilder {
20 ThreadPoolBuilder()
21 }
22 }
23 #[derive(Debug)]
24 pub struct ThreadPool ();
25 impl ThreadPool {
26 #[inline(always)]
27 pub fn install<OP, R>(&self, op: OP) -> R where
28 OP: FnOnce() -> R + Send,
29 R: Send, {
30 op()
31 }
32 }
33
34 pub mod iter {
35 pub trait IntoParallelIterator {
36 type Iter: Iterator<Item = Self::Item>;
37 type Item: Send;
38
39 fn into_par_iter(self) -> Self::Iter;
40 }
41
42 impl<I: IntoIterator> IntoParallelIterator for I where
43 I::Item : Send {
44 type Item = I::Item;
45 type Iter = I::IntoIter;
46
47 #[inline(always)]
48 fn into_par_iter(self) -> I::IntoIter {
49 self.into_iter()
50 }
51 }
52
53 pub trait IntoParallelRefMutIterator<'data> {
54 type Iter: IntoParallelIterator<Item = Self::Item>;
55 type Item: Send + 'data;
56
57 fn par_iter_mut(&'data mut self) -> Self::Iter;
58 }
59
60 impl<'data, I: 'data + ?Sized> IntoParallelRefMutIterator<'data> for I
61 where
62 &'data mut I: IntoParallelIterator,
63 {
64 type Iter = <&'data mut I as IntoParallelIterator>::Iter;
65 type Item = <&'data mut I as IntoParallelIterator>::Item;
66
67 #[inline(always)]
68 fn par_iter_mut(&'data mut self) -> Self::Iter {
69 self.into_par_iter()
70 }
71 }
72
73 pub trait ParallelIterator: Iterator {
74 #[inline(always)]
75 fn flat_map_iter<U, F>(self, f: F) -> std::iter::FlatMap<Self, U, F>
76 where
77 Self: Sized,
78 U: IntoIterator,
79 F: FnMut(<Self as Iterator>::Item) -> U,
80 {
81 self.flat_map(f)
82 }
83 }
84
85 impl<I: Iterator> ParallelIterator for I {}
86 }
87 pub mod slice {
88 pub trait ParallelSlice<T: Sync> {
89 fn par_chunks_exact(
90 &self, chunk_size: usize,
91 ) -> std::slice::ChunksExact<'_, T>;
92 }
93
94 impl<T: Sync> ParallelSlice<T> for [T] {
95 #[inline(always)]
96 fn par_chunks_exact(
97 &self, chunk_size: usize,
98 ) -> std::slice::ChunksExact<'_, T> {
99 self.chunks_exact(chunk_size)
100 }
101 }
102 }
103
104 pub mod prelude {
105 pub use super::iter::*;
106 pub use super::slice::*;
107 }
108
109 #[inline(always)]
110 pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
111 where
112 A: FnOnce() -> RA + Send,
113 B: FnOnce() -> RB + Send,
114 RA: Send,
115 RB: Send {
116 (oper_a(), oper_b())
117 }
118
119 use std::marker::PhantomData;
120
121 pub struct Scope<'scope>{
122 #[allow(clippy::type_complexity)]
123 marker: PhantomData<Box<dyn FnOnce(&Scope<'scope>) + Send + Sync + 'scope>>,
124 }
125
126 impl<'scope> Scope<'scope> {
127 #[inline(always)]
128 pub fn spawn<BODY>(&self, body: BODY)
129 where BODY: FnOnce(&Scope<'scope>) + Send + 'scope
130 {
131 body(self)
132 }
133 }
134
135 #[inline(always)]
136 pub fn scope<'scope, OP, R>(op: OP) -> R
137 where OP: for<'s> FnOnce(&'s Scope<'scope>) -> R + 'scope + Send, R: Send,
138 {
139 op(&Scope { marker: PhantomData })
140 }
141 } else {
142 pub use rayon::*;
143 }
144}