1use std::{cell::UnsafeCell, ops::Range, slice};
4
5#[repr(transparent)]
9#[derive(Clone, Copy)]
10pub struct SharedSlice<'a, T>(&'a [SyncUnsafeCell<T>]);
11
12impl<'a, T> SharedSlice<'a, T> {
13 pub fn new(data: &'a mut [T]) -> Self {
14 Self(unsafe {
15 slice::from_raw_parts(data.as_ptr() as *const SyncUnsafeCell<T>, data.len())
16 })
17 }
18
19 pub fn len(self) -> usize {
20 self.0.len()
21 }
22
23 pub fn is_empty(self) -> bool {
24 self.len() == 0
25 }
26
27 pub unsafe fn get(self, index: usize) -> &'a T {
32 unsafe { &*self.0[index].get() }
33 }
34
35 pub unsafe fn get_mut(self, index: usize) -> &'a mut T {
40 unsafe { &mut *self.0[index].get() }
41 }
42
43 pub unsafe fn slice(self, range: Range<usize>) -> &'a [T] {
44 debug_assert!(range.start <= self.0.len());
45 debug_assert!(range.end <= self.0.len());
46
47 if range.start >= range.end {
48 return &[];
49 }
50
51 unsafe { core::slice::from_raw_parts(self.get(range.start), range.end - range.start) }
52 }
53
54 pub unsafe fn slice_mut(self, range: Range<usize>) -> &'a mut [T] {
55 debug_assert!(range.start <= self.0.len());
56 debug_assert!(range.end <= self.0.len());
57
58 if range.start >= range.end {
59 return &mut [];
60 }
61 unsafe {
62 core::slice::from_raw_parts_mut(self.get_mut(range.start), range.end - range.start)
63 }
64 }
65}
66
67#[repr(transparent)]
69struct SyncUnsafeCell<T: ?Sized> {
70 value: UnsafeCell<T>,
71}
72
73unsafe impl<T: ?Sized + Sync> Sync for SyncUnsafeCell<T> {}
74
75impl<T: ?Sized> SyncUnsafeCell<T> {
77 pub const fn get(&self) -> *mut T {
78 self.value.get()
79 }
80}