#![deny(missing_docs)]
#![deny(unsafe_op_in_unsafe_fn)]
mod policy;
pub use policy::{
Adaptive, AdaptiveWithThreshold, ExecutionPolicy, Parallel, Sequential,
ADAPTIVE_PARALLEL_THRESHOLD,
};
use core::marker::PhantomData;
pub(crate) struct DisjointMutPtr<T>(pub(crate) *mut T);
unsafe impl<T: Send> Send for DisjointMutPtr<T> {}
unsafe impl<T: Send> Sync for DisjointMutPtr<T> {}
impl<T> DisjointMutPtr<T> {
#[inline]
pub(crate) unsafe fn get_mut<'a>(&self, i: usize) -> &'a mut T {
unsafe { &mut *self.0.add(i) }
}
#[inline]
pub(crate) fn base(&self) -> *mut T {
self.0
}
}
pub mod ops;
pub use ops::{
enumerate_mut_with, enumerate_with, fold_reduce_with, for_each_chunk_mut_enumerated_with,
for_each_chunk_mut_with, for_each_chunk_mut_with_state,
for_each_chunk_pair_mut_enumerated_with, for_each_chunk_quad_mut_enumerated_with,
for_each_chunk_triple_mut_enumerated_with, for_each_index_with, for_each_mut_with,
for_each_with, join, join_with, map_collect_index_with, map_collect_mut_with, map_collect_with,
map_reduce_with, reduce_index_with, scope, Scope,
};
pub struct ParRef<'a, T, P> {
data: &'a [T],
_policy: PhantomData<P>,
}
impl<'a, T, P: ExecutionPolicy> ParRef<'a, T, P> {
pub fn for_each<F: Fn(&T) + Send + Sync>(self, f: F)
where
T: Sync,
{
for_each_with::<P, _, _>(self.data, f);
}
pub fn enumerate<F: Fn(usize, &T) + Send + Sync>(self, f: F)
where
T: Sync,
{
enumerate_with::<P, _, _>(self.data, f);
}
pub fn map_collect<R: Send, F: Fn(&T) -> R + Send + Sync>(self, f: F) -> Vec<R>
where
T: Sync,
{
map_collect_with::<P, _, _, _>(self.data, f)
}
pub fn map_collect_index<R: Send, F: Fn(usize, &T) -> R + Send + Sync>(self, f: F) -> Vec<R>
where
T: Sync,
{
map_collect_index_with::<P, _, _>(self.data.len(), |i| f(i, &self.data[i]))
}
pub fn map_reduce<R, M, Rd>(self, identity: R, map: M, reduce: Rd) -> R
where
T: Sync,
R: Send + Sync + Clone,
M: Fn(&T) -> R + Send + Sync,
Rd: Fn(R, R) -> R + Send + Sync,
{
map_reduce_with::<P, _, _, _, _>(self.data, identity, map, reduce)
}
}
pub struct ParMut<'a, T, P> {
data: &'a mut [T],
_policy: PhantomData<P>,
}
impl<'a, T, P: ExecutionPolicy> ParMut<'a, T, P> {
pub fn for_each<F: Fn(&mut T) + Send + Sync>(self, f: F)
where
T: Send,
{
for_each_mut_with::<P, _, _>(self.data, f);
}
pub fn enumerate<F: Fn(usize, &mut T) + Send + Sync>(self, f: F)
where
T: Send,
{
enumerate_mut_with::<P, _, _>(self.data, f);
}
}
pub trait ParallelSlice<T> {
fn par(&self) -> ParRef<'_, T, Adaptive>;
}
impl<T> ParallelSlice<T> for [T] {
#[inline]
fn par(&self) -> ParRef<'_, T, Adaptive> {
ParRef {
data: self,
_policy: PhantomData,
}
}
}
pub trait ParallelSliceMut<T> {
fn par_mut(&mut self) -> ParMut<'_, T, Adaptive>;
}
impl<T> ParallelSliceMut<T> for [T] {
#[inline]
fn par_mut(&mut self) -> ParMut<'_, T, Adaptive> {
ParMut {
data: self,
_policy: PhantomData,
}
}
}
#[cfg(feature = "melinoe")]
pub mod melinoe_ext;
#[cfg(test)]
#[path = "tests.rs"]
mod tests;