orx_concurrent_iter/implementations/jagged_arrays/as_raw_slice.rs
1use crate::implementations::jagged_arrays::RawSlice;
2use alloc::vec::Vec;
3
4/// A type that can be represented as a slice.
5pub trait AsRawSlice<T> {
6    /// Beginning of the slice.
7    fn ptr(&self) -> *const T;
8
9    /// Length of the slice.
10    fn length(&self) -> usize;
11
12    /// Creates a slice from this slice with `len` elements starting from the `begin`.
13    fn raw_slice(&self, begin: usize, len: usize) -> RawSlice<T>;
14
15    // provided
16
17    /// True if length is zero; false otherwise.
18    fn is_empty(&self) -> bool {
19        self.length() == 0
20    }
21
22    /// Returns pointers to the first and last, (len-1)-th, element of the slice.
23    ///
24    /// If the slice is empty, both pointers are null.
25    fn first_and_last_ptrs(&self) -> [*const T; 2] {
26        match self.length() {
27            0 => [core::ptr::null(), core::ptr::null()],
28            n => [self.ptr(), unsafe { self.ptr_at(n - 1) }],
29        }
30    }
31
32    /// Returns the pointer to the `position`-th element of the slice.
33    ///
34    /// # SAFETY
35    ///
36    /// Must ensure that `position` is in bounds; otherwise,
37    /// the method accesses out of bounds memory if `position >= self.len()`.
38    unsafe fn ptr_at(&self, position: usize) -> *const T {
39        debug_assert!(position < self.length());
40        unsafe { self.ptr().add(position) }
41    }
42}
43
44/// A type that can be represented as a slice which also owns the data, such as the std vec.
45pub trait AsOwningSlice<T>: AsRawSlice<T> {
46    /// Capacity of the allocation.
47    fn capacity(&self) -> usize;
48
49    /// Drops the `position`-th element of the slice.
50    ///
51    /// # SAFETY
52    ///
53    /// Must ensure that `position` is in bounds; otherwise,
54    /// the method accesses out of bounds memory if `position >= self.len()`.
55    ///
56    /// After this call, the corresponding element of the slice must be considered as
57    /// uninitialized memory and should not be accessed.
58    ///
59    /// Further, it must not be attempted to drop the second time.
60    unsafe fn drop_in_place(&self, position: usize) {
61        let ptr = unsafe { self.ptr_at(position) } as *mut T;
62        unsafe { ptr.drop_in_place() };
63    }
64
65    /// Drops the allocation and releases the memory used by the owning slice.
66    ///
67    /// # SAFETY
68    ///
69    /// Once allocation is dropped, it is not safe to use any of the methods except for `len` and
70    /// `capacity`, since the memory that the pointers point to does not belong to the slice now.
71    unsafe fn drop_allocation(&self) {
72        let _vec_to_drop = unsafe { Vec::from_raw_parts(self.ptr() as *mut T, 0, self.capacity()) };
73    }
74}
75
76// implementations
77
78impl<T> AsRawSlice<T> for &[T] {
79    fn ptr(&self) -> *const T {
80        self.as_ptr()
81    }
82
83    fn length(&self) -> usize {
84        self.len()
85    }
86
87    fn raw_slice(&self, begin: usize, len: usize) -> RawSlice<T> {
88        debug_assert!(begin < self.len());
89        let ptr = unsafe { self.as_ptr().add(begin) };
90        RawSlice::new(ptr, len)
91    }
92}
93
94impl<T> AsRawSlice<T> for Vec<T> {
95    fn ptr(&self) -> *const T {
96        self.as_ptr()
97    }
98
99    fn length(&self) -> usize {
100        self.len()
101    }
102
103    fn raw_slice(&self, begin: usize, len: usize) -> RawSlice<T> {
104        debug_assert!(begin < self.len());
105        let ptr = unsafe { self.as_ptr().add(begin) };
106        RawSlice::new(ptr, len)
107    }
108}