paradis_core/
slice.rs

1//! Core primitives for slices.
2use crate::par_access::ParAccess;
3use crate::{BoundedParAccess, Bounds, IntoParAccess, LinearParAccess};
4use std::marker::PhantomData;
5
6/// Parallel access to a mutable slice.
7#[derive(Debug)]
8pub struct SliceParAccessMut<'a, T> {
9    ptr: *mut T,
10    len: usize,
11    marker: PhantomData<&'a mut T>,
12}
13
14impl<'a, T> SliceParAccessMut<'a, T> {
15    /// Obtain parallel access to a mutable slice.
16    ///
17    /// In most cases, prefer to go through the implementation of [`IntoParAccess`] instead of this
18    /// method directly.
19    pub fn from_slice_mut(slice: &'a mut [T]) -> Self {
20        Self {
21            ptr: slice.as_mut_ptr(),
22            len: slice.len(),
23            marker: PhantomData,
24        }
25    }
26}
27
28unsafe impl<'a, T: Send> Sync for SliceParAccessMut<'a, T> {}
29unsafe impl<'a, T: Send> Send for SliceParAccessMut<'a, T> {}
30
31unsafe impl<'a, T: Send> ParAccess<usize> for SliceParAccessMut<'a, T> {
32    type Record = &'a mut T;
33
34    #[inline(always)]
35    unsafe fn clone_access(&self) -> Self {
36        Self {
37            ptr: self.ptr,
38            len: self.len,
39            marker: Default::default(),
40        }
41    }
42
43    #[inline(always)]
44    unsafe fn get_unsync_unchecked(&self, index: usize) -> Self::Record {
45        unsafe { &mut *self.ptr.add(index) }
46    }
47}
48
49unsafe impl<'a, T: Send> BoundedParAccess<usize> for SliceParAccessMut<'a, T> {
50    #[inline(always)]
51    fn in_bounds(&self, index: usize) -> bool {
52        index < self.len
53    }
54
55    fn bounds(&self) -> Bounds<usize> {
56        Bounds {
57            offset: 0,
58            extent: self.len,
59        }
60    }
61}
62
63impl<'a, T: Send> IntoParAccess<usize> for &'a mut [T] {
64    type Access = SliceParAccessMut<'a, T>;
65
66    fn into_par_access(self) -> Self::Access {
67        SliceParAccessMut::from_slice_mut(self)
68    }
69}
70
71unsafe impl<'a, T: Send> LinearParAccess for SliceParAccessMut<'a, T> {
72    fn collection_len(&self) -> usize {
73        self.len
74    }
75}