#![deny(missing_debug_implementations)]
#![deny(broken_intra_doc_links)]
#![no_std]
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(not(test))]
extern crate no_std_compat as std;
use std::{
prelude::v1::*,
cmp,
fmt,
iter::FromIterator,
mem,
ops::{Index, IndexMut},
};
use crate::{
core::{Core, DefaultCore, OwningCore, OptionCore, BitVecCore},
iter::{Indices, Iter, IterMut, IntoIter, Values, ValuesMut},
};
#[cfg(test)]
mod tests;
pub mod core;
pub mod iter;
pub type StableVec<T> = StableVecFacade<T, DefaultCore<T>>;
pub type InlineStableVec<T> = StableVecFacade<T, OptionCore<T>>;
pub type ExternStableVec<T> = StableVecFacade<T, BitVecCore<T>>;
#[derive(Clone)]
pub struct StableVecFacade<T, C: Core<T>> {
core: OwningCore<T, C>,
num_elements: usize,
}
impl<T, C: Core<T>> StableVecFacade<T, C> {
pub fn new() -> Self {
Self {
core: OwningCore::new(C::new()),
num_elements: 0,
}
}
pub fn with_capacity(capacity: usize) -> Self {
let mut out = Self::new();
out.reserve_exact(capacity);
out
}
pub fn push(&mut self, elem: T) -> usize {
let index = self.core.len();
self.reserve(1);
unsafe {
self.core.set_len(index + 1);
self.core.insert_at(index, elem);
}
self.num_elements += 1;
index
}
pub fn insert(&mut self, index: usize, mut elem: T) -> Option<T> {
if index >= self.core.cap() {
panic!(
"`index ({}) >= capacity ({})` in `StableVecFacade::insert`",
index,
self.core.cap(),
);
}
if self.has_element_at(index) {
unsafe {
mem::swap(self.core.get_unchecked_mut(index), &mut elem);
}
Some(elem)
} else {
if index >= self.core.len() {
unsafe {
self.core.set_len(index + 1);
}
}
unsafe {
self.core.insert_at(index, elem);
}
self.num_elements += 1;
None
}
}
pub fn remove(&mut self, index: usize) -> Option<T> {
if index >= self.core.cap() {
panic!(
"`index ({}) >= capacity ({})` in `StableVecFacade::remove`",
index,
self.core.cap(),
);
}
if self.has_element_at(index) {
let elem = unsafe {
self.core.remove_at(index)
};
self.num_elements -= 1;
Some(elem)
} else {
None
}
}
pub fn clear(&mut self) {
self.core.clear();
self.num_elements = 0;
}
pub fn get(&self, index: usize) -> Option<&T> {
if self.has_element_at(index) {
let elem = unsafe {
self.core.get_unchecked(index)
};
Some(elem)
} else {
None
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if self.has_element_at(index) {
let elem = unsafe {
self.core.get_unchecked_mut(index)
};
Some(elem)
} else {
None
}
}
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
self.core.get_unchecked(index)
}
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
self.core.get_unchecked_mut(index)
}
pub fn has_element_at(&self, index: usize) -> bool {
if index >= self.core.cap() {
false
} else {
unsafe {
self.core.has_element_at(index)
}
}
}
pub fn num_elements(&self) -> usize {
self.num_elements
}
pub fn next_push_index(&self) -> usize {
self.core.len()
}
pub fn capacity(&self) -> usize {
self.core.cap()
}
pub fn is_empty(&self) -> bool {
self.num_elements == 0
}
pub fn is_compact(&self) -> bool {
self.num_elements == self.core.len()
}
pub fn iter(&self) -> Iter<'_, T, C> {
Iter::new(self)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T, C> {
IterMut::new(self)
}
pub fn values(&self) -> Values<'_, T, C> {
Values::new(self)
}
pub fn values_mut(&mut self) -> ValuesMut<T, C> {
ValuesMut::new(self)
}
pub fn indices(&self) -> Indices<'_, T, C> {
Indices::new(self)
}
pub fn reserve(&mut self, additional: usize) {
#[inline(never)]
#[cold]
fn capacity_overflow() -> ! {
panic!("capacity overflow in `stable_vec::StableVecFacade::reserve` (attempt \
to allocate more than `isize::MAX` elements");
}
let new_cap = match self.core.len().checked_add(additional) {
None => capacity_overflow(),
Some(new_cap) => new_cap,
};
if self.core.cap() < new_cap {
let new_cap = cmp::max(new_cap, 2 * self.core.cap());
if new_cap > isize::max_value() as usize {
capacity_overflow();
}
unsafe {
self.core.realloc(new_cap);
}
}
}
pub fn reserve_for(&mut self, index: usize) {
if index >= self.capacity() {
self.reserve(1 + index - self.next_push_index());
}
}
pub fn reserve_exact(&mut self, additional: usize) {
#[inline(never)]
#[cold]
fn capacity_overflow() -> ! {
panic!("capacity overflow in `stable_vec::StableVecFacade::reserve_exact` (attempt \
to allocate more than `isize::MAX` elements");
}
let new_cap = match self.core.len().checked_add(additional) {
None => capacity_overflow(),
Some(new_cap) => new_cap,
};
if self.core.cap() < new_cap {
if new_cap > isize::max_value() as usize {
capacity_overflow();
}
unsafe {
self.core.realloc(new_cap);
}
}
}
pub fn remove_first(&mut self) -> Option<T> {
self.find_first_index().and_then(|index| self.remove(index))
}
pub fn remove_last(&mut self) -> Option<T> {
self.find_last_index().and_then(|index| self.remove(index))
}
pub fn find_first(&self) -> Option<&T> {
self.find_first_index().map(|index| unsafe { self.core.get_unchecked(index) })
}
pub fn find_first_mut(&mut self) -> Option<&mut T> {
self.find_first_index().map(move |index| unsafe { self.core.get_unchecked_mut(index) })
}
pub fn find_last(&self) -> Option<&T> {
self.find_last_index().map(|index| unsafe { self.core.get_unchecked(index) })
}
pub fn find_last_mut(&mut self) -> Option<&mut T> {
self.find_last_index().map(move |index| unsafe { self.core.get_unchecked_mut(index) })
}
pub fn first_filled_slot_from(&self, start: usize) -> Option<usize> {
if start > self.core.cap() {
panic!(
"`start` is {}, but capacity is {} in `first_filled_slot_from`",
start,
self.capacity(),
);
} else {
unsafe { self.core.first_filled_slot_from(start) }
}
}
pub fn first_filled_slot_below(&self, start: usize) -> Option<usize> {
if start > self.core.cap() {
panic!(
"`start` is {}, but capacity is {} in `first_filled_slot_below`",
start,
self.capacity(),
);
} else {
unsafe { self.core.first_filled_slot_below(start) }
}
}
pub fn first_empty_slot_from(&self, start: usize) -> Option<usize> {
if start > self.core.cap() {
panic!(
"`start` is {}, but capacity is {} in `first_empty_slot_from`",
start,
self.capacity(),
);
} else {
unsafe { self.core.first_empty_slot_from(start) }
}
}
pub fn first_empty_slot_below(&self, start: usize) -> Option<usize> {
if start > self.core.cap() {
panic!(
"`start` is {}, but capacity is {} in `first_empty_slot_below`",
start,
self.capacity(),
);
} else {
unsafe { self.core.first_empty_slot_below(start) }
}
}
pub fn find_first_index(&self) -> Option<usize> {
unsafe {
self.core.first_filled_slot_from(0)
}
}
pub fn find_last_index(&self) -> Option<usize> {
unsafe {
self.core.first_filled_slot_below(self.core.len())
}
}
pub fn shrink_to_fit(&mut self) {
unsafe {
let new_cap = self.core.len();
self.core.realloc(new_cap);
}
}
pub fn make_compact(&mut self) {
if self.is_compact() {
return;
}
if self.num_elements > 0 {
unsafe {
let first_hole_index = self.core.first_empty_slot_from(0).unwrap();
let mut element_index = first_hole_index + 1;
for hole_index in first_hole_index..self.num_elements {
while !self.core.has_element_at(element_index) {
element_index += 1;
}
self.core.swap(hole_index, element_index);
}
}
}
unsafe {
self.core.set_len(self.num_elements);
}
}
pub fn reordering_make_compact(&mut self) {
if self.is_compact() {
return;
}
if self.num_elements > 0 {
unsafe {
let len = self.core.len();
let mut element_index = len;
let mut hole_index = 0;
loop {
element_index = self.core.first_filled_slot_below(element_index).unwrap_or(0);
hole_index = self.core.first_empty_slot_from(hole_index).unwrap_or(len);
if hole_index > element_index {
break;
}
self.core.swap(hole_index, element_index);
}
}
}
unsafe {
self.core.set_len(self.num_elements);
}
}
pub fn contains<U>(&self, item: &U) -> bool
where
U: PartialEq<T>,
{
self.values().any(|e| item == e)
}
pub fn swap(&mut self, a: usize, b: usize) {
assert!(a < self.core.cap());
assert!(b < self.core.cap());
let mut len = self.core.len();
if a >= len && self.has_element_at(b) {
len = a + 1;
}
if b >= len && self.has_element_at(a) {
len = b + 1;
}
unsafe { self.core.set_len(len) };
unsafe { self.core.swap(a, b) };
}
pub fn retain<P>(&mut self, mut should_be_kept: P)
where
P: FnMut(&T) -> bool,
{
let mut pos = 0;
unsafe {
while let Some(idx) = self.core.first_filled_slot_from(pos) {
let elem = self.core.get_unchecked(idx);
if !should_be_kept(elem) {
self.core.remove_at(idx);
self.num_elements -= 1;
}
pos = idx + 1;
}
}
}
pub fn retain_indices<P>(&mut self, mut should_be_kept: P)
where
P: FnMut(usize) -> bool,
{
let mut pos = 0;
unsafe {
while let Some(idx) = self.core.first_filled_slot_from(pos) {
if !should_be_kept(idx) {
self.core.remove_at(idx);
self.num_elements -= 1;
}
pos = idx + 1;
}
}
}
pub fn extend_from_slice(&mut self, new_elements: &[T])
where
T: Clone,
{
let len = new_elements.len();
self.reserve(len);
self.num_elements += len;
unsafe {
let mut i = self.core.len();
let new_len = self.core.len() + len;
self.core.set_len(new_len);
for elem in new_elements {
self.core.insert_at(i, elem.clone());
i += 1;
}
}
}
}
#[inline(never)]
#[cold]
fn index_fail(idx: usize) -> ! {
panic!("attempt to index StableVec with index {}, but no element exists at that index", idx);
}
impl<T, C: Core<T>> Index<usize> for StableVecFacade<T, C> {
type Output = T;
fn index(&self, index: usize) -> &T {
match self.get(index) {
Some(v) => v,
None => index_fail(index),
}
}
}
impl<T, C: Core<T>> IndexMut<usize> for StableVecFacade<T, C> {
fn index_mut(&mut self, index: usize) -> &mut T {
match self.get_mut(index) {
Some(v) => v,
None => index_fail(index),
}
}
}
impl<T, C: Core<T>> Default for StableVecFacade<T, C> {
fn default() -> Self {
Self::new()
}
}
impl<T, S, C: Core<T>> From<S> for StableVecFacade<T, C>
where
S: AsRef<[T]>,
T: Clone,
{
fn from(slice: S) -> Self {
let mut out = Self::new();
out.extend_from_slice(slice.as_ref());
out
}
}
impl<T, C: Core<T>> FromIterator<T> for StableVecFacade<T, C> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
let mut out = Self::new();
out.extend(iter);
out
}
}
impl<T, C: Core<T>> Extend<T> for StableVecFacade<T, C> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
let it = iter.into_iter();
self.reserve(it.size_hint().0);
for elem in it {
self.push(elem);
}
}
}
impl<'a, T, C: Core<T>> IntoIterator for &'a StableVecFacade<T, C> {
type Item = (usize, &'a T);
type IntoIter = Iter<'a, T, C>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, C: Core<T>> IntoIterator for &'a mut StableVecFacade<T, C> {
type Item = (usize, &'a mut T);
type IntoIter = IterMut<'a, T, C>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T, C: Core<T>> IntoIterator for StableVecFacade<T, C> {
type Item = (usize, T);
type IntoIter = IntoIter<T, C>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
impl<T: fmt::Debug, C: Core<T>> fmt::Debug for StableVecFacade<T, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "StableVec ")?;
f.debug_list().entries(self.values()).finish()
}
}
impl<Ta, Tb, Ca, Cb> PartialEq<StableVecFacade<Tb, Cb>> for StableVecFacade<Ta, Ca>
where
Ta: PartialEq<Tb>,
Ca: Core<Ta>,
Cb: Core<Tb>,
{
fn eq(&self, other: &StableVecFacade<Tb, Cb>) -> bool {
self.num_elements() == other.num_elements()
&& self.capacity() == other.capacity()
&& self.next_push_index() == other.next_push_index()
&& (0..self.capacity()).all(|idx| {
match (self.get(idx), other.get(idx)) {
(None, None) => true,
(Some(a), Some(b)) => a == b,
_ => false,
}
})
}
}
impl<T: Eq, C: Core<T>> Eq for StableVecFacade<T, C> {}
impl<A, B, C: Core<A>> PartialEq<[B]> for StableVecFacade<A, C>
where
A: PartialEq<B>,
{
fn eq(&self, other: &[B]) -> bool {
self.values().eq(other)
}
}
impl<'other, A, B, C: Core<A>> PartialEq<&'other [B]> for StableVecFacade<A, C>
where
A: PartialEq<B>,
{
fn eq(&self, other: &&'other [B]) -> bool {
self == *other
}
}
impl<A, B, C: Core<A>> PartialEq<Vec<B>> for StableVecFacade<A, C>
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<B>) -> bool {
self == &other[..]
}
}