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}