fenris_paradis/
slice.rs

1use crate::{ParallelIndexedAccess, ParallelIndexedCollection};
2use std::marker::PhantomData;
3use std::ops::Range;
4
5#[derive(Copy)]
6pub struct ParallelSliceAccess<'a, T> {
7    ptr: *mut T,
8    marker: PhantomData<&'a mut T>,
9}
10
11impl<'a, T> ParallelSliceAccess<'a, T> {
12    /// Construct a subslice for the given range.
13    ///
14    /// # Safety
15    ///
16    /// The range must be valid for the slice.
17    ///
18    /// Multiple threads must not call this function with overlapping ranges without synchronization.
19    pub unsafe fn subslice_mut(&self, range: Range<usize>) -> &'a mut [T] {
20        let Range { start, end } = range;
21        debug_assert!(end >= start);
22        let ptr = self.ptr.add(start);
23        let len = end - start;
24        std::slice::from_raw_parts_mut(ptr, len)
25    }
26}
27
28impl<'a, T> Clone for ParallelSliceAccess<'a, T> {
29    fn clone(&self) -> Self {
30        Self {
31            ptr: self.ptr,
32            marker: PhantomData,
33        }
34    }
35}
36
37unsafe impl<'a, T: Sync> Sync for ParallelSliceAccess<'a, T> {}
38unsafe impl<'a, T: Send> Send for ParallelSliceAccess<'a, T> {}
39
40unsafe impl<'a, 'b, T: 'b + Sync + Send> ParallelIndexedAccess<'b> for ParallelSliceAccess<'a, T>
41where
42    'a: 'b,
43{
44    type Record = &'b T;
45    type RecordMut = &'b mut T;
46
47    unsafe fn get_unchecked(&self, global_index: usize) -> Self::Record {
48        // TODO: This might technically be unsound. Should we use .wrapping_add, or something else?
49        &*self.ptr.add(global_index)
50    }
51
52    unsafe fn get_unchecked_mut(&self, global_index: usize) -> Self::RecordMut {
53        // TODO: This might technically be unsound. Should we use .wrapping_add, or something else?
54        &mut *self.ptr.add(global_index)
55    }
56}
57
58unsafe impl<'a, T: 'a + Sync + Send> ParallelIndexedCollection<'a> for [T] {
59    type Access = ParallelSliceAccess<'a, T>;
60
61    unsafe fn create_access(&'a mut self) -> Self::Access {
62        ParallelSliceAccess {
63            ptr: self.as_mut_ptr(),
64            marker: PhantomData,
65        }
66    }
67
68    fn len(&self) -> usize {
69        <[T]>::len(&self)
70    }
71}