stable_vec/core/mod.rs
1//! `Core` trait definition and implementations.
2//!
3//! There are multiple ways to implement the "stable vector" interface, each
4//! with different performance characteristics. The `Core` is this
5//! implementation, making the stable vector work. See [`Core`][Core] for
6//! more information.
7
8use ::core::{
9 fmt,
10 marker::PhantomData,
11 ops::{Deref, DerefMut},
12};
13
14pub use self::option::OptionCore;
15pub use self::bitvec::BitVecCore;
16
17mod option;
18mod bitvec;
19
20
21/// The default core implementation of the stable vector. Fine in most
22/// situations.
23pub type DefaultCore<T> = BitVecCore<T>;
24
25/// The core of a stable vector.
26///
27/// *Note*: If you are a user of this crate, you probably don't care about
28/// this! See the documentation on [`StableVecFacade`][crate::StableVecFacade]
29/// and the different core implementations for more useful information. This
30/// trait is only important for you if you want to implement your own core
31/// implementation.
32///
33/// Implementors of the trait take the core role in the stable vector: storing
34/// elements of type `T` where each element might be deleted. The elements can
35/// be referred to by an index.
36///
37/// Core types must never read deleted elements in `drop()`. So they must
38/// ensure to only ever drop existing elements.
39///
40/// **IMPORTANT**: should be an `unsafe` trait! This will be changed in the next
41/// major version. Treat it semantically as `unsafe`.
42///
43///
44/// # Formal semantics
45///
46/// A core defines a map from `usize` (the so called "indices") to elements of
47/// type `Option<T>`. It has a length (`len`) and a capacity (`cap`).
48///
49/// It's best to think of this as a contiguous sequence of "slots". A slot can
50/// either be empty or filled with an element. A core has always `cap` many
51/// slots. Here is an example of such a core with `len = 8` and `cap = 10`.
52///
53/// ```text
54/// 0 1 2 3 4 5 6 7 8 9 10
55/// ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
56/// │ a │ - │ b │ c │ - │ - │ d │ - │ - │ - │
57/// └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
58/// ↑ ↑
59/// len cap
60/// ```
61///
62/// `len` and `cap` divide the index space into three parts, which have the
63/// following invariants:
64/// - `0 ≤ i < len`: slots with index `i` can be empty or filled
65/// - `len ≤ i < cap`: slots with index `i` are always empty
66/// - `cap ≤ i`: slots with index `i` are undefined (all methods dealing with
67/// indices will exhibit undefined behavior when the index is `≥ cap`)
68///
69/// Additional required invariants:
70/// - `len ≤ cap`
71/// - `cap ≤ isize::MAX`
72/// - Methods with `&self` receiver do not change anything observable about the
73/// core.
74///
75/// These invariants must not (at any time) be violated by users of this API.
76///
77/// Cloning a core must clone everything, including all empty slots. This means
78/// that the capacity of the clone must be at least the capacity of the
79/// original value.
80pub trait Core<T> {
81 /// Creates an empty instance without any elements. Must not allocate
82 /// memory.
83 ///
84 /// # Formal
85 ///
86 /// **Postconditons** (of returned instance `out`):
87 /// - `out.len() == 0`
88 /// - `out.cap() == 0`
89 fn new() -> Self;
90
91 /// Returns the length of this core (the `len`). See the trait docs for
92 /// more information.
93 fn len(&self) -> usize;
94
95 /// Sets the `len` to a new value.
96 ///
97 /// # Formal
98 ///
99 /// **Preconditions**:
100 /// - `new_len ≤ self.cap()`
101 /// - ∀ i in `new_len..self.cap()` ⇒ `self.has_element_at(i) == false`
102 ///
103 /// **Invariants**:
104 /// - *slot data*
105 ///
106 /// **Postconditons**:
107 /// - `self.len() == new_len`
108 unsafe fn set_len(&mut self, new_len: usize);
109
110 /// Returns the capacity of this core (the `cap`). See the trait docs for
111 /// more information.
112 fn cap(&self) -> usize;
113
114 /// Reallocates the memory to have a `cap` of at least `new_cap`. This
115 /// method should try its best to allocate exactly `new_cap`.
116 ///
117 /// This means that after calling this method, inserting elements at
118 /// indices in the range `0..new_cap` is valid. This method shall not check
119 /// if there is already enough capacity available.
120 ///
121 /// For implementors: please mark this impl with `#[cold]` and
122 /// `#[inline(never)]`.
123 ///
124 /// # Formal
125 ///
126 /// **Preconditions**:
127 /// - `new_cap ≥ self.len()` (as a consequence, this method does not (need
128 /// to) drop elements; all slots >= `new_cap` are empty)
129 /// - `new_cap ≤ isize::MAX`
130 ///
131 /// **Invariants**:
132 /// - *slot data*
133 /// - `self.len()`
134 ///
135 /// **Postconditons**:
136 /// - `self.cap() >= new_cap`
137 unsafe fn realloc(&mut self, new_cap: usize);
138
139 /// Checks if there exists an element with index `idx`.
140 ///
141 /// # Formal
142 ///
143 /// **Preconditions**:
144 /// - `idx < self.cap()`
145 unsafe fn has_element_at(&self, idx: usize) -> bool;
146
147 /// Inserts `elem` at the index `idx`.
148 ///
149 /// # Formal
150 ///
151 /// **Preconditions**:
152 /// - `idx < self.cap()`
153 /// - `self.has_element_at(idx) == false`
154 ///
155 /// **Invariants**:
156 /// - `self.len()`
157 /// - `self.cap()`
158 ///
159 /// **Postconditons**:
160 /// - `self.get_unchecked(idx) == elem`
161 unsafe fn insert_at(&mut self, idx: usize, elem: T);
162
163 /// Removes the element at index `idx` and returns it.
164 ///
165 /// # Formal
166 ///
167 /// **Preconditions**:
168 /// - `idx < self.cap()`
169 /// - `self.has_element_at(idx) == true`
170 ///
171 /// **Invariants**:
172 /// - `self.len()`
173 /// - `self.cap()`
174 ///
175 /// **Postconditons**:
176 /// - `self.has_element_at(idx) == false`
177 unsafe fn remove_at(&mut self, idx: usize) -> T;
178
179 /// Returns a reference to the element at the index `idx`.
180 ///
181 /// # Formal
182 ///
183 /// **Preconditions**:
184 /// - `idx < self.cap()`
185 /// - `self.has_element_at(idx) == true` (implying `idx < self.len()`)
186 unsafe fn get_unchecked(&self, idx: usize) -> &T;
187
188 /// Returns a mutable reference to the element at the index `idx`.
189 ///
190 /// # Formal
191 ///
192 /// **Preconditions**:
193 /// - `idx < self.cap()`
194 /// - `self.has_element_at(idx) == true` (implying `idx < self.len()`)
195 unsafe fn get_unchecked_mut(&mut self, idx: usize) -> &mut T;
196
197 /// Deletes all elements without deallocating memory. Drops all existing
198 /// elements. Sets `len` to 0.
199 ///
200 /// **Note**: not actually used by `StableVecFacade::clear`, as it isn't
201 /// possible to do that safely. This method will be changed or removed in
202 /// the next major version.
203 ///
204 /// # Formal
205 ///
206 /// **Invariants**:
207 /// - `self.cap()`
208 ///
209 /// **Postconditons**:
210 /// - `self.len() == 0` (implying all slots are empty)
211 fn clear(&mut self);
212
213 /// Performs a forwards search starting at index `idx`, returning the
214 /// index of the first filled slot that is found.
215 ///
216 /// Specifically, if an element at index `idx` exists, `Some(idx)` is
217 /// returned.
218 ///
219 /// The inputs `idx >= self.len()` are only allowed for convenience and
220 /// because it doesn't make the implementation more complicated. For those
221 /// `idx` values, `None` is always returned.
222 ///
223 /// # Formal
224 ///
225 /// **Preconditions**:
226 /// - `idx ≤ self.cap()`
227 ///
228 /// **Postconditons** (for return value `out`):
229 /// - if `out == None`:
230 /// - ∀ i in `idx..self.len()` ⇒ `self.has_element_at(i) == false`
231 /// - if `out == Some(j)`:
232 /// - ∀ i in `idx..j` ⇒ `self.has_element_at(i) == false`
233 /// - `self.has_element_at(j) == true`
234 unsafe fn first_filled_slot_from(&self, idx: usize) -> Option<usize> {
235 debug_assert!(idx <= self.cap());
236
237 (idx..self.len()).find(|&idx| self.has_element_at(idx))
238 }
239
240 /// Performs a backwards search starting at index `idx - 1`, returning the
241 /// index of the first filled slot that is found.
242 ///
243 /// Note: passing in `idx >= self.len()` just wastes time, as those slots
244 /// are never filled.
245 ///
246 /// # Formal
247 ///
248 /// **Preconditions**:
249 /// - `idx <= self.cap()`
250 ///
251 /// **Postconditons** (for return value `out`):
252 /// - if `out == None`:
253 /// - ∀ i in `0..idx` ⇒ `self.has_element_at(i) == false`
254 /// - if `out == Some(j)`:
255 /// - ∀ i in `j + 1..idx` ⇒ `self.has_element_at(i) == false`
256 /// - `self.has_element_at(j) == true`
257 unsafe fn first_filled_slot_below(&self, idx: usize) -> Option<usize> {
258 debug_assert!(idx <= self.cap());
259
260 (0..idx).rev().find(|&idx| self.has_element_at(idx))
261 }
262
263 /// Performs a forwards search starting at index `idx`, returning the
264 /// index of the first empty slot that is found.
265 ///
266 /// # Formal
267 ///
268 /// **Preconditions**:
269 /// - `idx ≤ self.cap()`
270 ///
271 /// **Postconditons** (for return value `out`):
272 /// - if `out == None`:
273 /// - ∀ i in `idx..self.len()` ⇒ `self.has_element_at(i) == true`
274 /// - if `out == Some(j)`:
275 /// - ∀ i in `idx..j` ⇒ `self.has_element_at(i) == true`
276 /// - `self.has_element_at(j) == false`
277 unsafe fn first_empty_slot_from(&self, idx: usize) -> Option<usize> {
278 debug_assert!(idx <= self.cap());
279
280 (idx..self.cap()).find(|&idx| !self.has_element_at(idx))
281 }
282
283 /// Performs a backwards search starting at index `idx - 1`, returning the
284 /// index of the first empty slot that is found.
285 ///
286 /// If `idx > self.len()`, `Some(idx)` is always returned (remember the
287 /// preconditions tho!).
288 ///
289 /// # Formal
290 ///
291 /// **Preconditions**:
292 /// - `idx <= self.cap()`
293 ///
294 /// **Postconditons** (for return value `out`):
295 /// - if `out == None`:
296 /// - ∀ i in `0..idx` ⇒ `self.has_element_at(i) == true`
297 /// - if `out == Some(j)`:
298 /// - ∀ i in `j + 1..idx` ⇒ `self.has_element_at(i) == true`
299 /// - `self.has_element_at(j) == false`
300 unsafe fn first_empty_slot_below(&self, idx: usize) -> Option<usize> {
301 debug_assert!(idx <= self.cap());
302
303 (0..idx).rev().find(|&idx| !self.has_element_at(idx))
304 }
305
306 /// Swaps the two slots with indices `a` and `b`. That is: the element
307 /// *and* the "filled/empty" status are swapped. The slots at indices `a`
308 /// and `b` can be empty or filled.
309 ///
310 /// # Formal
311 ///
312 /// **Preconditions**:
313 /// - `a < self.cap()`
314 /// - `b < self.cap()`
315 ///
316 /// **Invariants**:
317 /// - `self.len()`
318 /// - `self.cap()`
319 ///
320 /// **Postconditons** (with `before` being `self` before the call):
321 /// - `before.has_element_at(a) == self.has_element_at(b)`
322 /// - `before.has_element_at(b) == self.has_element_at(a)`
323 /// - if `self.has_element_at(a)`:
324 /// - `self.get_unchecked(a) == before.get_unchecked(b)`
325 /// - if `self.has_element_at(b)`:
326 /// - `self.get_unchecked(b) == before.get_unchecked(a)`
327 unsafe fn swap(&mut self, a: usize, b: usize);
328}
329
330
331/// Just a wrapper around a core with a `PhantomData<T>` field to signal
332/// ownership of `T` (for variance and for the drop checker).
333///
334/// Implements `Deref` and `DerefMut`, returning the actual core. This is just
335/// a helper so that not all structs storing a core have to also have a
336/// `PhantomData` field.
337#[derive(Clone)]
338#[allow(missing_debug_implementations)]
339pub(crate) struct OwningCore<T, C: Core<T>> {
340 core: C,
341 _dummy: PhantomData<T>,
342}
343
344impl<T, C: Core<T>> OwningCore<T, C> {
345 pub(crate) fn new(core: C) -> Self {
346 Self {
347 core,
348 _dummy: PhantomData,
349 }
350 }
351}
352
353impl<T, C: Core<T> + fmt::Debug> fmt::Debug for OwningCore<T, C> {
354 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
355 self.core.fmt(f)
356 }
357}
358
359impl<T, C: Core<T>> Deref for OwningCore<T, C> {
360 type Target = C;
361 fn deref(&self) -> &Self::Target {
362 &self.core
363 }
364}
365
366impl<T, C: Core<T>> DerefMut for OwningCore<T, C> {
367 fn deref_mut(&mut self) -> &mut Self::Target {
368 &mut self.core
369 }
370}