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