soapy_shared/
lib.rs

1pub trait Soapy: Sized {
2    type RawSoa: RawSoa<Self>;
3}
4
5/// A low-level utility providing fundamental operations needed by `Soa<T>`
6///
7/// In particular, it manages an allocation and a set of pointers into
8/// the allocation. Each of the pointers corresponds to a field of the type `T`
9/// and is treated as an array of values of that field's type.
10///
11/// # Safety
12///
13/// Use of this type is inherently unsafe and should be restricted to the
14/// implementation of `Soa`. There is no guarantee of contract stability between
15/// versions. Further, this type will **neither** deallocate its memory **nor**
16/// drop its contents when it is dropped. Special care must be taken to avoid
17/// unsound use.
18///
19/// In the method documentation, it is established that `PREV_CAP` is
20///
21/// - 0 if no previous calls to [`RawSoa::realloc_grow`] or [`RawSoa::realloc_shrink`] have been
22/// made, or
23/// - the same value as was used for `new_capacity` in previous calls
24/// to [`RawSoa::realloc_grow`] and [`RawSoa::realloc_shrink`]
25pub trait RawSoa<T>: Copy + Clone {
26    /// For each field with type `F` in `T`, `Slices` has a field with type
27    /// `&[F]`
28    type Slices<'a>
29    where
30        Self: 'a;
31
32    /// For each field with type `F` in `T`, `SlicesMut` has a field with type
33    /// `&mut [F]`
34    type SlicesMut<'a>
35    where
36        Self: 'a;
37
38    /// For each field with type `F` in `T`, `Ref` has a field with type
39    /// `&F`
40    type Ref<'a>
41    where
42        Self: 'a;
43
44    /// For each field with type `F` in `T`, `RefMut` has a field with type
45    /// `&mut F`
46    type RefMut<'a>
47    where
48        Self: 'a;
49
50    /// Creates a `Self` with dangling pointers for all its fields and without
51    /// allocating memory.
52    fn dangling() -> Self;
53
54    /// Constructs safe, immutable slices of the arrays managed by `Self` with
55    /// the range `start..end`.
56    ///
57    /// # Safety
58    ///
59    /// The caller must ensure that
60    /// - `start <= end`
61    /// - `start <= PREV_LEN`
62    /// - `end <= PREV_LEN`
63    unsafe fn slices(&self, start: usize, end: usize) -> Self::Slices<'_>;
64
65    /// Constructs safe, mutable slices of the arrays managed by `Self` with the
66    /// range `start..end`.
67    ///
68    /// # Safety
69    ///
70    /// The caller must ensure that
71    /// - `start <= end`
72    /// - `start <= PREV_LEN`
73    /// - `end <= PREV_LEN`
74    unsafe fn slices_mut(&mut self, start: usize, end: usize) -> Self::SlicesMut<'_>;
75
76    /// Returns the pointer that contains the allocated capacity.
77    ///
78    /// The pointer will point to invalid memory in these circumstances:
79    /// - `PREV_CAP == 0`
80    /// - `size_of::<T>() == 0`
81    fn as_ptr(self) -> *mut u8;
82
83    /// Construct a new `Self` with the given pointer and capacity.
84    ///
85    /// # Safety
86    ///
87    /// The pointer should come from a previous instance of `Self` with
88    /// `PREV_CAP == capacity`.
89    unsafe fn from_parts(ptr: *mut u8, capacity: usize) -> Self;
90
91    /// Allocates room for `capacity` elements.
92    ///
93    /// # Safety
94    ///
95    /// The caller must ensure that
96    ///
97    /// - `size_of::<T>() > 0`
98    /// - `capacity > 0`
99    /// - `PREV_CAP == 0` (Otherwise use [`RawSoa::realloc_grow`])
100    unsafe fn alloc(capacity: usize) -> Self;
101
102    /// Grows the allocation with room for `old_capacity` elements to fit
103    /// `new_capacity` elements and moves `length` number of array elements to
104    /// their new locations.
105    ///
106    /// # Safety
107    ///
108    /// The caller must ensure that
109    ///
110    /// - `size_of::<T>() > 0`
111    /// - `new_capacity > old_capacity`
112    /// - `length <= old_capacity`
113    /// - `old_capacity > 0` (Otherwise use [`RawSoa::alloc`])
114    unsafe fn realloc_grow(&mut self, old_capacity: usize, new_capacity: usize, length: usize);
115
116    /// Shrinks the allocation with room for `old_capacity` elements to fit
117    /// `new_capacity` elements and moves `length` number of array elements to
118    /// their new locations.
119    ///
120    /// # Safety
121    ///
122    /// The caller must ensure that
123    ///
124    /// - `size_of::<T>() > 0`
125    /// - `new_capacity < old_capacity`
126    /// - `length <= new_capacity`
127    /// - `old_capacity > 0` (Otherwise use [`RawSoa::dealloc`])
128    unsafe fn realloc_shrink(&mut self, old_capacity: usize, new_capacity: usize, length: usize);
129
130    /// Deallocates the allocation with room for `capacity` elements. The state
131    /// after calling this method is equivalent to [`RawSoa::dangling`].
132    ///
133    /// # Safety
134    ///
135    /// `Self` no longer valid after calling this function. The caller must ensure that
136    ///
137    /// - `size_of::<T>() > 0`
138    /// - `old_capacity > 0`
139    unsafe fn dealloc(self, old_capacity: usize);
140
141    /// Copies `count` elements from `src` index to `dst` index in each of the
142    /// arrays.
143    ///
144    /// # Safety
145    ///
146    /// The caller must ensure that
147    ///
148    /// - `src < PREV_CAP`
149    /// - `dst < PREV_CAP`
150    /// - `src + count <= PREV_CAP`
151    /// - `dst + count <= PREV_CAP`
152    unsafe fn copy(&mut self, src: usize, dst: usize, count: usize);
153
154    /// Sets the element at `index` to `element`.
155    ///
156    /// # Safety
157    ///
158    /// The caller must ensure that
159    ///
160    /// - `index < PREV_CAP`
161    unsafe fn set(&mut self, index: usize, element: T);
162
163    /// Gets the element at `index`.
164    ///
165    /// # Safety
166    ///
167    /// After calling `get`, the element at `index` should be treated as having
168    /// been moved out of `Self` and into the caller. Therefore, it is no longer
169    /// valid to reference this array element either by value or by reference.
170    /// The caller must ensure that
171    ///
172    /// - `index < PREV_CAP`
173    unsafe fn get(&self, index: usize) -> T;
174
175    /// Gets a reference to the element at `index`.
176    ///
177    /// # Safety
178    ///
179    /// The caller must ensure that
180    ///
181    /// - `index < PREV_CAP`
182    unsafe fn get_ref<'a>(&self, index: usize) -> Self::Ref<'a>;
183
184    /// Gets a mutable reference to the element at `index`.
185    ///
186    /// # Safety
187    ///
188    /// The caller must ensure that
189    ///
190    /// - `index < PREV_CAP`
191    unsafe fn get_mut<'a>(&self, index: usize) -> Self::RefMut<'a>;
192}