use std::collections::VecDeque;
#[derive(Debug)]
pub struct DynamicDeque<T, const STACK_SIZE: usize> {
stack: heapless::Deque<T, STACK_SIZE>,
heap: VecDeque<T>,
}
impl<T, const STACK_SIZE: usize> Default for DynamicDeque<T, STACK_SIZE> {
fn default() -> Self {
Self {
stack: heapless::Deque::new(),
heap: VecDeque::new(),
}
}
}
#[allow(unused)]
impl<T, const STATIC_SIZE: usize> DynamicDeque<T, STATIC_SIZE> {
pub fn from<const SIZE: usize>(prepare: [T; SIZE]) -> Self {
let mut instance = Self::default();
for item in prepare {
instance.push_back(item);
}
instance
}
pub fn push_back_stack(&mut self, value: T) -> Result<(), T> {
self.stack.push_back(value)
}
pub fn push_back(&mut self, value: T) {
if let Err(value) = self.stack.push_back(value) {
self.heap.push_back(value);
}
}
pub fn pop_front(&mut self) -> Option<T> {
let res = self.stack.pop_front();
if !self.stack.is_full() && !self.heap.is_empty() {
let front = self.heap.pop_front().expect("Should have");
if self.stack.push_back(front).is_err() {
panic!("cannot happen");
}
}
res
}
pub fn is_empty(&self) -> bool {
self.stack.is_empty()
}
pub fn len(&self) -> usize {
self.stack.len() + self.heap.len()
}
#[inline(always)]
pub fn pop2(&mut self, e: T) -> T {
if self.is_empty() {
e
} else {
let out = self.pop_front().expect("Should have because just push");
self.push_back(e);
out
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_push_back() {
let mut deque: DynamicDeque<i32, 2> = DynamicDeque::default();
assert!(deque.push_back_stack(1).is_ok());
assert!(deque.push_back_stack(2).is_ok());
assert!(deque.push_back_stack(3).is_err());
assert_eq!(deque.len(), 2);
deque.push_back(3);
assert_eq!(deque.len(), 3);
}
#[test]
fn test_pop_front() {
let mut deque: DynamicDeque<i32, 2> = DynamicDeque::default();
deque.push_back(1);
deque.push_back(2);
deque.push_back(3);
assert_eq!(deque.pop_front(), Some(1));
assert_eq!(deque.pop_front(), Some(2));
assert_eq!(deque.pop_front(), Some(3));
assert_eq!(deque.pop_front(), None);
assert_eq!(deque.len(), 0);
}
#[test]
fn test_is_empty() {
let mut deque: DynamicDeque<i32, 2> = DynamicDeque::default();
assert_eq!(deque.is_empty(), true);
deque.push_back(1);
assert_eq!(deque.is_empty(), false);
deque.pop_front();
assert_eq!(deque.is_empty(), true);
}
}