#![allow(dead_code)]
use core::fmt::{Debug, Error, Formatter};
use tarrasque::{ExtractError, ExtractResult};
use crate::error::{OVERFLOW, UNDERFLOW};
use super::{Number};
const SIZE: usize = 64;
#[derive(Copy, Clone)]
pub struct NumberDeque {
buffer: [Number; SIZE],
top: usize,
bottom: usize,
}
impl NumberDeque {
#[inline]
pub fn new() -> Self {
Self { buffer: [Number::Integer(0); SIZE], top: 0, bottom: 0 }
}
#[inline]
pub fn len(&self) -> usize {
self.top.wrapping_sub(self.bottom)
}
#[inline]
pub fn is_empty(&self) -> bool {
self.top == self.bottom
}
#[inline]
pub fn push_top<'s>(&mut self, value: Number) -> ExtractResult<'s, ()> {
if self.len() != self.buffer.len() {
self.buffer[self.top & (self.buffer.len() - 1)] = value;
self.top = self.top.wrapping_add(1);
Ok(())
} else {
Err(ExtractError::Code(OVERFLOW))
}
}
#[inline]
pub fn push_bottom<'s>(
&mut self, value: Number
) -> ExtractResult<'s, ()> {
if self.len() != self.buffer.len() {
self.bottom = self.bottom.wrapping_sub(1);
self.buffer[self.bottom & (self.buffer.len() - 1)] = value;
Ok(())
} else {
Err(ExtractError::Code(OVERFLOW))
}
}
#[inline]
pub fn pop_top<'s, T>(
&mut self
) -> ExtractResult<'s, T> where Number: Into<T> {
if !self.is_empty() {
self.top -= 1;
Ok(self.buffer[self.top & (self.buffer.len() - 1)].into())
} else {
Err(ExtractError::Code(UNDERFLOW))
}
}
#[inline]
pub fn pop_bottom<'s, T>(
&mut self
) -> ExtractResult<'s, T> where Number: Into<T> {
if !self.is_empty() {
let value = self.buffer[self.bottom & (self.buffer.len() - 1)];
self.bottom = self.bottom.wrapping_add(1);
Ok(value.into())
} else {
Err(ExtractError::Code(UNDERFLOW))
}
}
}
impl Debug for NumberDeque {
#[inline]
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let bottom = self.bottom & (self.buffer.len() - 1);
let top = self.top & (self.buffer.len() - 1);
f.debug_list().entries((bottom..top).map(|i| self.buffer[i])).finish()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_number_deque_top() {
let mut deque = NumberDeque::new();
for number in 0..SIZE as i16 {
deque.push_top(Number::Integer(number)).unwrap();
}
let result = deque.push_top(Number::Integer(64));
assert_eq!(result, Err(ExtractError::Code(OVERFLOW)));
for number in (0..SIZE as i16).rev() {
assert_eq!(deque.pop_top(), Ok(Number::Integer(number)));
}
let result = deque.pop_top::<i16>();
assert_eq!(result, Err(ExtractError::Code(UNDERFLOW)));
}
#[test]
fn test_number_deque_bottom() {
let mut deque = NumberDeque::new();
for number in 0..SIZE as i16 {
deque.push_bottom(Number::Integer(number)).unwrap();
}
let result = deque.push_bottom(Number::Integer(64));
assert_eq!(result, Err(ExtractError::Code(OVERFLOW)));
for number in (0..SIZE as i16).rev() {
assert_eq!(deque.pop_bottom(), Ok(Number::Integer(number)));
}
let result = deque.pop_bottom::<i16>();
assert_eq!(result, Err(ExtractError::Code(UNDERFLOW)));
}
}