#[cfg(feature = "alloc")]
use alloc::collections::TryReserveError;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::fmt;
pub unsafe trait SlotStorage<S>:
IntoIterator<Item = S, IntoIter: DoubleEndedIterator + ExactSizeIterator>
{
type Error: fmt::Debug;
const EMPTY: Self;
fn with_capacity(capacity: usize) -> Self;
fn capacity(&self) -> usize;
fn as_slice(&self) -> &[S];
fn as_mut_slice(&mut self) -> &mut [S];
fn ensure_room(&mut self) -> Result<(), Self::Error>;
fn try_push(&mut self, item: S) -> Result<(), S>;
fn clear(&mut self);
#[inline]
fn len(&self) -> usize {
self.as_slice().len()
}
#[inline]
fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
}
pub trait ReserveStorage<S>: SlotStorage<S> {
fn reserve(&mut self, additional: usize);
fn try_reserve(&mut self, additional: usize) -> Result<(), Self::Error>;
}
#[cfg(feature = "alloc")]
unsafe impl<S> SlotStorage<S> for Vec<S> {
type Error = TryReserveError;
const EMPTY: Self = Vec::new();
#[inline]
fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity)
}
#[inline]
fn capacity(&self) -> usize {
Vec::capacity(self)
}
#[inline]
fn as_slice(&self) -> &[S] {
self
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [S] {
self
}
#[inline]
fn ensure_room(&mut self) -> Result<(), TryReserveError> {
Vec::try_reserve(self, 1)
}
#[inline]
fn try_push(&mut self, item: S) -> Result<(), S> {
match Vec::try_reserve(self, 1) {
Ok(()) => {
Vec::push(self, item);
Ok(())
}
Err(_) => Err(item),
}
}
#[inline]
fn clear(&mut self) {
Vec::clear(self)
}
}
#[cfg(feature = "alloc")]
impl<S> ReserveStorage<S> for Vec<S> {
#[inline]
fn reserve(&mut self, additional: usize) {
Vec::reserve(self, additional);
}
#[inline]
fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
Vec::try_reserve(self, additional)
}
}
#[cfg(feature = "arrayvec")]
unsafe impl<S, const CAP: usize> SlotStorage<S> for arrayvec::ArrayVec<S, CAP> {
type Error = arrayvec::CapacityError;
const EMPTY: Self = arrayvec::ArrayVec::new_const();
#[inline]
fn with_capacity(_capacity: usize) -> Self {
arrayvec::ArrayVec::new_const()
}
#[inline]
fn capacity(&self) -> usize {
CAP
}
#[inline]
fn as_slice(&self) -> &[S] {
self
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [S] {
self
}
#[inline]
fn ensure_room(&mut self) -> Result<(), arrayvec::CapacityError> {
if arrayvec::ArrayVec::is_full(self) {
Err(arrayvec::CapacityError::new(()))
} else {
Ok(())
}
}
#[inline]
fn try_push(&mut self, item: S) -> Result<(), S> {
arrayvec::ArrayVec::try_push(self, item).map_err(arrayvec::CapacityError::element)
}
#[inline]
fn clear(&mut self) {
arrayvec::ArrayVec::clear(self);
}
}
#[cfg(feature = "smallvec")]
unsafe impl<S, const N: usize> SlotStorage<S> for smallvec::SmallVec<S, N> {
type Error = smallvec::CollectionAllocErr;
const EMPTY: Self = smallvec::SmallVec::new();
#[inline]
fn with_capacity(capacity: usize) -> Self {
smallvec::SmallVec::with_capacity(capacity)
}
#[inline]
fn capacity(&self) -> usize {
smallvec::SmallVec::capacity(self)
}
#[inline]
fn as_slice(&self) -> &[S] {
self
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [S] {
self
}
#[inline]
fn ensure_room(&mut self) -> Result<(), smallvec::CollectionAllocErr> {
smallvec::SmallVec::try_reserve(self, 1)
}
#[inline]
fn try_push(&mut self, item: S) -> Result<(), S> {
match smallvec::SmallVec::try_reserve(self, 1) {
Ok(()) => {
smallvec::SmallVec::push(self, item);
Ok(())
}
Err(_) => Err(item),
}
}
#[inline]
fn clear(&mut self) {
smallvec::SmallVec::clear(self);
}
}
#[cfg(feature = "smallvec")]
impl<S, const N: usize> ReserveStorage<S> for smallvec::SmallVec<S, N> {
#[inline]
fn reserve(&mut self, additional: usize) {
smallvec::SmallVec::reserve(self, additional);
}
#[inline]
fn try_reserve(&mut self, additional: usize) -> Result<(), smallvec::CollectionAllocErr> {
smallvec::SmallVec::try_reserve(self, additional)
}
}