1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::error;
use crate::lang::Error;
type Result<T> = std::result::Result<T, Error>;
#[derive(Clone)]
pub struct Stack<T> {
overflow_message: &'static str,
vec: Vec<T>,
}
impl<T: std::fmt::Debug> std::fmt::Debug for Stack<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.vec)
}
}
impl<T> Stack<T> {
pub fn new(overflow_message: &'static str) -> Stack<T> {
Stack {
overflow_message,
vec: vec![],
}
}
fn max_len(&self) -> usize {
u16::max_value() as usize
}
fn overflow_check(&self) -> Result<()> {
if self.vec.len() > self.max_len() {
Err(error!(OutOfMemory; self.overflow_message))
} else {
Ok(())
}
}
fn underflow_error(&self) -> Error {
error!(InternalError; "UNDERFLOW")
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.vec.get_mut(index)
}
pub fn clear(&mut self) {
self.vec.clear()
}
pub fn drain<R>(&mut self, range: R) -> std::vec::Drain<'_, T>
where
R: std::ops::RangeBounds<usize>,
{
debug_assert!(range.end_bound() == std::ops::Bound::Unbounded);
self.vec.drain(range)
}
pub fn len(&self) -> usize {
self.vec.len()
}
pub fn is_empty(&self) -> bool {
self.vec.is_empty()
}
pub fn is_full(&self) -> bool {
self.vec.len() > self.max_len() - 32
}
pub fn last(&self) -> Option<&T> {
self.vec.last()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.vec.get(index)
}
pub fn append(&mut self, other: &mut Stack<T>) -> Result<()> {
self.vec.append(&mut other.vec);
self.overflow_check()
}
pub fn push(&mut self, val: T) -> Result<()> {
self.vec.push(val);
self.overflow_check()
}
pub fn pop(&mut self) -> Result<T> {
match self.vec.pop() {
Some(v) => Ok(v),
None => Err(self.underflow_error()),
}
}
pub fn pop_2(&mut self) -> Result<(T, T)> {
let two = self.pop()?;
let one = self.pop()?;
Ok((one, two))
}
pub fn pop_n(&mut self, len: usize) -> Result<Stack<T>> {
if len > self.vec.len() {
Err(self.underflow_error())
} else {
let range = (self.vec.len() - len as usize)..;
let mut st: Stack<T> = Stack::new(self.overflow_message);
for item in self.drain(range) {
st.push(item)?;
}
Ok(st)
}
}
}
impl<T> IntoIterator for Stack<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}