#[cfg(feature = "parallel")]
pub fn current_num_threads() -> usize {
rayon::current_num_threads()
}
#[cfg(not(feature = "parallel"))]
pub fn current_num_threads() -> usize {
1
}
#[cfg(feature = "parallel")]
pub use rayon::iter::{IndexedParallelIterator, ParallelIterator};
#[cfg(feature = "parallel")]
pub use rayon::prelude::*;
#[cfg(feature = "parallel")]
pub use rayon::slice::{ParallelSlice, ParallelSliceMut};
#[cfg(not(feature = "parallel"))]
mod seq {
pub trait ParallelSlice<T: Sync> {
fn par_chunks(&self, chunk_size: usize) -> core::slice::Chunks<'_, T>;
}
impl<T: Sync> ParallelSlice<T> for [T] {
fn par_chunks(&self, chunk_size: usize) -> core::slice::Chunks<'_, T> {
self.chunks(chunk_size)
}
}
pub trait ParallelSliceMut<T: Send> {
fn par_chunks_mut(&mut self, chunk_size: usize) -> core::slice::ChunksMut<'_, T>;
}
impl<T: Send> ParallelSliceMut<T> for [T] {
fn par_chunks_mut(&mut self, chunk_size: usize) -> core::slice::ChunksMut<'_, T> {
self.chunks_mut(chunk_size)
}
}
}
#[cfg(not(feature = "parallel"))]
pub use seq::{ParallelSlice, ParallelSliceMut};
#[cfg(not(feature = "parallel"))]
pub use core::iter::Iterator as IndexedParallelIterator;
#[cfg(not(feature = "parallel"))]
pub use core::iter::Iterator as ParallelIterator;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn current_num_threads_is_positive() {
assert!(current_num_threads() >= 1);
}
#[test]
fn par_chunks_mut_shape_matches_sequential() {
let mut v = vec![0i32; 8];
v.par_chunks_mut(4)
.enumerate()
.for_each(|(i, chunk)| chunk.iter_mut().for_each(|x| *x = i as i32));
assert_eq!(v, vec![0, 0, 0, 0, 1, 1, 1, 1]);
}
}