#![warn(missing_docs)]
use crate::collection::{Collection, ExpansionMode, FixedSizeCollection, Iterators};
use std::cmp::Ordering;
use std::marker::PhantomData;
use std::ptr::NonNull;
use trait_based_collection_macros::{internal_check_expansion_add, iterator, All};
pub trait DequeCollection<'a, T>: Collection<'a, T>
where
T: 'a,
{
fn push_front(&mut self, value: T);
fn push_back(&mut self, value: T) {
self.add(value);
}
fn pop_front(&mut self) -> Option<T> {
self.remove()
}
fn pop_back(&mut self) -> Option<T>;
fn peek_front(&'a self) -> Option<Self::ItemRef> {
self.peek()
}
fn peek_front_mut(&'a mut self) -> Option<Self::ItemMut> {
self.peek_mut()
}
fn peek_back(&'a self) -> Option<Self::ItemRef> {
self.get(self.len() - 1)
}
fn peek_back_mut(&'a mut self) -> Option<Self::ItemMut> {
self.get_mut(self.len() - 1)
}
}
#[derive(Debug)]
struct NodeQueue<T> {
value: T,
prev: Option<NonNull<NodeQueue<T>>>,
}
impl<T> NodeQueue<T> {
const fn new(value: T) -> Self {
Self { value, prev: None }
}
}
#[derive(Debug, All)]
pub struct Queue<T> {
head: Option<NonNull<NodeQueue<T>>>,
tail: Option<NonNull<NodeQueue<T>>>,
len: usize,
}
pub struct QueueIter<'a, T> {
current: Option<NonNull<NodeQueue<T>>>,
len: usize,
_marker: PhantomData<&'a T>,
}
impl<'a, T> QueueIter<'a, T> {
const fn new(stack: &'a Queue<T>) -> Self {
QueueIter {
current: stack.head,
len: stack.len,
_marker: PhantomData,
}
}
}
iterator!(Queue, QueueIter, ref, {
let current = self.current.take()?;
unsafe {
let current = current.as_ref();
self.current = current.prev;
self.len -= 1;
Some(¤t.value)
}
});
pub struct QueueIterMut<'a, T> {
current: Option<NonNull<NodeQueue<T>>>,
len: usize,
_marker: PhantomData<&'a mut T>,
}
impl<'a, T> QueueIterMut<'a, T> {
fn new(stack: &'a mut Queue<T>) -> Self {
QueueIterMut {
current: stack.head,
len: stack.len,
_marker: PhantomData,
}
}
}
iterator!(Queue, QueueIterMut, mut, {
let mut current = self.current.take()?;
unsafe {
let current = current.as_mut();
self.current = current.prev;
self.len -= 1;
Some(&mut current.value)
}
});
impl<'a, T> Iterators<'a, T> for Queue<T>
where
T: 'a,
{
type ItemRef = &'a T;
type ItemMut = &'a mut T;
type Iter = QueueIter<'a, T>;
type IterMut = QueueIterMut<'a, T>;
fn iter(&'a self) -> Self::Iter {
QueueIter::new(self)
}
fn iter_mut(&'a mut self) -> Self::IterMut {
QueueIterMut::new(self)
}
}
impl<T> Queue<T> {
fn get_node(&self, index: usize) -> Option<NonNull<NodeQueue<T>>> {
if index >= self.len() {
return None;
}
#[allow(clippy::unwrap_used)]
(0..index).fold(self.head, |node, _| unsafe { node.unwrap().as_ref().prev })
}
}
impl<'a, T> Collection<'a, T> for Queue<T>
where
T: 'a,
{
fn new_default() -> Self {
Self {
head: None,
tail: None,
len: 0,
}
}
fn add(&mut self, value: T) {
let node = Box::new(NodeQueue::new(value));
let node_ptr = NonNull::new(Box::into_raw(node)).expect("Failed to allocate memory");
if let Some(mut tail) = self.tail {
unsafe {
tail.as_mut().prev = Some(node_ptr);
}
} else {
self.head = Some(node_ptr);
}
self.len += 1;
self.tail = Some(node_ptr);
}
fn remove(&mut self) -> Option<T> {
let mut node = self.head.take()?;
self.len -= 1;
if self.is_empty() {
self.tail = None;
}
unsafe {
if let Some(prev) = node.as_mut().prev.take() {
self.head = Some(prev);
}
Some(Box::from_raw(node.as_ptr()).value)
}
}
fn peek(&self) -> Option<Self::ItemRef> {
self.head.map(|head| unsafe { &head.as_ref().value })
}
fn peek_mut(&'a mut self) -> Option<Self::ItemMut> {
self.head
.map(|mut head| unsafe { &mut head.as_mut().value })
}
fn get(&'a self, index: usize) -> Option<Self::ItemRef> {
self.get_node(index)
.map(|node| unsafe { &node.as_ref().value })
}
fn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut> {
self.get_node(index)
.map(|mut node| unsafe { &mut node.as_mut().value })
}
fn len(&self) -> usize {
self.len
}
}
#[derive(Debug)]
struct NodeDeque<T> {
value: T,
prev: Option<NonNull<NodeDeque<T>>>,
next: Option<NonNull<NodeDeque<T>>>,
}
impl<T> NodeDeque<T> {
const fn new(value: T) -> Self {
Self {
value,
prev: None,
next: None,
}
}
}
#[derive(Debug, All)]
pub struct Deque<T> {
head: Option<NonNull<NodeDeque<T>>>,
tail: Option<NonNull<NodeDeque<T>>>,
len: usize,
}
impl<T> DoubleEndedIterator for DequeIntoIter<T> {
fn next_back(&mut self) -> Option<T> {
self.0.pop_back()
}
}
pub struct DequeIter<'a, T> {
current_normal: Option<NonNull<NodeDeque<T>>>,
current_reversed: Option<NonNull<NodeDeque<T>>>,
len: usize,
_marker: PhantomData<&'a T>,
}
impl<'a, T> DequeIter<'a, T> {
const fn new(stack: &'a Deque<T>) -> Self {
DequeIter {
current_normal: stack.head,
current_reversed: stack.tail,
len: stack.len,
_marker: PhantomData,
}
}
}
iterator!(Deque, DequeIter, ref, {
if self.len == 0 {
return None;
}
let current = self.current_normal.take()?;
unsafe {
let current = current.as_ref();
self.current_normal = current.prev;
self.len -= 1;
Some(¤t.value)
}
});
impl<'a, T> DoubleEndedIterator for DequeIter<'a, T> {
fn next_back(&mut self) -> Option<&'a T> {
if self.len == 0 {
return None;
}
let current = self.current_reversed.take()?;
unsafe {
let current = current.as_ref();
self.current_reversed = current.next;
self.len -= 1;
Some(¤t.value)
}
}
}
pub struct DequeIterMut<'a, T> {
current_normal: Option<NonNull<NodeDeque<T>>>,
current_reversed: Option<NonNull<NodeDeque<T>>>,
len: usize,
_marker: PhantomData<&'a mut T>,
}
impl<'a, T> DequeIterMut<'a, T> {
fn new(stack: &'a mut Deque<T>) -> Self {
DequeIterMut {
current_normal: stack.head,
current_reversed: stack.tail,
len: stack.len,
_marker: PhantomData,
}
}
}
iterator!(Deque, DequeIterMut, mut, {
if self.len == 0 {
return None;
}
let mut current = self.current_normal.take()?;
unsafe {
let current = current.as_mut();
self.current_normal = current.prev;
self.len -= 1;
Some(&mut current.value)
}
});
impl<'a, T> DoubleEndedIterator for DequeIterMut<'a, T> {
fn next_back(&mut self) -> Option<&'a mut T> {
if self.len == 0 {
return None;
}
let mut current = self.current_reversed.take()?;
unsafe {
let current = current.as_mut();
self.current_reversed = current.next;
self.len -= 1;
Some(&mut current.value)
}
}
}
impl<'a, T> Iterators<'a, T> for Deque<T>
where
T: 'a,
{
type ItemRef = &'a T;
type ItemMut = &'a mut T;
type Iter = DequeIter<'a, T>;
type IterMut = DequeIterMut<'a, T>;
fn iter(&'a self) -> Self::Iter {
DequeIter::new(self)
}
fn iter_mut(&'a mut self) -> Self::IterMut {
DequeIterMut::new(self)
}
}
impl<T> Deque<T> {
fn get_node(&self, index: usize) -> Option<NonNull<NodeDeque<T>>> {
if index >= self.len() {
return None;
}
#[allow(clippy::unwrap_used)] if index <= self.len / 2 {
(0..index).fold(self.head, |node, _| unsafe { node.unwrap().as_ref().prev })
} else {
(index + 1..self.len())
.fold(self.tail, |node, _| unsafe { node.unwrap().as_ref().next })
}
}
}
impl<'a, T> Collection<'a, T> for Deque<T>
where
T: 'a,
{
fn new_default() -> Self {
Self {
head: None,
tail: None,
len: 0,
}
}
fn add(&mut self, value: T) {
let node = Box::new(NodeDeque::new(value));
let mut node_ptr = NonNull::new(Box::into_raw(node)).expect("Failed to allocate memory");
if let Some(mut tail_ptr) = self.tail {
unsafe {
node_ptr.as_mut().next = Some(tail_ptr);
tail_ptr.as_mut().prev = Some(node_ptr);
}
} else {
self.head = Some(node_ptr);
}
self.len += 1;
self.tail = Some(node_ptr);
}
fn remove(&mut self) -> Option<T> {
let mut node = self.head.take()?;
self.len -= 1;
if self.is_empty() {
self.tail = None;
}
unsafe {
if let Some(mut prev) = node.as_mut().prev.take() {
prev.as_mut().next = None;
self.head = Some(prev);
}
Some(Box::from_raw(node.as_ptr()).value)
}
}
fn peek(&self) -> Option<Self::ItemRef> {
self.head.map(|head| unsafe { &head.as_ref().value })
}
fn peek_mut(&'a mut self) -> Option<Self::ItemMut> {
self.head
.map(|mut head| unsafe { &mut head.as_mut().value })
}
fn get(&'a self, index: usize) -> Option<Self::ItemRef> {
self.get_node(index)
.map(|node| unsafe { &node.as_ref().value })
}
fn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut> {
self.get_node(index)
.map(|mut node| unsafe { &mut node.as_mut().value })
}
fn len(&self) -> usize {
self.len
}
}
impl<'a, T> DequeCollection<'a, T> for Deque<T>
where
T: 'a,
{
fn push_front(&mut self, value: T) {
let node = Box::new(NodeDeque::new(value));
let mut node_ptr = NonNull::new(Box::into_raw(node)).expect("Failed to allocate memory");
if let Some(mut head_ptr) = self.head {
unsafe {
node_ptr.as_mut().prev = Some(head_ptr);
head_ptr.as_mut().next = Some(node_ptr);
}
} else {
self.tail = Some(node_ptr);
}
self.len += 1;
self.head = Some(node_ptr);
}
fn pop_back(&mut self) -> Option<T> {
let mut node = self.tail.take()?;
self.len -= 1;
if self.is_empty() {
self.head = None;
}
unsafe {
if let Some(mut next) = node.as_mut().next.take() {
next.as_mut().prev = None;
self.tail = Some(next);
}
Some(Box::from_raw(node.as_ptr()).value)
}
}
fn peek_back(&self) -> Option<Self::ItemRef> {
self.tail.map(|tail| unsafe { &(*tail.as_ref()).value })
}
fn peek_back_mut(&'a mut self) -> Option<Self::ItemMut> {
self.tail
.map(|mut tail| unsafe { &mut (*tail.as_mut()).value })
}
}
#[derive(Debug, All)]
pub struct CircularDeque<T> {
data: Vec<Option<T>>,
head: usize,
tail: usize,
len: usize,
pub mode: ExpansionMode,
}
impl<T> DoubleEndedIterator for CircularDequeIntoIter<T> {
fn next_back(&mut self) -> Option<T> {
self.0.pop_back()
}
}
pub struct CircularDequeIter<'a, T> {
deque: &'a CircularDeque<T>,
current_normal: usize,
current_reversed: usize,
len: usize,
}
impl<'a, T> CircularDequeIter<'a, T> {
const fn new(deque: &'a CircularDeque<T>) -> Self {
CircularDequeIter {
deque,
current_normal: deque.head,
current_reversed: deque.tail,
len: deque.len,
}
}
}
iterator!(CircularDeque, CircularDequeIter, ref, {
if self.len == 0 {
return None;
}
let current = self.current_normal;
self.current_normal = self.deque.sub_index(current, 1);
self.len -= 1;
self.deque.data[current].as_ref()
});
impl<'a, T> DoubleEndedIterator for CircularDequeIter<'a, T> {
fn next_back(&mut self) -> Option<&'a T> {
if self.len == 0 {
return None;
}
let current = self.current_reversed;
self.current_reversed = self.deque.add_index(current, 1);
self.len -= 1;
self.deque.data[current].as_ref()
}
}
pub struct CircularDequeIterMut<'a, T> {
deque: &'a mut CircularDeque<T>,
current_normal: usize,
current_reversed: usize,
len: usize,
}
impl<'a, T> CircularDequeIterMut<'a, T> {
fn new(deque: &'a mut CircularDeque<T>) -> Self {
CircularDequeIterMut {
current_normal: deque.head,
current_reversed: deque.tail,
len: deque.len,
deque,
}
}
}
iterator!(CircularDeque, CircularDequeIterMut, mut, {
if self.len == 0 {
return None;
}
let current = self.current_normal;
self.current_normal = self.deque.sub_index(current, 1);
let current_ptr = self.deque.data[current].as_mut()?;
self.len -= 1;
unsafe { Some(&mut *(current_ptr as *mut T)) }
});
impl<'a, T> DoubleEndedIterator for CircularDequeIterMut<'a, T> {
fn next_back(&mut self) -> Option<&'a mut T> {
if self.len == 0 {
return None;
}
let current = self.current_reversed;
self.current_reversed = (current + 1) % self.deque.capacity();
let current_ptr = self.deque.data[current].as_mut()?;
self.len -= 1;
unsafe { Some(&mut *(current_ptr as *mut T)) }
}
}
impl<'a, T> Iterators<'a, T> for CircularDeque<T>
where
T: 'a,
{
type ItemRef = &'a T;
type ItemMut = &'a mut T;
type Iter = CircularDequeIter<'a, T>;
type IterMut = CircularDequeIterMut<'a, T>;
fn iter(&'a self) -> Self::Iter {
CircularDequeIter::new(self)
}
fn iter_mut(&'a mut self) -> Self::IterMut {
CircularDequeIterMut::new(self)
}
}
impl<T> CircularDeque<T> {
fn add_index(&self, index: usize, add: usize) -> usize {
if self.capacity() == 0 {
return usize::MAX;
}
index.wrapping_add(add) % self.capacity()
}
fn sub_index(&self, index: usize, sub: usize) -> usize {
if self.capacity() == 0 {
return usize::MAX;
}
match index.cmp(&sub) {
Ordering::Greater => (index - sub) % self.capacity(),
Ordering::Equal => 0,
Ordering::Less => self.capacity() - (sub - index) % self.capacity(),
}
}
}
impl<'a, T> Collection<'a, T> for CircularDeque<T>
where
T: 'a,
{
fn new_default() -> Self {
Self::with_mode(16, ExpansionMode::default())
}
fn with_capacity(capacity: usize) -> Self {
Self::with_mode(capacity, ExpansionMode::Panic)
}
fn with_approximate_capacity(approx_capacity: usize) -> Self {
Self::with_mode(approx_capacity, ExpansionMode::default())
}
#[internal_check_expansion_add]
fn add(&mut self, value: T) {
if !self.is_empty() {
self.tail = self.sub_index(self.tail, 1);
}
self.data[self.tail] = Some(value);
self.len += 1;
}
fn remove(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
let value = self.data[self.head].take();
if self.len > 1 {
self.head = self.sub_index(self.head, 1);
}
self.len -= 1;
value
}
fn clear(&mut self) {
self.data.clear();
self.head = 0;
self.tail = 0;
self.len = 0;
}
fn peek(&'a self) -> Option<Self::ItemRef> {
self.data.get(self.head).map(Option::as_ref)?
}
fn peek_mut(&'a mut self) -> Option<Self::ItemMut> {
self.data.get_mut(self.head).and_then(Option::as_mut)
}
fn get(&'a self, index: usize) -> Option<Self::ItemRef> {
self.data
.get(self.sub_index(self.head, index))
.and_then(Option::as_ref)
}
fn get_mut(&'a mut self, index: usize) -> Option<Self::ItemMut> {
let index = self.sub_index(self.head, index);
self.data.get_mut(index).map(Option::as_mut)?
}
fn len(&self) -> usize {
self.len
}
}
impl<'a, T> FixedSizeCollection<'a, T> for CircularDeque<T>
where
T: 'a,
{
fn with_mode(capacity: usize, mode: ExpansionMode) -> Self {
assert_ne!(capacity, 0, "Capacity must be greater than 0");
Self {
data: (0..capacity).map(|_| None).collect(),
head: 0,
tail: 0,
len: 0,
mode,
}
}
fn capacity(&self) -> usize {
self.data.len()
}
fn expand(&mut self, extra_size: usize) {
let prev_capacity = self.capacity();
self.data.resize_with(prev_capacity + extra_size, || None);
if self.tail > self.head {
for i in self.tail..prev_capacity {
self.data[extra_size + i] = self.data[i].take();
}
self.tail += extra_size;
}
}
fn mode(&self) -> &ExpansionMode {
&self.mode
}
}
impl<'a, T> DequeCollection<'a, T> for CircularDeque<T>
where
T: 'a,
{
#[internal_check_expansion_add]
fn push_front(&mut self, value: T) {
if !self.is_empty() {
self.head = self.add_index(self.head, 1);
}
self.data[self.head] = Some(value);
self.len += 1;
}
fn pop_back(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
let value = self.data[self.tail].take();
if self.len > 1 {
self.tail = self.add_index(self.tail, 1);
}
self.len -= 1;
value
}
fn peek_back(&'a self) -> Option<Self::ItemRef> {
self.data.get(self.tail).map(Option::as_ref)?
}
fn peek_back_mut(&'a mut self) -> Option<Self::ItemMut> {
self.data.get_mut(self.tail).and_then(Option::as_mut)
}
}
#[cfg(test)]
mod tests_collection {
#![allow(clippy::cast_possible_truncation)]
use super::*;
use trait_based_collection_macros::test_collection;
#[test_collection(Queue, Deque, CircularDeque)]
fn test_add<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
queue.add(u32::MAX);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_remove<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for i in 0..5 {
assert_eq!(queue.remove(), Some(i));
}
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_clear<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
queue.clear();
assert_eq!(queue.len(), 0);
assert!(queue.is_empty());
assert_eq!(queue.peek(), None);
assert_eq!(queue.remove(), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_peek<C: Collection<u32>>(mut queue: C) {
assert_eq!(queue.peek(), None);
for i in 0..5 {
queue.add(i);
assert_eq!(queue.peek(), Some(&0));
}
for i in 0..5 {
assert_eq!(queue.peek(), Some(&i));
queue.remove();
}
assert_eq!(queue.peek(), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_peek_mut<C: Collection<u32>>(mut queue: C) {
assert_eq!(queue.peek_mut(), None);
for i in 0..5 {
queue.add(i);
let peek = queue.peek_mut().unwrap();
assert_eq!(*peek, i);
*peek += 1;
}
assert_eq!(queue.peek_mut(), Some(&mut 5));
queue.remove();
for mut i in 1..5 {
assert_eq!(queue.peek_mut(), Some(&mut i));
queue.remove();
}
assert_eq!(queue.peek_mut(), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_get<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for i in 0..5 {
assert_eq!(queue.get(i as usize), Some(&i));
}
assert_eq!(queue.get(6), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_get_mut<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for i in 0..5 {
let get = queue.get_mut(i as usize).unwrap();
*get += 1;
assert_eq!(*get, i + 1);
}
assert_eq!(queue.get_mut(6), None);
for i in 1..6 {
assert_eq!(queue.remove(), Some(i));
}
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_find<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for i in 0..5 {
assert_eq!(queue.find(&i), Some(i as usize));
}
assert_eq!(queue.find(&6), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_contains<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for i in 0..5 {
assert!(queue.contains(&i));
}
assert!(!queue.contains(&6));
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_len<C: Collection<u32>>(mut queue: C) {
assert_eq!(queue.len(), 0);
for i in 0..5 {
queue.add(i);
assert_eq!(queue.len(), (i + 1) as usize);
}
assert_eq!(queue.len(), 5);
for i in (0..5_usize).rev() {
queue.remove();
assert_eq!(queue.len(), i);
}
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_is_empty<C: Collection<u32>>(mut queue: C) {
assert!(queue.is_empty());
for i in 0..5 {
queue.add(i);
assert!(!queue.is_empty());
}
for i in 0..5 {
queue.remove();
assert_eq!(queue.is_empty(), i == 4);
}
}
#[test_collection(Queue, Deque, CircularDeque)]
fn basic_test_queue<C: Collection<u32>>(mut queue: C) {
for i in 0..10 {
queue.add(i);
}
for mut i in 0..10_u32 {
assert_eq!(queue.len(), 10 - i as usize);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&i));
assert_eq!(queue.peek_mut(), Some(&mut i));
match queue.get(1) {
Some(x) => assert_eq!(*x, i + 1),
None => assert_eq!(i, 9),
}
match queue.get_mut(1) {
Some(x) => assert_eq!(*x, i + 1),
None => assert_eq!(i, 9),
}
assert_eq!(queue.find(&i), Some(0));
assert!(queue.contains(&i));
assert_eq!(queue.remove(), Some(i));
}
assert_eq!(queue.len(), 0);
assert!(queue.is_empty());
assert_eq!(queue.peek(), None);
assert_eq!(queue.peek_mut(), None);
assert_eq!(queue.get(2), None);
assert_eq!(queue.get_mut(2), None);
assert_eq!(queue.find(&0), None);
assert!(!queue.contains(&0));
assert_eq!(queue.remove(), None);
for i in 0..10 {
queue.add(i);
}
queue.clear();
assert_eq!(queue.len(), 0);
assert!(queue.is_empty());
assert_eq!(queue.peek(), None);
assert_eq!(queue.peek_mut(), None);
assert_eq!(queue.get(2), None);
assert_eq!(queue.get_mut(2), None);
assert_eq!(queue.find(&0), None);
assert!(!queue.contains(&0));
assert_eq!(queue.remove(), None);
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_from_iter<C: Collection<usize>>(mut _queue: C) {
let mut queue: C<usize> = vec![1, 2, 3, 4, 5].into_iter().collect();
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for i in 1..6 {
assert_eq!(queue.remove(), Some(i));
}
}
#[test_collection(Queue, Deque, CircularDeque)]
fn test_into_iter<C: Collection<u32>>(mut queue: C) {
for i in 0..5 {
queue.add(i);
}
for (i, &elem) in queue.iter().enumerate() {
assert_eq!(elem, i as u32);
}
let mut i: u32 = 0;
for elem in &queue {
assert_eq!(*elem, i);
i += 1;
}
for (i, elem) in queue.iter_mut().enumerate() {
*elem += 1;
assert_eq!(*elem, i as u32 + 1);
}
let mut i: u32 = 0;
for elem in &mut queue {
*elem -= 1;
assert_eq!(*elem, i);
i += 1;
}
for (i, elem) in queue.into_iter().enumerate() {
assert_eq!(elem, i as u32);
}
}
#[test]
fn test_macro_queue() {
let mut queue = queue![];
queue.add(1);
assert_eq!(queue.remove(), Some(1));
let mut queue = queue![1, 2, 3, 4, 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for i in 1..6 {
assert_eq!(queue.remove(), Some(i));
}
let mut queue = queue![1; 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for _ in 0..5 {
assert_eq!(queue.remove(), Some(1));
}
}
#[test]
fn test_macro_deque() {
let mut queue = deque![];
queue.add(1);
assert_eq!(queue.remove(), Some(1));
let mut queue = deque![1, 2, 3, 4, 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for i in 1..6 {
assert_eq!(queue.remove(), Some(i));
}
let mut queue = deque![1; 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for _ in 0..5 {
assert_eq!(queue.remove(), Some(1));
}
}
#[test]
fn test_cycles_circular_queue() {
let mut queue = CircularDeque::with_mode(5, ExpansionMode::Panic);
for _ in 0..10 {
for i in 0..3 {
queue.add(i);
}
for i in 0..3 {
assert_eq!(queue.remove(), Some(i));
}
}
}
#[test]
fn test_capacity_circular_queue() {
let mut queue = CircularDeque::with_mode(5, ExpansionMode::Panic);
assert_eq!(queue.capacity(), 5);
for _ in 0..7 {
for i in 0..3 {
queue.add(i);
assert_eq!(queue.capacity(), 5);
}
for i in 0..3 {
assert_eq!(queue.remove(), Some(i));
assert_eq!(queue.capacity(), 5);
}
}
}
#[test]
fn test_macro_circular_queue() {
let mut queue = circular_deque![];
for i in 0..10 {
queue.add(i);
}
assert_eq!(queue.remove(), Some(0));
let mut queue = circular_deque![1, 2, 3, 4, 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for i in 1..6 {
assert_eq!(queue.remove(), Some(i));
}
let mut queue = circular_deque![1; 5];
assert_eq!(queue.len(), 5);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
for _ in 0..5 {
assert_eq!(queue.remove(), Some(1));
}
}
#[test]
fn test_deque_to_circular_queue() {
let queue = deque![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
.into_iter()
.collect::<CircularDeque<u32>>();
assert_eq!(queue.len(), 10);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&0));
}
}
#[cfg(test)]
mod tests_deque_collection {
use super::*;
use trait_based_collection_macros::test_collection;
#[test_collection(Deque, CircularDeque)]
fn test_push_back<C: Collection<u32>>(mut queue: C) {
queue.add(1); queue.add(2); queue.push_back(3);
assert_eq!(queue.len(), 3);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&1));
assert_eq!(queue.remove(), Some(1));
assert_eq!(queue.remove(), Some(2));
assert_eq!(queue.remove(), Some(3));
}
#[test_collection(Deque, CircularDeque)]
fn test_push_front_deque<C: Collection<u32>>(mut queue: C) {
queue.add(1); queue.add(2); queue.push_front(3);
assert_eq!(queue.len(), 3);
assert!(!queue.is_empty());
assert_eq!(queue.peek(), Some(&3));
assert_eq!(queue.remove(), Some(3));
assert_eq!(queue.remove(), Some(1));
assert_eq!(queue.remove(), Some(2));
}
#[test_collection(Deque, CircularDeque)]
fn test_pop_back_deque<C: Collection<u32>>(mut queue: C) {
queue.add(1);
queue.add(2);
queue.add(3);
assert_eq!(queue.pop_back(), Some(3));
assert_eq!(queue.pop_back(), Some(2));
assert_eq!(queue.pop_back(), Some(1));
}
#[test_collection(Deque, CircularDeque)]
fn test_pop_front_deque<C: Collection<u32>>(mut queue: C) {
queue.add(1);
queue.add(2);
queue.add(3);
assert_eq!(queue.pop_front(), Some(1));
assert_eq!(queue.pop_front(), Some(2));
assert_eq!(queue.pop_front(), Some(3));
}
#[test_collection(Deque, CircularDeque)]
fn test_peek_front_deque<C: Collection<u32>>(mut queue: C) {
queue.add(1);
queue.add(2);
queue.add(3);
for i in 1..4 {
assert_eq!(queue.peek_front(), Some(&i));
queue.remove();
}
}
#[test_collection(Deque, CircularDeque)]
fn test_peek_back_deque<C: Collection<u32>>(mut queue: C) {
queue.add(1);
queue.add(2);
queue.add(3);
for _ in 1..4 {
assert_eq!(queue.peek_back(), Some(&3));
queue.remove();
}
}
}