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/// **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}