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}