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