use std::iter::FromIterator;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct DoubleStack<T> {
read_stack: Vec<T>,
write_stack: Vec<T>,
}
impl<T> DoubleStack<T> {
pub fn new() -> Self {
Self {
read_stack: Default::default(),
write_stack: Default::default(),
}
}
#[inline(always)]
pub fn pop(&mut self) -> Option<T> {
self.read_stack.pop()
}
#[inline(always)]
pub fn push(&mut self, v: T) {
self.write_stack.push(v);
}
#[inline(always)]
pub fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.write_stack.extend(iter)
}
#[inline(always)]
pub fn swap(&mut self) {
debug_assert!(
self.read_stack.is_empty(),
"Tried to swap stacks while the read stack is not empty"
);
std::mem::swap(&mut self.read_stack, &mut self.write_stack);
}
pub fn len(&self) -> usize {
self.read_stack.len() + self.write_stack.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<T: Clone> DoubleStack<T> {
#[inline(always)]
pub fn extend_from_slice(&mut self, v: &[T]) {
self.write_stack.extend_from_slice(&v)
}
}
impl<T> Default for DoubleStack<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> FromIterator<T> for DoubleStack<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self {
read_stack: Default::default(),
write_stack: iter.into_iter().collect(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_push_pop() {
let mut s: DoubleStack<u8> = Default::default();
assert_eq!(s.pop(), None);
for i in 0..10 {
s.push(i);
assert_eq!(s.pop(), None);
}
s.swap();
for i in (0..10).rev() {
s.push(i);
assert_eq!(s.pop(), Some(i));
}
assert_eq!(s.pop(), None);
s.swap();
for i in 0..10 {
assert_eq!(s.pop(), Some(i));
}
assert_eq!(s.pop(), None);
}
#[test]
fn test_extend() {
let mut s: DoubleStack<u8> = Default::default();
s.extend(0..10);
assert_eq!(s.pop(), None);
s.swap();
for i in (0..10).rev() {
assert_eq!(s.pop(), Some(i))
}
assert_eq!(s.pop(), None);
}
#[test]
fn test_extend_from_slice() {
let mut s: DoubleStack<u8> = Default::default();
s.extend(0..10);
assert_eq!(s.pop(), None);
s.swap();
for i in (0..10).rev() {
assert_eq!(s.pop(), Some(i))
}
assert_eq!(s.pop(), None);
}
#[test]
fn test_from_iter() {
let mut s: DoubleStack<u8> = (0..10).collect();
assert_eq!(s.pop(), None);
s.swap();
for i in (0..10).rev() {
assert_eq!(s.pop(), Some(i))
}
assert_eq!(s.pop(), None);
}
}