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}