Skip to main content

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}