use crate::{
vec::{OwnedVecStorage, VecStorage, VecStorageInner, ViewVecStorage},
CapacityError,
};
use core::{
cmp::Ordering,
fmt,
iter::FusedIterator,
marker::PhantomData,
mem::{ManuallyDrop, MaybeUninit},
ptr, slice,
};
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
#[cfg_attr(feature = "zeroize", derive(Zeroize))]
pub struct DequeInner<T, S: VecStorage<T> + ?Sized> {
phantom: PhantomData<T>,
front: usize,
back: usize,
full: bool,
buffer: S,
}
pub type Deque<T, const N: usize> = DequeInner<T, OwnedVecStorage<T, N>>;
pub type DequeView<T> = DequeInner<T, ViewVecStorage<T>>;
impl<T, const N: usize> Deque<T, N> {
const INIT: MaybeUninit<T> = MaybeUninit::uninit();
pub const fn new() -> Self {
const {
assert!(N > 0);
}
Self {
phantom: PhantomData,
buffer: VecStorageInner {
buffer: [Self::INIT; N],
},
front: 0,
back: 0,
full: false,
}
}
pub const fn capacity(&self) -> usize {
N
}
pub const fn len(&self) -> usize {
if self.full {
N
} else if self.back < self.front {
self.back + N - self.front
} else {
self.back - self.front
}
}
}
impl<T, S: VecStorage<T> + ?Sized> DequeInner<T, S> {
pub fn as_view(&self) -> &DequeView<T> {
S::as_deque_view(self)
}
pub fn as_mut_view(&mut self) -> &mut DequeView<T> {
S::as_deque_view_mut(self)
}
pub fn storage_capacity(&self) -> usize {
self.buffer.borrow().len()
}
fn increment(&self, i: usize) -> usize {
if i + 1 == self.storage_capacity() {
0
} else {
i + 1
}
}
fn decrement(&self, i: usize) -> usize {
if i == 0 {
self.storage_capacity() - 1
} else {
i - 1
}
}
pub fn storage_len(&self) -> usize {
if self.full {
self.storage_capacity()
} else if self.back < self.front {
self.back + self.storage_capacity() - self.front
} else {
self.back - self.front
}
}
pub fn clear(&mut self) {
unsafe { self.drop_contents() }
self.front = 0;
self.back = 0;
self.full = false;
}
unsafe fn drop_contents(&mut self) {
let (a, b) = self.as_mut_slices();
ptr::drop_in_place(a);
ptr::drop_in_place(b);
}
pub fn is_empty(&self) -> bool {
self.front == self.back && !self.full
}
pub fn is_full(&self) -> bool {
self.full
}
pub fn as_slices(&self) -> (&[T], &[T]) {
unsafe {
if self.is_empty() {
(&[], &[])
} else if self.back <= self.front {
(
slice::from_raw_parts(
self.buffer.borrow().as_ptr().add(self.front).cast::<T>(),
self.storage_capacity() - self.front,
),
slice::from_raw_parts(self.buffer.borrow().as_ptr().cast::<T>(), self.back),
)
} else {
(
slice::from_raw_parts(
self.buffer.borrow().as_ptr().add(self.front).cast::<T>(),
self.back - self.front,
),
&[],
)
}
}
}
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
let ptr = self.buffer.borrow_mut().as_mut_ptr();
unsafe {
if self.is_empty() {
(&mut [], &mut [])
} else if self.back <= self.front {
(
slice::from_raw_parts_mut(
ptr.add(self.front).cast::<T>(),
self.storage_capacity() - self.front,
),
slice::from_raw_parts_mut(ptr.cast::<T>(), self.back),
)
} else {
(
slice::from_raw_parts_mut(
ptr.add(self.front).cast::<T>(),
self.back - self.front,
),
&mut [],
)
}
}
}
#[inline]
fn is_contiguous(&self) -> bool {
self.front <= self.storage_capacity() - self.storage_len()
}
pub fn make_contiguous(&mut self) -> &mut [T] {
if self.is_contiguous() {
return unsafe {
slice::from_raw_parts_mut(
self.buffer.borrow_mut().as_mut_ptr().add(self.front).cast(),
self.storage_len(),
)
};
}
let buffer_ptr: *mut T = self.buffer.borrow_mut().as_mut_ptr().cast();
let len = self.storage_len();
let free = self.storage_capacity() - len;
let front_len = self.storage_capacity() - self.front;
let back = len - front_len;
let back_len = back;
if free >= front_len {
unsafe {
ptr::copy(buffer_ptr, buffer_ptr.add(front_len), back_len);
ptr::copy_nonoverlapping(buffer_ptr.add(self.front), buffer_ptr, front_len);
}
self.front = 0;
self.back = len;
} else if free >= back_len {
unsafe {
ptr::copy(
buffer_ptr.add(self.front),
buffer_ptr.add(self.back),
front_len,
);
ptr::copy_nonoverlapping(
buffer_ptr,
buffer_ptr.add(self.back + front_len),
back_len,
);
}
self.front = back;
self.back = 0;
} else {
if front_len > back_len {
unsafe {
if free != 0 {
ptr::copy(buffer_ptr, buffer_ptr.add(free), back_len);
}
let slice: &mut [T] = slice::from_raw_parts_mut(
buffer_ptr.add(free),
self.storage_capacity() - free,
);
slice.rotate_left(back_len);
self.front = free;
self.back = 0;
}
} else {
unsafe {
if free != 0 {
ptr::copy(
buffer_ptr.add(self.front),
buffer_ptr.add(back_len),
front_len,
);
}
let slice: &mut [T] = slice::from_raw_parts_mut(buffer_ptr, len);
slice.rotate_right(front_len);
self.front = 0;
self.back = len;
}
}
}
unsafe { slice::from_raw_parts_mut(buffer_ptr.add(self.front), len) }
}
pub fn front(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
Some(unsafe { &*self.buffer.borrow().get_unchecked(self.front).as_ptr() })
}
}
pub fn front_mut(&mut self) -> Option<&mut T> {
if self.is_empty() {
None
} else {
Some(unsafe {
&mut *self
.buffer
.borrow_mut()
.get_unchecked_mut(self.front)
.as_mut_ptr()
})
}
}
pub fn back(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
let index = self.decrement(self.back);
Some(unsafe { &*self.buffer.borrow().get_unchecked(index).as_ptr() })
}
}
pub fn back_mut(&mut self) -> Option<&mut T> {
if self.is_empty() {
None
} else {
let index = self.decrement(self.back);
Some(unsafe {
&mut *self
.buffer
.borrow_mut()
.get_unchecked_mut(index)
.as_mut_ptr()
})
}
}
pub fn pop_front(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
Some(unsafe { self.pop_front_unchecked() })
}
}
pub fn pop_back(&mut self) -> Option<T> {
if self.is_empty() {
None
} else {
Some(unsafe { self.pop_back_unchecked() })
}
}
pub fn push_front(&mut self, item: T) -> Result<(), T> {
if self.is_full() {
Err(item)
} else {
unsafe { self.push_front_unchecked(item) }
Ok(())
}
}
pub fn push_back(&mut self, item: T) -> Result<(), T> {
if self.is_full() {
Err(item)
} else {
unsafe { self.push_back_unchecked(item) }
Ok(())
}
}
pub unsafe fn pop_front_unchecked(&mut self) -> T {
debug_assert!(!self.is_empty());
let index = self.front;
self.full = false;
self.front = self.increment(self.front);
self.buffer
.borrow_mut()
.get_unchecked_mut(index)
.as_ptr()
.read()
}
pub unsafe fn pop_back_unchecked(&mut self) -> T {
debug_assert!(!self.is_empty());
self.full = false;
self.back = self.decrement(self.back);
self.buffer
.borrow_mut()
.get_unchecked_mut(self.back)
.as_ptr()
.read()
}
pub unsafe fn push_front_unchecked(&mut self, item: T) {
debug_assert!(!self.is_full());
let index = self.decrement(self.front);
*self.buffer.borrow_mut().get_unchecked_mut(index) = MaybeUninit::new(item);
self.front = index;
if self.front == self.back {
self.full = true;
}
}
pub unsafe fn push_back_unchecked(&mut self, item: T) {
debug_assert!(!self.is_full());
*self.buffer.borrow_mut().get_unchecked_mut(self.back) = MaybeUninit::new(item);
self.back = self.increment(self.back);
if self.front == self.back {
self.full = true;
}
}
pub fn get(&self, index: usize) -> Option<&T> {
if index < self.storage_len() {
let idx = self.to_physical_index(index);
Some(unsafe { self.buffer.borrow().get_unchecked(idx).assume_init_ref() })
} else {
None
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index < self.storage_len() {
let idx = self.to_physical_index(index);
Some(unsafe {
self.buffer
.borrow_mut()
.get_unchecked_mut(idx)
.assume_init_mut()
})
} else {
None
}
}
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
debug_assert!(index < self.storage_len());
let idx = self.to_physical_index(index);
self.buffer.borrow().get_unchecked(idx).assume_init_ref()
}
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
debug_assert!(index < self.storage_len());
let idx = self.to_physical_index(index);
self.buffer
.borrow_mut()
.get_unchecked_mut(idx)
.assume_init_mut()
}
pub fn swap(&mut self, i: usize, j: usize) {
let len = self.storage_len();
assert!(i < len);
assert!(j < len);
unsafe { self.swap_unchecked(i, j) }
}
pub unsafe fn swap_unchecked(&mut self, i: usize, j: usize) {
debug_assert!(i < self.storage_len());
debug_assert!(j < self.storage_len());
let idx_i = self.to_physical_index(i);
let idx_j = self.to_physical_index(j);
let buffer = self.buffer.borrow_mut();
let buffer_ptr = buffer.as_mut_ptr();
let ptr_i = buffer_ptr.add(idx_i);
let ptr_j = buffer_ptr.add(idx_j);
ptr::swap(ptr_i, ptr_j);
}
pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
let len = self.storage_len();
if len > 0 && index < len {
Some(unsafe {
self.swap_unchecked(index, 0);
self.pop_front_unchecked()
})
} else {
None
}
}
pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
let len = self.storage_len();
if len > 0 && index < len {
Some(unsafe {
self.swap_unchecked(index, len - 1);
self.pop_back_unchecked()
})
} else {
None
}
}
fn to_physical_index(&self, index: usize) -> usize {
let mut res = self.front + index;
if res >= self.storage_capacity() {
res -= self.storage_capacity();
}
res
}
pub fn iter(&self) -> Iter<'_, T> {
let (start, end) = self.as_slices();
Iter {
inner: start.iter().chain(end),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
let (start, end) = self.as_mut_slices();
IterMut {
inner: start.iter_mut().chain(end),
}
}
pub fn truncate(&mut self, len: usize) {
struct Dropper<'a, T>(&'a mut [T]);
impl<'a, T> Drop for Dropper<'a, T> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(self.0);
}
}
}
unsafe {
if len >= self.storage_len() {
return;
}
let (front, back) = self.as_mut_slices();
if len > front.len() {
let begin = len - front.len();
let drop_back = back.get_unchecked_mut(begin..) as *mut _;
self.back = self.to_physical_index(len);
self.full = false;
ptr::drop_in_place(drop_back);
} else {
let drop_back = back as *mut _;
let drop_front = front.get_unchecked_mut(len..) as *mut _;
self.back = self.to_physical_index(len);
self.full = false;
let _back_dropper = Dropper(&mut *drop_back);
ptr::drop_in_place(drop_front);
}
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
self.retain_mut(|elem| f(elem));
}
pub fn retain_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut T) -> bool,
{
let len = self.storage_len();
let mut idx = 0;
let mut cur = 0;
while cur < len {
let val = self
.get_mut(cur)
.expect("cur was checked to be less than deque's length");
if !f(val) {
cur += 1;
break;
}
cur += 1;
idx += 1;
}
while cur < len {
let val = self
.get_mut(cur)
.expect("cur was checked to be less than deque's length");
if !f(val) {
cur += 1;
continue;
}
self.swap(idx, cur);
cur += 1;
idx += 1;
}
if cur != idx {
self.truncate(idx);
}
}
}
pub struct Iter<'a, T> {
inner: core::iter::Chain<core::slice::Iter<'a, T>, core::slice::Iter<'a, T>>,
}
pub struct IterMut<'a, T> {
inner: core::iter::Chain<core::slice::IterMut<'a, T>, core::slice::IterMut<'a, T>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T> DoubleEndedIterator for Iter<'_, T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back()
}
}
impl<T> ExactSizeIterator for Iter<'_, T> {}
impl<T> FusedIterator for Iter<'_, T> {}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T> DoubleEndedIterator for IterMut<'_, T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back()
}
}
impl<T> ExactSizeIterator for IterMut<'_, T> {}
impl<T> FusedIterator for IterMut<'_, T> {}
impl<T, const N: usize> Default for Deque<T, N> {
fn default() -> Self {
Self::new()
}
}
impl<T, S: VecStorage<T> + ?Sized> Drop for DequeInner<T, S> {
fn drop(&mut self) {
unsafe { self.drop_contents() }
}
}
impl<T: fmt::Debug, S: VecStorage<T> + ?Sized> fmt::Debug for DequeInner<T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self).finish()
}
}
impl<T, S: VecStorage<T> + ?Sized> Extend<T> for DequeInner<T, S> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for item in iter {
self.push_back(item).ok().unwrap();
}
}
}
impl<'a, T: 'a + Copy, S: VecStorage<T> + ?Sized> Extend<&'a T> for DequeInner<T, S> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied());
}
}
#[derive(Clone)]
pub struct IntoIter<T, const N: usize> {
deque: Deque<T, N>,
}
impl<T, const N: usize> Iterator for IntoIter<T, N> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.deque.pop_front()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
fn next_back(&mut self) -> Option<Self::Item> {
self.deque.pop_back()
}
}
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
fn len(&self) -> usize {
self.deque.len()
}
}
impl<T, const N: usize> IntoIterator for Deque<T, N> {
type Item = T;
type IntoIter = IntoIter<T, N>;
fn into_iter(self) -> Self::IntoIter {
IntoIter { deque: self }
}
}
impl<'a, T, S: VecStorage<T> + ?Sized> IntoIterator for &'a DequeInner<T, S> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, S: VecStorage<T> + ?Sized> IntoIterator for &'a mut DequeInner<T, S> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T, const N: usize> Clone for Deque<T, N>
where
T: Clone,
{
fn clone(&self) -> Self {
let mut res = Self::new();
for i in self {
unsafe { res.push_back_unchecked(i.clone()) }
}
res
}
}
impl<T: PartialEq, const N: usize> PartialEq for Deque<T, N> {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
let (sa, sb) = self.as_slices();
let (oa, ob) = other.as_slices();
match sa.len().cmp(&oa.len()) {
Ordering::Equal => sa == oa && sb == ob,
Ordering::Less => {
let front = sa.len();
let mid = oa.len() - front;
let (oa_front, oa_mid) = oa.split_at(front);
let (sb_mid, sb_back) = sb.split_at(mid);
debug_assert_eq!(sa.len(), oa_front.len());
debug_assert_eq!(sb_mid.len(), oa_mid.len());
debug_assert_eq!(sb_back.len(), ob.len());
sa == oa_front && sb_mid == oa_mid && sb_back == ob
}
Ordering::Greater => {
let front = oa.len();
let mid = sa.len() - front;
let (sa_front, sa_mid) = sa.split_at(front);
let (ob_mid, ob_back) = ob.split_at(mid);
debug_assert_eq!(sa_front.len(), oa.len());
debug_assert_eq!(sa_mid.len(), ob_mid.len());
debug_assert_eq!(sb.len(), ob_back.len());
sa_front == oa && sa_mid == ob_mid && sb == ob_back
}
}
}
}
impl<T: Eq, const N: usize> Eq for Deque<T, N> {}
impl<T, const NS: usize, const ND: usize> TryFrom<[T; NS]> for Deque<T, ND> {
type Error = (CapacityError, [T; NS]);
fn try_from(value: [T; NS]) -> Result<Self, Self::Error> {
if NS > ND {
return Err((CapacityError, value));
}
let mut deq = Self::default();
let value = ManuallyDrop::new(value);
unsafe {
ptr::copy_nonoverlapping(
value.as_ptr(),
deq.buffer.buffer.as_mut_ptr().cast::<T>(),
NS,
);
}
deq.front = 0;
deq.back = NS;
deq.full = NS == ND;
Ok(deq)
}
}
#[cfg(test)]
mod tests {
use super::Deque;
use crate::CapacityError;
use static_assertions::assert_not_impl_any;
assert_not_impl_any!(Deque<*const (), 4>: Send);
#[test]
fn static_new() {
static mut _V: Deque<i32, 4> = Deque::new();
}
#[test]
fn stack_new() {
let mut _v: Deque<i32, 4> = Deque::new();
}
#[test]
fn drop() {
droppable!();
{
let mut v: Deque<Droppable, 2> = Deque::new();
v.push_back(Droppable::new()).ok().unwrap();
v.push_back(Droppable::new()).ok().unwrap();
v.pop_front().unwrap();
}
assert_eq!(Droppable::count(), 0);
{
let mut v: Deque<Droppable, 2> = Deque::new();
v.push_back(Droppable::new()).ok().unwrap();
v.push_back(Droppable::new()).ok().unwrap();
}
assert_eq!(Droppable::count(), 0);
{
let mut v: Deque<Droppable, 2> = Deque::new();
v.push_front(Droppable::new()).ok().unwrap();
v.push_front(Droppable::new()).ok().unwrap();
}
assert_eq!(Droppable::count(), 0);
}
#[test]
fn full() {
let mut v: Deque<i32, 4> = Deque::new();
v.push_back(0).unwrap();
v.push_front(1).unwrap();
v.push_back(2).unwrap();
v.push_back(3).unwrap();
assert!(v.push_front(4).is_err());
assert!(v.push_back(4).is_err());
assert!(v.is_full());
}
#[test]
fn empty() {
let mut v: Deque<i32, 4> = Deque::new();
assert!(v.is_empty());
v.push_back(0).unwrap();
assert!(!v.is_empty());
v.push_front(1).unwrap();
assert!(!v.is_empty());
v.pop_front().unwrap();
v.pop_front().unwrap();
assert!(v.pop_front().is_none());
assert!(v.pop_back().is_none());
assert!(v.is_empty());
}
#[test]
fn front_back() {
let mut v: Deque<i32, 4> = Deque::new();
assert_eq!(v.front(), None);
assert_eq!(v.front_mut(), None);
assert_eq!(v.back(), None);
assert_eq!(v.back_mut(), None);
v.push_back(4).unwrap();
assert_eq!(v.front(), Some(&4));
assert_eq!(v.front_mut(), Some(&mut 4));
assert_eq!(v.back(), Some(&4));
assert_eq!(v.back_mut(), Some(&mut 4));
v.push_front(3).unwrap();
assert_eq!(v.front(), Some(&3));
assert_eq!(v.front_mut(), Some(&mut 3));
assert_eq!(v.back(), Some(&4));
assert_eq!(v.back_mut(), Some(&mut 4));
v.pop_back().unwrap();
assert_eq!(v.front(), Some(&3));
assert_eq!(v.front_mut(), Some(&mut 3));
assert_eq!(v.back(), Some(&3));
assert_eq!(v.back_mut(), Some(&mut 3));
v.pop_front().unwrap();
assert_eq!(v.front(), None);
assert_eq!(v.front_mut(), None);
assert_eq!(v.back(), None);
assert_eq!(v.back_mut(), None);
}
#[test]
fn extend() {
let mut v: Deque<i32, 4> = Deque::new();
v.extend(&[1, 2, 3]);
assert_eq!(v.pop_front().unwrap(), 1);
assert_eq!(v.pop_front().unwrap(), 2);
assert_eq!(*v.front().unwrap(), 3);
v.push_back(4).unwrap();
v.extend(&[5, 6]);
assert_eq!(v.pop_front().unwrap(), 3);
assert_eq!(v.pop_front().unwrap(), 4);
assert_eq!(v.pop_front().unwrap(), 5);
assert_eq!(v.pop_front().unwrap(), 6);
assert!(v.pop_front().is_none());
}
#[test]
#[should_panic]
fn extend_panic() {
let mut v: Deque<i32, 4> = Deque::new();
v.extend(&[1, 2, 3, 4, 5]);
}
#[test]
fn iter() {
let mut v: Deque<i32, 4> = Deque::new();
v.push_back(0).unwrap();
v.push_back(1).unwrap();
v.push_front(2).unwrap();
v.push_front(3).unwrap();
v.pop_back().unwrap();
v.push_front(4).unwrap();
let mut items = v.iter();
assert_eq!(items.next(), Some(&4));
assert_eq!(items.next(), Some(&3));
assert_eq!(items.next(), Some(&2));
assert_eq!(items.next(), Some(&0));
assert_eq!(items.next(), None);
}
#[test]
fn iter_mut() {
let mut v: Deque<i32, 4> = Deque::new();
v.push_back(0).unwrap();
v.push_back(1).unwrap();
v.push_front(2).unwrap();
v.push_front(3).unwrap();
v.pop_back().unwrap();
v.push_front(4).unwrap();
let mut items = v.iter_mut();
assert_eq!(items.next(), Some(&mut 4));
assert_eq!(items.next(), Some(&mut 3));
assert_eq!(items.next(), Some(&mut 2));
assert_eq!(items.next(), Some(&mut 0));
assert_eq!(items.next(), None);
}
#[test]
fn iter_move() {
let mut v: Deque<i32, 4> = Deque::new();
v.push_back(0).unwrap();
v.push_back(1).unwrap();
v.push_back(2).unwrap();
v.push_back(3).unwrap();
let mut items = v.into_iter();
assert_eq!(items.next(), Some(0));
assert_eq!(items.next(), Some(1));
assert_eq!(items.next(), Some(2));
assert_eq!(items.next(), Some(3));
assert_eq!(items.next(), None);
}
#[test]
fn iter_move_back() {
let mut v: Deque<i32, 4> = Deque::new();
v.push_back(0).unwrap();
v.push_back(1).unwrap();
v.push_back(2).unwrap();
v.push_back(3).unwrap();
let mut items = v.into_iter();
assert_eq!(items.next_back(), Some(3));
assert_eq!(items.next_back(), Some(2));
assert_eq!(items.next_back(), Some(1));
assert_eq!(items.next_back(), Some(0));
assert_eq!(items.next_back(), None);
}
#[test]
fn iter_move_len() {
let mut v: Deque<i32, 3> = Deque::new();
v.push_back(0).unwrap();
v.push_back(1).unwrap();
v.push_back(2).unwrap();
let mut items = v.into_iter();
assert_eq!(items.len(), 3);
let _ = items.next();
assert_eq!(items.len(), 2);
let _ = items.next_back();
assert_eq!(items.len(), 1);
let _ = items.next();
assert_eq!(items.len(), 0);
}
#[test]
fn iter_move_drop() {
droppable!();
{
let mut deque: Deque<Droppable, 2> = Deque::new();
deque.push_back(Droppable::new()).ok().unwrap();
deque.push_back(Droppable::new()).ok().unwrap();
let mut items = deque.into_iter();
let _ = items.next();
let _ = items.next();
}
assert_eq!(Droppable::count(), 0);
{
let mut deque: Deque<Droppable, 2> = Deque::new();
deque.push_back(Droppable::new()).ok().unwrap();
deque.push_back(Droppable::new()).ok().unwrap();
let _items = deque.into_iter();
}
assert_eq!(Droppable::count(), 0);
{
let mut deque: Deque<Droppable, 2> = Deque::new();
deque.push_back(Droppable::new()).ok().unwrap();
deque.push_back(Droppable::new()).ok().unwrap();
let mut items = deque.into_iter();
let _ = items.next(); }
assert_eq!(Droppable::count(), 0);
}
#[test]
fn push_and_pop() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.len(), 0);
assert_eq!(q.pop_front(), None);
assert_eq!(q.pop_back(), None);
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
assert_eq!(q.len(), 1);
assert_eq!(q.pop_back(), Some(0));
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
q.push_back(1).unwrap();
q.push_front(2).unwrap();
q.push_front(3).unwrap();
assert_eq!(q.len(), 4);
assert_eq!(q.pop_front(), Some(3));
assert_eq!(q.len(), 3);
assert_eq!(q.pop_front(), Some(2));
assert_eq!(q.len(), 2);
assert_eq!(q.pop_back(), Some(1));
assert_eq!(q.len(), 1);
assert_eq!(q.pop_front(), Some(0));
assert_eq!(q.len(), 0);
assert_eq!(q.pop_front(), None);
assert_eq!(q.pop_back(), None);
assert_eq!(q.len(), 0);
}
#[test]
fn as_slices() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
q.push_back(1).unwrap();
q.push_back(2).unwrap();
q.push_back(3).unwrap();
assert_eq!(q.as_slices(), (&[0, 1, 2, 3][..], &[][..]));
q.pop_front().unwrap();
assert_eq!(q.as_slices(), (&[1, 2, 3][..], &[][..]));
q.push_back(4).unwrap();
assert_eq!(q.as_slices(), (&[1, 2, 3][..], &[4][..]));
}
#[test]
fn clear() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
q.push_back(1).unwrap();
q.push_back(2).unwrap();
q.push_back(3).unwrap();
assert_eq!(q.len(), 4);
q.clear();
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
assert_eq!(q.len(), 1);
}
#[test]
fn make_contiguous() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.len(), 0);
q.push_back(0).unwrap();
q.push_back(1).unwrap();
q.push_back(2).unwrap();
q.push_back(3).unwrap();
assert_eq!(q.pop_front(), Some(0));
assert_eq!(q.pop_front(), Some(1));
q.push_back(4).unwrap();
assert_eq!(q.as_slices(), ([2, 3].as_slice(), [4].as_slice()));
assert_eq!(q.make_contiguous(), &[2, 3, 4]);
assert_eq!(q.as_slices(), ([2, 3, 4].as_slice(), [].as_slice()));
assert_eq!(q.pop_front(), Some(2));
assert_eq!(q.pop_front(), Some(3));
q.push_back(5).unwrap();
q.push_back(6).unwrap();
assert_eq!(q.as_slices(), ([4].as_slice(), [5, 6].as_slice()));
assert_eq!(q.make_contiguous(), &[4, 5, 6]);
assert_eq!(q.as_slices(), ([4, 5, 6].as_slice(), [].as_slice()));
assert_eq!(q.pop_front(), Some(4));
q.push_back(7).unwrap();
q.push_back(8).unwrap();
assert_eq!(q.as_slices(), ([5, 6, 7].as_slice(), [8].as_slice()));
assert_eq!(q.make_contiguous(), &[5, 6, 7, 8]);
assert_eq!(q.as_slices(), ([5, 6, 7, 8].as_slice(), [].as_slice()));
}
#[test]
fn get() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.get(0), None);
q.push_back(0).unwrap();
assert_eq!(q.get(0), Some(&0));
assert_eq!(q.get(1), None);
q.push_back(1).unwrap();
assert_eq!(q.get(0), Some(&0));
assert_eq!(q.get(1), Some(&1));
assert_eq!(q.get(2), None);
q.pop_front().unwrap();
assert_eq!(q.get(0), Some(&1));
assert_eq!(q.get(1), None);
q.push_back(2).unwrap();
q.push_back(3).unwrap();
q.push_back(4).unwrap();
assert_eq!(q.get(0), Some(&1));
assert_eq!(q.get(1), Some(&2));
assert_eq!(q.get(2), Some(&3));
assert_eq!(q.get(3), Some(&4));
}
#[test]
fn get_mut() {
let mut q: Deque<i32, 4> = Deque::new();
assert_eq!(q.get(0), None);
q.push_back(0).unwrap();
assert_eq!(q.get_mut(0), Some(&mut 0));
assert_eq!(q.get_mut(1), None);
q.push_back(1).unwrap();
assert_eq!(q.get_mut(0), Some(&mut 0));
assert_eq!(q.get_mut(1), Some(&mut 1));
assert_eq!(q.get_mut(2), None);
*q.get_mut(0).unwrap() = 42;
*q.get_mut(1).unwrap() = 43;
assert_eq!(q.pop_front(), Some(42));
assert_eq!(q.pop_front(), Some(43));
assert_eq!(q.pop_front(), None);
}
#[test]
fn swap() {
let mut q: Deque<i32, 4> = Deque::new();
q.push_back(40).unwrap();
q.push_back(41).unwrap();
q.push_back(42).unwrap();
q.pop_front().unwrap();
q.push_back(43).unwrap();
assert_eq!(*q.get(0).unwrap(), 41);
assert_eq!(*q.get(1).unwrap(), 42);
assert_eq!(*q.get(2).unwrap(), 43);
q.swap(0, 1);
assert_eq!(*q.get(0).unwrap(), 42);
assert_eq!(*q.get(1).unwrap(), 41);
assert_eq!(*q.get(2).unwrap(), 43);
q.swap(1, 2);
assert_eq!(*q.get(0).unwrap(), 42);
assert_eq!(*q.get(1).unwrap(), 43);
assert_eq!(*q.get(2).unwrap(), 41);
q.swap(1, 1);
assert_eq!(*q.get(0).unwrap(), 42);
assert_eq!(*q.get(1).unwrap(), 43);
assert_eq!(*q.get(2).unwrap(), 41);
}
#[test]
fn swap_remove_front() {
let mut q: Deque<i32, 4> = Deque::new();
q.push_back(40).unwrap();
q.push_back(41).unwrap();
q.push_back(42).unwrap();
q.push_back(43).unwrap();
assert_eq!(q.swap_remove_front(2), Some(42));
assert_eq!(q.swap_remove_front(1), Some(40));
assert_eq!(q.swap_remove_front(0), Some(41));
assert_eq!(q.swap_remove_front(1), None);
assert_eq!(q.swap_remove_front(4), None);
assert_eq!(q.swap_remove_front(6), None);
assert_eq!(q.swap_remove_front(0), Some(43));
}
#[test]
fn swap_remove_back() {
let mut q: Deque<i32, 4> = Deque::new();
q.push_back(40).unwrap();
q.push_back(41).unwrap();
q.push_back(42).unwrap();
q.push_back(43).unwrap();
q.pop_front().unwrap();
q.push_back(44).unwrap();
assert_eq!(q.swap_remove_back(1), Some(42));
assert_eq!(q.swap_remove_front(1), Some(44));
assert_eq!(q.swap_remove_front(0), Some(41));
assert_eq!(q.swap_remove_front(1), None);
assert_eq!(q.swap_remove_front(4), None);
assert_eq!(q.swap_remove_front(6), None);
assert_eq!(q.swap_remove_front(0), Some(43));
}
#[test]
#[should_panic = "i < len"]
fn swap_i_out_of_bounds() {
let mut q: Deque<i32, 4> = Deque::new();
q.push_back(40).unwrap();
q.push_back(41).unwrap();
q.push_back(42).unwrap();
q.pop_front().unwrap();
q.swap(2, 0);
}
#[test]
#[should_panic = "j < len"]
fn swap_j_out_of_bounds() {
let mut q: Deque<i32, 4> = Deque::new();
q.push_back(40).unwrap();
q.push_back(41).unwrap();
q.push_back(42).unwrap();
q.pop_front().unwrap();
q.swap(0, 2);
}
#[test]
fn equality() {
let mut a: Deque<i32, 7> = Deque::new();
let mut b: Deque<i32, 7> = Deque::new();
assert_eq!(a, b);
a.push_back(1).unwrap();
a.push_back(2).unwrap();
a.push_back(3).unwrap();
assert_ne!(a, b);
b.push_back(1).unwrap();
b.push_back(2).unwrap();
b.push_back(3).unwrap();
assert_eq!(a, b);
a.push_back(1).unwrap();
a.push_back(2).unwrap();
a.push_back(3).unwrap();
assert_ne!(a, b);
b.push_front(3).unwrap();
b.push_front(2).unwrap();
b.push_front(1).unwrap();
assert_eq!(a, b);
a.push_back(4).unwrap();
b.push_back(4).unwrap();
assert_eq!(a, b);
a.clear();
b.clear();
a.push_back(1).unwrap();
a.push_back(2).unwrap();
a.push_back(3).unwrap();
a.push_front(3).unwrap();
a.push_front(2).unwrap();
a.push_front(1).unwrap();
b.push_back(2).unwrap();
b.push_back(3).unwrap();
b.push_back(1).unwrap();
b.push_back(2).unwrap();
b.push_back(3).unwrap();
b.push_front(1).unwrap();
assert_eq!(a, b);
}
#[test]
fn try_from_array() {
assert!(matches!(
Deque::<u8, 3>::try_from([1, 2, 3, 4]),
Err((CapacityError, [1, 2, 3, 4]))
));
let deq1 = Deque::<u8, 3>::try_from([1, 2, 3]).unwrap();
let mut deq2 = Deque::<u8, 3>::new();
deq2.push_back(1).unwrap();
deq2.push_back(2).unwrap();
deq2.push_back(3).unwrap();
assert!(deq1.is_full());
assert_eq!(deq1, deq2);
let deq1 = Deque::<u8, 8>::try_from([1, 2, 3, 4]).unwrap();
let mut deq2 = Deque::<u8, 8>::new();
deq2.push_back(1).unwrap();
deq2.push_back(2).unwrap();
deq2.push_back(3).unwrap();
deq2.push_back(4).unwrap();
assert!(!deq1.is_full());
assert_eq!(deq1, deq2);
}
#[test]
fn try_from_array_with_zst() {
#[derive(Debug, PartialEq, Copy, Clone)]
struct ZeroSizedType;
let deq1 =
Deque::<ZeroSizedType, 5>::try_from([ZeroSizedType, ZeroSizedType, ZeroSizedType])
.unwrap();
let mut deq2 = Deque::<ZeroSizedType, 5>::new();
deq2.push_back(ZeroSizedType).unwrap();
deq2.push_back(ZeroSizedType).unwrap();
deq2.push_back(ZeroSizedType).unwrap();
assert_eq!(deq1, deq2);
assert_eq!(deq1.len(), 3);
}
#[test]
fn try_from_array_drop() {
droppable!();
{
let _result = Deque::<Droppable, 2>::try_from([
Droppable::new(),
Droppable::new(),
Droppable::new(),
]);
}
assert_eq!(Droppable::count(), 0);
{
let _result = Deque::<Droppable, 3>::try_from([
Droppable::new(),
Droppable::new(),
Droppable::new(),
]);
}
assert_eq!(Droppable::count(), 0);
{
let _result = Deque::<Droppable, 4>::try_from([
Droppable::new(),
Droppable::new(),
Droppable::new(),
]);
}
assert_eq!(Droppable::count(), 0);
}
#[test]
#[cfg(feature = "zeroize")]
fn test_deque_zeroize() {
use zeroize::Zeroize;
let mut deque = Deque::<u8, 16>::new();
for i in 1..=8 {
deque.push_back(i).unwrap();
}
for i in 9..=16 {
deque.push_front(i).unwrap();
}
assert_eq!(deque.len(), 16);
assert_eq!(deque.front(), Some(&16));
assert_eq!(deque.back(), Some(&8));
deque.zeroize();
assert_eq!(deque.len(), 0);
assert!(deque.is_empty());
}
#[test]
fn truncate_empty() {
droppable!();
const LEN: usize = 1;
let mut tester: Deque<_, LEN> = Deque::new();
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
tester.truncate(123);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
assert!(tester.push_front(Droppable::new()).is_ok());
assert_eq!(tester.len(), 1);
assert_eq!(Droppable::count(), 1);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
}
#[test]
fn truncate_contiguous() {
droppable!();
fn slice_lengths<T>(slices: (&[T], &[T])) -> (usize, usize) {
let (a, b) = slices;
(a.len(), b.len())
}
const LEN: usize = 20;
let mut tester: Deque<_, LEN> = Deque::new();
for _ in 0..5 {
assert!(tester.push_front(Droppable::new()).is_ok());
}
tester.truncate(10);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(5);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
for _ in 0..5 {
assert!(tester.push_front(Droppable::new()).is_ok());
}
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(3);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (3, 0));
assert_eq!(Droppable::count(), 3);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
tester.clear();
for _ in 0..5 {
assert!(tester.push_back(Droppable::new()).is_ok());
}
tester.truncate(10);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(5);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
for _ in 0..5 {
assert!(tester.push_back(Droppable::new()).is_ok());
}
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (5, 0));
assert_eq!(Droppable::count(), 5);
tester.truncate(3);
let lens = slice_lengths(tester.as_slices());
assert_eq!(lens, (3, 0));
assert_eq!(Droppable::count(), 3);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
}
#[test]
fn truncate_non_contiguous() {
const LEN: usize = 20;
let mut tester: Deque<u8, LEN> = Deque::new();
for x in 1..=3 {
assert!(tester.push_front(x).is_ok());
}
for y in 1..=3 {
assert!(tester.push_back(y).is_ok());
}
tester.truncate(10);
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2, 3][..]));
println!("{} {}", tester.front, tester.back);
tester.truncate(6);
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2, 3][..]));
tester.truncate(0);
assert_eq!(tester.as_slices(), (&[][..], &[][..]));
tester.clear();
for x in 1..=3 {
assert!(tester.push_front(x).is_ok());
}
for y in 1..=3 {
assert!(tester.push_back(y).is_ok());
}
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2, 3][..]));
tester.truncate(5);
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2][..]));
assert!(tester.push_back(3).is_ok());
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2, 3][..]));
tester.truncate(3);
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[][..]));
for y in 1..=3 {
assert!(tester.push_back(y).is_ok());
}
assert_eq!(tester.as_slices(), (&[3, 2, 1][..], &[1, 2, 3][..]));
tester.truncate(2);
assert_eq!(tester.as_slices(), (&[3, 2][..], &[][..]));
tester.truncate(0);
assert_eq!(tester.as_slices(), (&[][..], &[][..]));
tester.truncate(123);
assert_eq!(tester.as_slices(), (&[][..], &[][..]));
}
#[test]
fn truncate_drop_count() {
droppable!();
const LEN: usize = 20;
const TRUNC: usize = 3;
for push_front_amt in 0..=LEN {
let mut tester: Deque<_, LEN> = Deque::new();
for index in 0..LEN {
if index < push_front_amt {
assert!(
tester.push_front(Droppable::new()).is_ok(),
"deque must have room for all {LEN} entries"
);
} else {
assert!(
tester.push_back(Droppable::new()).is_ok(),
"deque must have room for all {LEN} entries"
);
}
}
assert_eq!(Droppable::count(), LEN as i32);
tester.truncate(TRUNC);
assert_eq!(tester.len(), TRUNC);
assert_eq!(Droppable::count(), TRUNC as i32);
tester.truncate(0);
assert_eq!(tester.len(), 0);
assert_eq!(Droppable::count(), 0);
}
}
#[test]
fn retain() {
droppable!();
const LEN: usize = 20;
for push_front_amt in 0..=LEN {
let mut tester: Deque<_, LEN> = Deque::new();
for index in 0..LEN {
if index < push_front_amt {
assert!(tester.push_front((index, Droppable::new())).is_ok());
} else {
assert!(tester.push_back((index, Droppable::new())).is_ok());
}
}
assert_eq!(Droppable::count(), LEN as i32);
tester.retain(|(x, _)| *x >= 10);
assert_eq!(tester.len(), 10);
assert_eq!(Droppable::count(), 10);
}
}
}