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
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::default::Default;
use std::slice;
use std::iter::Map;
pub struct DStack<I> {
stacks: Vec<StackVal<I>>,
rec_head: Option<usize>,
out_head: usize,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum StackVal<I> {
Enter(I),
Exit(I)
}
impl<I> DStack<I> where I: Copy {
pub fn with_capacity(n: usize) -> DStack<I> where I: Default {
assert!(n > 1);
DStack {
stacks: vec![StackVal::Enter(I::default()); n],
rec_head: None,
out_head: n
}
}
pub fn capacity(&self) -> usize {
self.stacks.len()
}
pub fn is_rec_empty(&self) -> bool {
self.rec_head.is_none()
}
pub fn is_data_empty(&self) -> bool {
self.out_head == self.capacity()
}
pub fn push_rec(&mut self, value: StackVal<I>) {
let head = self.rec_head.map_or(0, |x| x + 1);
assert!(head < self.out_head);
self.stacks[head] = value;
self.rec_head = Some(head);
}
pub fn push_data(&mut self, value: I) {
self.out_head -= 1;
if let Some(rec_head) = self.rec_head {
assert!(self.out_head > rec_head);
}
self.stacks[self.out_head] = StackVal::Enter(value);
}
pub fn pop_rec(&mut self) -> Option<StackVal<I>> {
match self.rec_head {
Some(rec_head) => {
let res = self.stacks[rec_head];
self.rec_head = if rec_head > 0 {
Some(rec_head - 1)
} else { None };
Some(res)
},
None => None
}
}
pub fn pop_data(&mut self) -> Option<I> {
if self.out_head >= self.stacks.len() {
None
}
else {
if let StackVal::Enter(res) = self.stacks[self.out_head] {
self.out_head += 1;
Some(res)
}
else {
unreachable!();
}
}
}
pub fn len_data(&self) -> usize {
let n = self.stacks.len();
n - self.out_head
}
pub fn clear_data(&mut self) {
self.out_head = self.stacks.len();
}
pub fn iter_data<'a>(&'a self) -> Map<slice::Iter<'a, StackVal<I>>, fn(& StackVal<I>) -> &I> {
self.stacks[self.out_head..].iter().map(extract_stack_val)
}
}
fn extract_stack_val<I>(stack_val: &StackVal<I>) -> &I {
match stack_val {
& StackVal::Enter(ref i) => &i,
& StackVal::Exit(ref i) => &i,
}
}