use super::Vector;
use std::fmt::{self, Debug};
use std::iter::FromIterator;
use std::ops::RangeBounds;
#[derive(Clone)]
pub struct Stack<T> {
data: Vector<T>,
}
pub struct Iter<'a, T> {
iter: std::iter::Rev<std::slice::Iter<'a, T>>,
}
pub struct IterMut<'a, T> {
iter: std::iter::Rev<std::slice::IterMut<'a, T>>,
}
pub struct Drain<T> {
elements: Vec<T>,
}
impl<T> Stack<T> {
#[inline]
pub fn new() -> Self {
Self {
data: Vector::new(),
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vector::with_capacity(capacity),
}
}
#[inline]
pub fn push(&mut self, value: T) {
self.data.push(value);
}
#[inline]
pub fn pop(&mut self) -> Option<T> {
self.data.pop()
}
#[inline]
pub fn peek(&self) -> Option<&T> {
self.data.last()
}
#[inline]
pub fn peek_mut(&mut self) -> Option<&mut T> {
self.data.last_mut()
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
}
#[inline]
pub fn capacity(&self) -> usize {
self.data.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
Iter {
iter: self.data.iter().rev(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut {
iter: self.data.iter_mut().rev(),
}
}
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.data
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.data
}
#[inline]
pub fn drain<R>(&mut self, range: R) -> Drain<T>
where
R: RangeBounds<usize>,
{
let mut elements: Vec<T> = self.data.drain(range).collect();
elements.reverse();
Drain { elements }
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T> Iterator for Drain<T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.elements.pop()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.elements.len();
(len, Some(len))
}
}
impl<'a, T> IntoIterator for &'a Stack<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Stack<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T: Debug> Debug for Stack<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stack").field("data", &self.data).finish()
}
}
impl<T> Default for Stack<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> FromIterator<T> for Stack<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut stack = Stack::new();
stack.extend(iter);
stack
}
}
impl<T> Extend<T> for Stack<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.data.extend(iter);
}
}
impl<T> From<Vec<T>> for Stack<T> {
#[inline]
fn from(vec: Vec<T>) -> Self {
Self {
data: Vector::from(vec),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stack_basic_operations() {
let mut stack = Stack::new();
stack.push(1);
stack.push(2);
stack.push(3);
assert_eq!(stack.len(), 3);
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
assert_eq!(stack.pop(), None);
assert!(stack.is_empty());
assert_eq!(stack.peek(), None);
}
#[test]
fn test_stack_peek() {
let mut stack = Stack::new();
stack.push(1);
assert_eq!(stack.peek(), Some(&1));
assert_eq!(stack.peek_mut(), Some(&mut 1));
if let Some(top) = stack.peek_mut() {
*top = 2;
}
assert_eq!(stack.pop(), Some(2));
}
#[test]
fn test_stack_capacity() {
let mut stack = Stack::with_capacity(10);
assert!(stack.capacity() >= 10);
for i in 0..20 {
stack.push(i);
}
assert!(stack.capacity() >= 20);
for _ in 0..15 {
stack.pop();
}
stack.shrink_to_fit();
assert!(stack.capacity() >= 5);
}
#[test]
fn test_iterator() {
let mut stack = Stack::new();
stack.push(1);
stack.push(2);
stack.push(3);
let mut iter = stack.iter();
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
let mut sum = 0;
for &x in &stack {
sum += x;
}
assert_eq!(sum, 6);
for x in &mut stack {
*x *= 2;
}
assert_eq!(stack.pop(), Some(6));
assert_eq!(stack.pop(), Some(4));
assert_eq!(stack.pop(), Some(2));
}
#[test]
fn test_as_slice() {
let mut stack = Stack::new();
stack.push(1);
stack.push(2);
stack.push(3);
let slice = stack.as_slice();
assert_eq!(slice, &[1, 2, 3]);
let mut_slice = stack.as_mut_slice();
mut_slice[0] *= 2;
mut_slice[1] *= 2;
mut_slice[2] *= 2;
assert_eq!(stack.pop(), Some(6));
assert_eq!(stack.pop(), Some(4));
assert_eq!(stack.pop(), Some(2));
}
#[test]
fn test_from_iterator() {
let vec = vec![1, 2, 3];
let mut stack: Stack<_> = vec.into_iter().collect();
assert_eq!(stack.len(), 3);
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
}
#[test]
fn test_extend() {
let mut stack = Stack::new();
stack.push(1);
stack.extend(vec![2, 3, 4]);
assert_eq!(stack.len(), 4);
assert_eq!(stack.pop(), Some(4));
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
stack.extend(std::iter::empty::<i32>());
assert!(stack.is_empty());
stack.extend(0..3);
stack.extend(3..5);
assert_eq!(stack.len(), 5);
for i in (0..5).rev() {
assert_eq!(stack.pop(), Some(i));
}
}
#[test]
fn test_from_vec() {
let vec = vec![1, 2, 3];
let mut stack = Stack::from(vec);
assert_eq!(stack.len(), 3);
assert_eq!(stack.pop(), Some(3));
assert_eq!(stack.pop(), Some(2));
assert_eq!(stack.pop(), Some(1));
}
#[test]
fn test_drain() {
let mut stack = Stack::new();
stack.extend(0..5);
let drained: Vec<_> = stack.drain(1..4).collect();
assert_eq!(drained, vec![1, 2, 3]); assert_eq!(stack.len(), 2);
assert_eq!(stack.pop(), Some(4));
assert_eq!(stack.pop(), Some(0));
stack.extend(0..3); let drained: Vec<_> = stack.drain(1..1).collect();
assert!(drained.is_empty());
assert_eq!(stack.len(), 3);
let drained: Vec<_> = stack.drain(..).collect();
assert_eq!(drained, vec![0, 1, 2]);
assert!(stack.is_empty());
}
}