[go: up one dir, main page]

rpds/stack/
mod.rs

1use crate::List;
2use archery::*;
3use core::cmp::Ordering;
4use core::fmt::Display;
5use core::hash::{Hash, Hasher};
6use core::iter::FromIterator;
7
8// TODO Use impl trait for return value when available
9pub type Iter<'a, T, P> = crate::list::Iter<'a, T, P>;
10
11/// Creates a [`Stack`](crate::Stack) containing the given arguments:
12///
13/// ```
14/// # use rpds::*;
15/// #
16/// let mut s = Stack::new()
17///     .push(1)
18///     .push(2)
19///     .push(3);
20///
21/// assert_eq!(stack![1, 2, 3], s);
22/// ```
23#[macro_export]
24macro_rules! stack {
25    ($($e:expr),*) => {
26        {
27            #[allow(unused_mut)]
28            let mut s = $crate::Stack::new();
29            $(
30                s.push_mut($e);
31            )*
32            s
33        }
34    };
35}
36
37/// Creates a [`Stack`](crate::Stack) that implements `Sync`, containing the given arguments:
38///
39/// ```
40/// # use rpds::*;
41/// #
42/// let mut s = Stack::new_sync()
43///     .push(1)
44///     .push(2)
45///     .push(3);
46///
47/// assert_eq!(stack_sync![1, 2, 3], s);
48///
49/// fn is_sync() -> impl Sync {
50///     stack_sync![0, 1, 1, 2, 3, 5, 8]
51/// }
52/// ```
53#[macro_export]
54macro_rules! stack_sync {
55    ($($e:expr),*) => {
56        {
57            #[allow(unused_mut)]
58            let mut s = $crate::Stack::new_sync();
59            $(
60                s.push_mut($e);
61            )*
62            s
63        }
64    };
65}
66
67/// A persistent stack with structural sharing.
68///
69/// # Complexity
70///
71/// Let *n* be the number of elements in the stack.
72///
73/// ## Temporal complexity
74///
75/// | Operation         | Average | Worst case  |
76/// |:----------------- | -------:| -----------:|
77/// | `new()`           |    Θ(1) |        Θ(1) |
78/// | `push()`          |    Θ(1) |        Θ(1) |
79/// | `pop()`           |    Θ(1) |        Θ(1) |
80/// | `peek()`          |    Θ(1) |        Θ(1) |
81/// | `size()`          |    Θ(1) |        Θ(1) |
82/// | `clone()`         |    Θ(1) |        Θ(1) |
83/// | iterator creation |    Θ(1) |        Θ(1) |
84/// | iterator step     |    Θ(1) |        Θ(1) |
85/// | iterator full     |    Θ(n) |        Θ(n) |
86///
87/// # Implementation details
88///
89/// This is a thin wrapper around a [`List`](crate::List).
90#[derive(Debug)]
91pub struct Stack<T, P = RcK>
92where
93    P: SharedPointerKind,
94{
95    list: List<T, P>,
96}
97
98pub type StackSync<T> = Stack<T, ArcTK>;
99
100impl<T> StackSync<T> {
101    #[must_use]
102    pub fn new_sync() -> StackSync<T> {
103        Stack::new_with_ptr_kind()
104    }
105}
106
107impl<T> Stack<T> {
108    #[must_use]
109    pub fn new() -> Stack<T> {
110        Stack::new_with_ptr_kind()
111    }
112}
113
114impl<T, P> Stack<T, P>
115where
116    P: SharedPointerKind,
117{
118    #[must_use]
119    pub fn new_with_ptr_kind() -> Stack<T, P> {
120        Stack { list: List::new_with_ptr_kind() }
121    }
122
123    #[must_use]
124    pub fn peek(&self) -> Option<&T> {
125        self.list.first()
126    }
127
128    #[must_use]
129    pub fn pop(&self) -> Option<Stack<T, P>> {
130        let mut new_stack = self.clone();
131
132        if new_stack.pop_mut() { Some(new_stack) } else { None }
133    }
134
135    pub fn pop_mut(&mut self) -> bool {
136        self.list.drop_first_mut()
137    }
138
139    #[must_use]
140    pub fn push(&self, v: T) -> Stack<T, P> {
141        let mut new_stack = self.clone();
142
143        new_stack.push_mut(v);
144
145        new_stack
146    }
147
148    pub fn push_mut(&mut self, v: T) {
149        self.list.push_front_mut(v);
150    }
151
152    #[must_use]
153    #[inline]
154    pub fn size(&self) -> usize {
155        self.list.len()
156    }
157
158    #[must_use]
159    #[inline]
160    pub fn is_empty(&self) -> bool {
161        self.list.is_empty()
162    }
163
164    pub fn iter(&self) -> Iter<'_, T, P> {
165        self.list.iter()
166    }
167}
168
169impl<T, P> Default for Stack<T, P>
170where
171    P: SharedPointerKind,
172{
173    fn default() -> Stack<T, P> {
174        Stack::new_with_ptr_kind()
175    }
176}
177
178impl<T: PartialEq, P, PO> PartialEq<Stack<T, PO>> for Stack<T, P>
179where
180    P: SharedPointerKind,
181    PO: SharedPointerKind,
182{
183    fn eq(&self, other: &Stack<T, PO>) -> bool {
184        self.list.eq(&other.list)
185    }
186}
187
188impl<T: Eq, P> Eq for Stack<T, P> where P: SharedPointerKind {}
189
190impl<T: PartialOrd<T>, P, PO> PartialOrd<Stack<T, PO>> for Stack<T, P>
191where
192    P: SharedPointerKind,
193    PO: SharedPointerKind,
194{
195    fn partial_cmp(&self, other: &Stack<T, PO>) -> Option<Ordering> {
196        self.list.partial_cmp(&other.list)
197    }
198}
199
200impl<T: Ord, P> Ord for Stack<T, P>
201where
202    P: SharedPointerKind,
203{
204    fn cmp(&self, other: &Stack<T, P>) -> Ordering {
205        self.list.cmp(&other.list)
206    }
207}
208
209impl<T: Hash, P> Hash for Stack<T, P>
210where
211    P: SharedPointerKind,
212{
213    fn hash<H: Hasher>(&self, state: &mut H) {
214        self.list.hash(state);
215    }
216}
217
218impl<T, P> Clone for Stack<T, P>
219where
220    P: SharedPointerKind,
221{
222    fn clone(&self) -> Stack<T, P> {
223        Stack { list: List::clone(&self.list) }
224    }
225}
226
227impl<T: Display, P> Display for Stack<T, P>
228where
229    P: SharedPointerKind,
230{
231    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
232        let mut first = true;
233
234        fmt.write_str("Stack(")?;
235
236        for v in self {
237            if !first {
238                fmt.write_str(", ")?;
239            }
240            v.fmt(fmt)?;
241            first = false;
242        }
243
244        fmt.write_str(")")
245    }
246}
247
248impl<'a, T, P> IntoIterator for &'a Stack<T, P>
249where
250    P: SharedPointerKind,
251{
252    type Item = &'a T;
253    type IntoIter = Iter<'a, T, P>;
254
255    fn into_iter(self) -> Iter<'a, T, P> {
256        self.list.iter()
257    }
258}
259
260impl<T, P> FromIterator<T> for Stack<T, P>
261where
262    P: SharedPointerKind,
263{
264    fn from_iter<I: IntoIterator<Item = T>>(into_iter: I) -> Stack<T, P> {
265        Stack { list: List::from_iter(into_iter) }
266    }
267}
268
269#[cfg(feature = "serde")]
270pub mod serde {
271    use super::*;
272    use ::serde::de::{Deserialize, Deserializer};
273    use ::serde::ser::{Serialize, Serializer};
274
275    impl<T, P> Serialize for Stack<T, P>
276    where
277        T: Serialize,
278        P: SharedPointerKind,
279    {
280        fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
281            self.list.serialize(serializer)
282        }
283    }
284
285    impl<'de, T, P> Deserialize<'de> for Stack<T, P>
286    where
287        T: Deserialize<'de>,
288        P: SharedPointerKind,
289    {
290        fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Stack<T, P>, D::Error> {
291            Deserialize::deserialize(deserializer).map(|list| Stack { list })
292        }
293    }
294}
295
296#[cfg(test)]
297mod test;