use core::iter::FromIterator;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde::Serialize;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[cfg(feature = "alloc")]
pub struct Deque<A> {
front: Vec<A>,
back: Vec<A>,
len: usize,
}
#[cfg(all(feature = "serde", feature = "alloc"))]
impl<'de, A: serde::Deserialize<'de>> serde::Deserialize<'de> for Deque<A> {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
#[derive(serde::Deserialize)]
#[serde(rename = "Deque")]
struct Wire<A> {
front: Vec<A>,
back: Vec<A>,
#[serde(default)]
#[allow(dead_code)]
len: usize,
}
let w = Wire::deserialize(d)?;
Ok(Deque {
len: w.front.len() + w.back.len(),
front: w.front,
back: w.back,
})
}
}
#[cfg(feature = "alloc")]
impl<A> Default for Deque<A> {
fn default() -> Self {
Deque::new()
}
}
#[cfg(feature = "alloc")]
impl<A: PartialEq> PartialEq for Deque<A> {
fn eq(&self, other: &Self) -> bool {
if self.len != other.len {
return false;
}
let self_iter = self.front.iter().rev().chain(self.back.iter());
let other_iter = other.front.iter().rev().chain(other.back.iter());
self_iter.eq(other_iter)
}
}
#[cfg(feature = "alloc")]
impl<A: Eq> Eq for Deque<A> {}
#[cfg(feature = "alloc")]
impl<A> Deque<A> {
#[inline]
pub fn new() -> Self {
Deque {
front: Vec::new(),
back: Vec::new(),
len: 0,
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn push_front(mut self, value: A) -> Self {
self.front.push(value);
Deque {
front: self.front,
back: self.back,
len: self.len + 1,
}
}
#[inline]
pub fn push_back(mut self, value: A) -> Self {
self.back.push(value);
Deque {
front: self.front,
back: self.back,
len: self.len + 1,
}
}
#[inline]
pub fn pop_front(mut self) -> Option<(A, Self)>
where
A: Clone,
{
if self.is_empty() {
return None;
}
if self.front.is_empty() {
self.rebalance_front();
}
let value = self.front.pop().unwrap();
Some((
value,
Deque {
front: self.front,
back: self.back,
len: self.len - 1,
},
))
}
#[inline]
pub fn pop_back(mut self) -> Option<(A, Self)>
where
A: Clone,
{
if self.is_empty() {
return None;
}
if self.back.is_empty() {
self.rebalance_back();
}
let value = self.back.pop().unwrap();
Some((
value,
Deque {
front: self.front,
back: self.back,
len: self.len - 1,
},
))
}
#[inline]
pub fn peek_front(&self) -> Option<&A> {
if self.is_empty() {
None
} else if !self.front.is_empty() {
self.front.last()
} else {
self.back.first()
}
}
#[inline]
pub fn peek_back(&self) -> Option<&A> {
if self.is_empty() {
None
} else if !self.back.is_empty() {
self.back.last()
} else {
self.front.first()
}
}
fn rebalance_front(&mut self)
where
A: Clone,
{
if self.back.is_empty() {
return;
}
let mid = self.back.len() / 2;
let mut new_front: Vec<A> = self.back.drain(..=mid).collect();
new_front.reverse();
self.front = new_front;
}
fn rebalance_back(&mut self)
where
A: Clone,
{
if self.front.is_empty() {
return;
}
let mid = self.front.len() / 2;
let mut new_back: Vec<A> = self.front.drain(..=mid).collect();
new_back.reverse();
self.back = new_back;
}
#[inline]
pub fn map<B, F>(&self, f: F) -> Deque<B>
where
A: Clone,
F: Fn(&A) -> B,
{
Deque {
front: self.front.iter().map(&f).collect(),
back: self.back.iter().map(&f).collect(),
len: self.len,
}
}
#[inline]
pub fn fold<B, F>(&self, init: B, f: F) -> B
where
A: Clone,
F: Fn(B, &A) -> B,
{
let acc = self.front.iter().rev().fold(init, &f);
self.back.iter().fold(acc, f)
}
#[inline]
pub fn filter<F>(&self, pred: F) -> Self
where
A: Clone,
F: Fn(&A) -> bool,
{
let front: Vec<A> = self.front.iter().filter(|x| pred(x)).cloned().collect();
let back: Vec<A> = self.back.iter().filter(|x| pred(x)).cloned().collect();
let len = front.len() + back.len();
Deque { front, back, len }
}
#[inline]
pub fn to_vec(&self) -> Vec<A>
where
A: Clone,
{
let mut result: Vec<A> = self.front.iter().rev().cloned().collect();
result.extend(self.back.iter().cloned());
result
}
#[inline]
pub fn reverse(self) -> Self {
Deque {
front: self.back,
back: self.front,
len: self.len,
}
}
#[inline]
pub fn concat(&self, other: &Self) -> Self
where
A: Clone,
{
let mut result = self.clone();
for item in other.front.iter().rev() {
result = result.push_back(item.clone());
}
for item in &other.back {
result = result.push_back(item.clone());
}
result
}
}
#[cfg(feature = "alloc")]
impl<A: Clone> From<Vec<A>> for Deque<A> {
fn from(vec: Vec<A>) -> Self {
let len = vec.len();
Deque {
front: Vec::new(),
back: vec,
len,
}
}
}
#[cfg(feature = "alloc")]
impl<A: Clone> FromIterator<A> for Deque<A> {
fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
let back: Vec<A> = iter.into_iter().collect();
let len = back.len();
Deque {
front: Vec::new(),
back,
len,
}
}
}
#[cfg(feature = "alloc")]
pub struct DequeIter<A> {
front: Vec<A>,
back: Vec<A>,
}
#[cfg(feature = "alloc")]
impl<A> Iterator for DequeIter<A> {
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
if !self.front.is_empty() {
Some(self.front.pop().unwrap())
} else if !self.back.is_empty() {
self.back.reverse();
core::mem::swap(&mut self.front, &mut self.back);
self.front.pop()
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.front.len() + self.back.len();
(len, Some(len))
}
}
#[cfg(feature = "alloc")]
impl<A: Clone> IntoIterator for Deque<A> {
type Item = A;
type IntoIter = DequeIter<A>;
fn into_iter(self) -> Self::IntoIter {
DequeIter {
front: self.front,
back: self.back,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn test_new_is_empty() {
let d: Deque<i32> = Deque::new();
assert!(d.is_empty());
assert_eq!(d.len(), 0);
}
#[test]
fn test_push_front() {
let d = Deque::new().push_front(1).push_front(2).push_front(3);
assert_eq!(d.len(), 3);
assert_eq!(d.peek_front(), Some(&3));
assert_eq!(d.peek_back(), Some(&1));
}
#[test]
fn test_push_back() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
assert_eq!(d.len(), 3);
assert_eq!(d.peek_front(), Some(&1));
assert_eq!(d.peek_back(), Some(&3));
}
#[test]
fn test_pop_front() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
let (first, d) = d
.pop_front()
.expect("deque with 3 elements should have a front element");
assert_eq!(first, 1);
let (second, d) = d
.pop_front()
.expect("deque with 2 remaining elements should have a front element");
assert_eq!(second, 2);
let (third, d) = d
.pop_front()
.expect("deque with 1 remaining element should have a front element");
assert_eq!(third, 3);
assert!(d.is_empty());
}
#[test]
fn test_pop_back() {
let d = Deque::new().push_front(1).push_front(2).push_front(3);
let (last, d) = d
.pop_back()
.expect("deque with 3 elements should have a back element");
assert_eq!(last, 1);
let (second_last, d) = d
.pop_back()
.expect("deque with 2 remaining elements should have a back element");
assert_eq!(second_last, 2);
let (first, d) = d
.pop_back()
.expect("deque with 1 remaining element should have a back element");
assert_eq!(first, 3);
assert!(d.is_empty());
}
#[test]
fn test_persistence() {
let d1 = Deque::new().push_back(1).push_back(2);
let d2 = d1.clone().push_back(3);
assert_eq!(d1.len(), 2);
assert_eq!(d2.len(), 3);
}
#[test]
fn test_mixed_operations() {
let d = Deque::new()
.push_back(2)
.push_front(1)
.push_back(3)
.push_front(0);
assert_eq!(d.peek_front(), Some(&0));
assert_eq!(d.peek_back(), Some(&3));
let items: Vec<_> = d.into_iter().collect();
assert_eq!(items, vec![0, 1, 2, 3]);
}
#[test]
fn test_reverse() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
let r = d.reverse();
assert_eq!(r.peek_front(), Some(&3));
assert_eq!(r.peek_back(), Some(&1));
}
#[test]
fn test_map() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
let doubled = d.map(|x| x * 2);
let items: Vec<_> = doubled.into_iter().collect();
assert_eq!(items, vec![2, 4, 6]);
}
#[test]
fn test_fold() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
let sum = d.fold(0, |acc, x| acc + x);
assert_eq!(sum, 6);
}
#[test]
fn test_filter() {
let d = Deque::new()
.push_back(1)
.push_back(2)
.push_back(3)
.push_back(4);
let evens = d.filter(|x| x % 2 == 0);
assert_eq!(evens.len(), 2);
}
#[test]
fn test_filter_empty_deque_returns_empty() {
let d: Deque<i32> = Deque::new();
let result = d.filter(|_| true);
assert_eq!(result.len(), 0);
assert_eq!(result.to_vec(), Vec::<i32>::new());
}
#[test]
fn test_filter_no_match_returns_empty() {
let d = Deque::new().push_back(1).push_back(3).push_back(5);
let evens = d.filter(|x| x % 2 == 0);
assert_eq!(evens.len(), 0);
assert_eq!(evens.to_vec(), Vec::<i32>::new());
}
#[test]
fn test_filter_preserves_element_values() {
let d = Deque::new()
.push_front(4) .push_front(3) .push_back(5) .push_back(6); let evens = d.filter(|x| x % 2 == 0);
assert_eq!(evens.len(), 2);
let mut v = evens.to_vec();
v.sort_unstable();
assert_eq!(v, vec![4, 6]);
}
#[test]
fn test_to_vec() {
let d = Deque::new().push_back(1).push_back(2).push_back(3);
assert_eq!(d.to_vec(), vec![1, 2, 3]);
}
#[test]
fn test_concat() {
let d1 = Deque::new().push_back(1).push_back(2);
let d2 = Deque::new().push_back(3).push_back(4);
let combined = d1.concat(&d2);
assert_eq!(combined.len(), 4);
assert_eq!(combined.to_vec(), vec![1, 2, 3, 4]);
}
#[test]
fn test_from_vec() {
let v = vec![1, 2, 3];
let d = Deque::from(v);
assert_eq!(d.len(), 3);
assert_eq!(d.to_vec(), vec![1, 2, 3]);
}
#[test]
fn test_from_iter() {
let d: Deque<i32> = vec![1, 2, 3].into_iter().collect();
assert_eq!(d.to_vec(), vec![1, 2, 3]);
}
#[test]
fn test_rebalance() {
let d = Deque::new()
.push_back(1)
.push_back(2)
.push_back(3)
.push_back(4);
let (first, d) = d
.pop_front()
.expect("deque should be non-empty before first front pop");
assert_eq!(first, 1);
let (second, _d) = d
.pop_front()
.expect("deque should be non-empty before second front pop");
assert_eq!(second, 2);
let d = Deque::new()
.push_front(1)
.push_front(2)
.push_front(3)
.push_front(4);
let (last, d) = d
.pop_back()
.expect("deque should be non-empty before first back pop");
assert_eq!(last, 1);
let (second_last, _) = d
.pop_back()
.expect("deque should be non-empty before second back pop");
assert_eq!(second_last, 2);
}
}
#[cfg(all(test, feature = "serde"))]
mod serde_invariant_tests {
use super::*;
#[test]
fn forged_len_is_recomputed() {
let d: Deque<i32> = serde_json::from_str(r#"{"front":[],"back":[],"len":5}"#).unwrap();
assert_eq!(d.len(), 0);
assert!(d.pop_front().is_none()); let d: Deque<i32> =
serde_json::from_str(r#"{"front":[1],"back":[2,3],"len":999}"#).unwrap();
assert_eq!(d.len(), 3);
}
}