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 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 &*self.ptr.add(global_index)
50 }
51
52 unsafe fn get_unchecked_mut(&self, global_index: usize) -> Self::RecordMut {
53 &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}