#![feature(array_map)]
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(html_root_url = "https://docs.rs/holodeque/0.2.0")]
pub mod array_deque;
mod meta;
pub mod slice_deque;
use core::{fmt, mem};
use crate::meta::{Meta, MetaDrain, MetaLayout};
pub use crate::{array_deque::ArrayDeque, slice_deque::SliceDeque};
pub(crate) trait BaseDeque<T>
where
T: Default,
{
type Meta: Meta;
fn meta(&self) -> &Self::Meta;
fn meta_mut(&mut self) -> &mut Self::Meta;
fn items(&self) -> &[T];
fn items_mut(&mut self) -> &mut [T];
fn capacity(&self) -> usize;
#[inline]
fn len(&self) -> usize {
self.meta().len()
}
fn as_slices(&self) -> (&[T], &[T]) {
let (front, back) = self.meta().as_ranges();
(&self.items()[front], &self.items()[back])
}
fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
let (high_range, wrap_range) = self.meta().as_ranges();
if wrap_range.is_empty() {
return (&mut self.items_mut()[high_range], &mut []);
}
let (wrap, front) = self.items_mut().split_at_mut(wrap_range.end);
let front_range = high_range.start - wrap_range.end..high_range.end - wrap_range.end;
(&mut front[front_range], &mut wrap[wrap_range])
}
#[inline]
fn is_empty(&self) -> bool {
matches!(self.meta().layout(), MetaLayout::Empty)
}
#[inline]
fn is_full(&self) -> bool {
self.len() == self.capacity()
}
fn front(&self) -> Option<&T> {
let front = self.meta().front()?;
Some(&self.items()[front])
}
fn front_mut(&mut self) -> Option<&mut T> {
let front = self.meta().front()?;
Some(&mut self.items_mut()[front])
}
fn back(&self) -> Option<&T> {
let back = self.meta().back()?;
Some(&self.items()[back])
}
fn back_mut(&mut self) -> Option<&mut T> {
let back = self.meta().back()?;
Some(&mut self.items_mut()[back])
}
fn push_front(&mut self, item: T) -> Result<(), CapacityError<T>> {
match self.meta_mut().reserve_front() {
Some(front) => {
self.items_mut()[front] = item;
Ok(())
}
None => Err(CapacityError { item }),
}
}
fn push_back(&mut self, item: T) -> Result<(), CapacityError<T>> {
match self.meta_mut().reserve_back() {
Some(back) => {
self.items_mut()[back] = item;
Ok(())
}
None => Err(CapacityError { item }),
}
}
fn pop_front(&mut self) -> Option<T> {
let freed = self.meta_mut().free_front()?;
Some(mem::take(&mut self.items_mut()[freed]))
}
fn pop_back(&mut self) -> Option<T> {
let freed = self.meta_mut().free_back()?;
Some(mem::take(&mut self.items_mut()[freed]))
}
fn clear(&mut self) {
for freed in self.meta_mut().clear() {
drop(mem::take(&mut self.items_mut()[freed]));
}
}
fn truncate(&mut self, len: usize) {
let n = self.len().saturating_sub(len);
if let Some(drain) = self.meta_mut().drain_back(n) {
for freed in drain {
drop(mem::take(&mut self.items_mut()[freed]));
}
}
}
}
pub(crate) struct DequeIter<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
meta: D::Meta,
deque: &'a D,
}
impl<'a, D, T> DequeIter<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
pub fn new(deque: &'a D) -> DequeIter<'a, D, T> {
DequeIter {
meta: deque.meta().clone(),
deque,
}
}
}
impl<'a, D, T> Iterator for DequeIter<'a, D, T>
where
D: BaseDeque<T>,
T: Default + 'a,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let next = self.meta.free_front()?;
Some(&self.deque.items()[next])
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.meta.len(), Some(self.meta.len()))
}
}
impl<'a, D, T> DoubleEndedIterator for DequeIter<'a, D, T>
where
D: BaseDeque<T>,
T: Default + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
let next_back = self.meta.free_back()?;
Some(&self.deque.items()[next_back])
}
}
pub(crate) struct DequeDrain<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
meta: MetaDrain<D::Meta>,
deque: &'a mut D,
}
impl<'a, D, T> DequeDrain<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
fn front(deque: &'a mut D, n: usize) -> Option<DequeDrain<'a, D, T>> {
let meta = deque.meta_mut().drain_front(n)?;
Some(DequeDrain { meta, deque })
}
fn back(deque: &'a mut D, n: usize) -> Option<DequeDrain<'a, D, T>> {
let meta = deque.meta_mut().drain_back(n)?;
Some(DequeDrain { meta, deque })
}
}
impl<'a, D, T> Iterator for DequeDrain<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let next = self.meta.next()?;
Some(mem::take(&mut self.deque.items_mut()[next]))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.meta.size_hint()
}
}
impl<'a, D, T> Drop for DequeDrain<'a, D, T>
where
D: BaseDeque<T>,
T: Default,
{
fn drop(&mut self) {
for index in &mut self.meta {
drop(mem::take(&mut self.deque.items_mut()[index]))
}
}
}
#[derive(Debug)]
pub struct CapacityError<T> {
item: T,
}
impl<T> CapacityError<T> {
pub fn get(&self) -> &T {
&self.item
}
pub fn into_inner(self) -> T {
self.item
}
}
impl<T> fmt::Display for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("deque capacity exceeded")
}
}
#[cfg(feature = "std")]
impl<T> std::error::Error for CapacityError<T> where T: fmt::Debug {}
pub(crate) enum DequeEnd {
Front,
Back,
}