pub trait StorageProvider<T> {
type StorageType: Storage<T>;
fn new() -> Self;
fn new_storage(&mut self) -> Self::StorageType;
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType;
}
pub trait Storage<T>: Clone {
type Provider: StorageProvider<T, StorageType = Self>;
fn clear(&mut self);
fn push(&mut self, value: T);
fn pop(&mut self) -> Option<T>;
fn as_slice(&self) -> &[T];
fn as_mut_slice(&mut self) -> &mut [T];
#[inline]
fn len(&self) -> usize {
self.as_slice().len()
}
fn capacity(&self) -> usize;
}
#[cfg(feature = "alloc")]
pub mod vec {
extern crate alloc;
use alloc::vec::Vec;
use super::{Storage, StorageProvider};
pub struct VecStorage;
impl<T> StorageProvider<T> for VecStorage
where
T: Clone,
{
type StorageType = Vec<T>;
#[inline]
fn new() -> Self {
Self
}
#[inline]
fn new_storage(&mut self) -> Self::StorageType {
Self::StorageType::new()
}
#[inline]
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType {
Self::StorageType::with_capacity(capacity)
}
}
impl<T> Storage<T> for Vec<T>
where
T: Clone,
{
type Provider = VecStorage;
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn push(&mut self, value: T) {
self.push(value);
}
#[inline]
fn pop(&mut self) -> Option<T> {
self.pop()
}
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn as_slice(&self) -> &[T] {
self.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
}
#[cfg(feature = "tinyvec")]
pub mod tinyvec {
use super::{Storage, StorageProvider};
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "alloc")]
pub use tinyvec::TinyVec;
pub use tinyvec::{Array, ArrayVec};
pub struct TinyVecArrayStorage<const CAP: usize>;
impl<const CAP: usize, T> StorageProvider<T> for TinyVecArrayStorage<CAP>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type StorageType = ArrayVec<[T; CAP]>;
#[inline]
fn new() -> Self {
Self
}
#[inline]
fn new_storage(&mut self) -> Self::StorageType {
Self::StorageType::new()
}
#[inline]
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType {
if capacity > <[T; CAP] as Array>::CAPACITY {
panic!(
"Requested capacity of {} exceeds maximum of {}",
capacity,
<[T; CAP] as Array>::CAPACITY
)
}
Self::StorageType::new()
}
}
impl<const CAP: usize, T> Storage<T> for ArrayVec<[T; CAP]>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type Provider = TinyVecArrayStorage<CAP>;
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn push(&mut self, value: T) {
self.push(value);
}
#[inline]
fn pop(&mut self) -> Option<T> {
self.pop()
}
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn as_slice(&self) -> &[T] {
self.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
#[cfg(feature = "alloc")]
pub struct TinyVecStorage<const CAP: usize>;
#[cfg(feature = "alloc")]
impl<const CAP: usize, T> StorageProvider<T> for TinyVecStorage<CAP>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type StorageType = TinyVec<[T; CAP]>;
#[inline]
fn new() -> Self {
Self
}
#[inline]
fn new_storage(&mut self) -> Self::StorageType {
Self::StorageType::new()
}
#[inline]
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType {
if capacity <= <[T; CAP] as Array>::CAPACITY {
TinyVec::Inline(ArrayVec::new())
} else {
TinyVec::Heap(Vec::with_capacity(capacity))
}
}
}
#[cfg(feature = "alloc")]
impl<const CAP: usize, T> Storage<T> for TinyVec<[T; CAP]>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type Provider = TinyVecStorage<CAP>;
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn push(&mut self, value: T) {
self.push(value);
}
#[inline]
fn pop(&mut self) -> Option<T> {
self.pop()
}
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn as_slice(&self) -> &[T] {
self.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
}
#[cfg(feature = "arrayvec")]
pub mod arrayvec {
use super::{Storage, StorageProvider};
pub use arrayvec::ArrayVec;
pub struct ArrayVecStorage<const CAP: usize>;
impl<const CAP: usize, T> StorageProvider<T> for ArrayVecStorage<CAP>
where
T: Clone,
{
type StorageType = ArrayVec<T, CAP>;
#[inline]
fn new() -> Self {
Self
}
#[inline]
fn new_storage(&mut self) -> Self::StorageType {
Self::StorageType::new()
}
#[inline]
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType {
if capacity > CAP {
panic!(
"Requested capacity of {} exceeds maximum of {}",
capacity, CAP
)
}
Self::StorageType::new()
}
}
impl<const CAP: usize, T> Storage<T> for ArrayVec<T, CAP>
where
T: Clone,
{
type Provider = ArrayVecStorage<CAP>;
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn push(&mut self, value: T) {
self.push(value);
}
#[inline]
fn pop(&mut self) -> Option<T> {
self.pop()
}
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn as_slice(&self) -> &[T] {
self.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
}
#[cfg(feature = "smallvec")]
pub mod smallvec {
use super::{Storage, StorageProvider};
pub use smallvec::{Array, SmallVec};
pub struct SmallVecStorage<const CAP: usize>;
impl<const CAP: usize, T> StorageProvider<T> for SmallVecStorage<CAP>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type StorageType = SmallVec<[T; CAP]>;
#[inline]
fn new() -> Self {
Self
}
#[inline]
fn new_storage(&mut self) -> Self::StorageType {
Self::StorageType::new()
}
#[inline]
fn storage_with_capacity(&mut self, capacity: usize) -> Self::StorageType {
SmallVec::with_capacity(capacity)
}
}
impl<const CAP: usize, T> Storage<T> for SmallVec<[T; CAP]>
where
T: Clone,
[T; CAP]: Array<Item = T>,
{
type Provider = SmallVecStorage<CAP>;
#[inline]
fn clear(&mut self) {
self.clear();
}
#[inline]
fn push(&mut self, value: T) {
self.push(value);
}
#[inline]
fn pop(&mut self) -> Option<T> {
self.pop()
}
#[inline]
fn len(&self) -> usize {
self.len()
}
#[inline]
fn capacity(&self) -> usize {
self.capacity()
}
#[inline]
fn as_slice(&self) -> &[T] {
self.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
}