Thanks to visit codestin.com
Credit goes to docs.rs

rpds/queue/
mod.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 */
5
6use crate::List;
7use alloc::vec::Vec;
8use archery::*;
9use core::borrow::Borrow;
10use core::cmp::Ordering;
11use core::fmt::Display;
12use core::hash::{Hash, Hasher};
13use core::iter::FromIterator;
14
15// TODO Use impl trait instead of this when available.
16type IterPtr<'a, T, P> =
17    core::iter::Chain<crate::list::IterPtr<'a, T, P>, LazilyReversedListIter<'a, T, P>>;
18pub type Iter<'a, T, P> = core::iter::Map<IterPtr<'a, T, P>, fn(&SharedPointer<T, P>) -> &T>;
19
20/// Creates a [`Queue`](crate::Queue) containing the given arguments:
21///
22/// ```
23/// # use rpds::*;
24/// #
25/// let q = Queue::new()
26///     .enqueue(1)
27///     .enqueue(2)
28///     .enqueue(3);
29///
30/// assert_eq!(queue![1, 2, 3], q);
31/// ```
32#[macro_export]
33macro_rules! queue {
34    ($($e:expr),*) => {
35        {
36            #[allow(unused_mut)]
37            let mut q = $crate::Queue::new();
38            $(
39                q.enqueue_mut($e);
40            )*
41            q
42        }
43    };
44}
45
46/// Creates a [`Queue`](crate::Queue) that implements `Sync`, containing the given arguments:
47///
48/// ```
49/// # use rpds::*;
50/// #
51/// let q = Queue::new_sync()
52///     .enqueue(1)
53///     .enqueue(2)
54///     .enqueue(3);
55///
56/// assert_eq!(queue_sync![1, 2, 3], q);
57///
58/// fn is_sync() -> impl Sync {
59///     queue_sync![0, 1, 3]
60/// }
61/// ```
62#[macro_export]
63macro_rules! queue_sync {
64    ($($e:expr),*) => {
65        {
66            #[allow(unused_mut)]
67            let mut q = $crate::Queue::new_sync();
68            $(
69                q.enqueue_mut($e);
70            )*
71            q
72        }
73    };
74}
75
76/// A persistent queue with structural sharing.
77///
78/// # Complexity
79///
80/// Let *n* be the number of elements in the queue.
81///
82/// ## Temporal complexity
83///
84/// | Operation             | Average | Worst case  |
85/// |:--------------------- | -------:| -----------:|
86/// | `new()`               |    Θ(1) |        Θ(1) |
87/// | `enqueue()`           |    Θ(1) |        Θ(1) |
88/// | `dequeue()`           |    Θ(1) |        Θ(n) |
89/// | `dequeue()` amortized |    Θ(1) |        Θ(1) |
90/// | `peek()`              |    Θ(1) |        Θ(1) |
91/// | `len()`               |    Θ(1) |        Θ(1) |
92/// | `clone()`             |    Θ(1) |        Θ(1) |
93/// | iterator creation     |    Θ(1) |        Θ(1) |
94/// | iterator step         |    Θ(1) |        Θ(n) |
95/// | iterator full         |    Θ(n) |        Θ(n) |
96///
97/// # Implementation details
98///
99/// This queue is implemented as described in
100/// [Immutability in C# Part Four: An Immutable Queue](https://goo.gl/hWyMuS).
101#[derive(Debug)]
102pub struct Queue<T, P = RcK>
103where
104    P: SharedPointerKind,
105{
106    in_list: List<T, P>,
107    out_list: List<T, P>,
108}
109
110pub type QueueSync<T> = Queue<T, ArcTK>;
111
112impl<T> QueueSync<T> {
113    #[must_use]
114    pub fn new_sync() -> QueueSync<T> {
115        Queue::new_with_ptr_kind()
116    }
117}
118
119impl<T> Queue<T> {
120    #[must_use]
121    pub fn new() -> Queue<T> {
122        Queue::new_with_ptr_kind()
123    }
124}
125
126impl<T, P> Queue<T, P>
127where
128    P: SharedPointerKind,
129{
130    #[must_use]
131    pub fn new_with_ptr_kind() -> Queue<T, P> {
132        Queue { in_list: List::new_with_ptr_kind(), out_list: List::new_with_ptr_kind() }
133    }
134
135    #[must_use]
136    pub fn peek(&self) -> Option<&T> {
137        if !self.out_list.is_empty() { self.out_list.first() } else { self.in_list.last() }
138    }
139
140    #[must_use]
141    pub fn dequeue(&self) -> Option<Queue<T, P>> {
142        let mut new_queue = self.clone();
143
144        if new_queue.dequeue_mut() { Some(new_queue) } else { None }
145    }
146
147    pub fn dequeue_mut(&mut self) -> bool {
148        if !self.out_list.is_empty() {
149            self.out_list.drop_first_mut();
150            true
151        } else if !self.in_list.is_empty() {
152            core::mem::swap(&mut self.in_list, &mut self.out_list);
153
154            self.out_list.reverse_mut();
155            self.out_list.drop_first_mut();
156            true
157        } else {
158            false
159        }
160    }
161
162    #[must_use]
163    pub fn enqueue(&self, v: T) -> Queue<T, P> {
164        let mut new_queue = self.clone();
165
166        new_queue.enqueue_mut(v);
167
168        new_queue
169    }
170
171    pub fn enqueue_mut(&mut self, v: T) {
172        self.in_list.push_front_mut(v);
173    }
174
175    #[must_use]
176    #[inline]
177    pub fn len(&self) -> usize {
178        self.in_list.len() + self.out_list.len()
179    }
180
181    #[must_use]
182    #[inline]
183    pub fn is_empty(&self) -> bool {
184        self.len() == 0
185    }
186
187    pub fn iter(&self) -> Iter<'_, T, P> {
188        self.iter_ptr().map(|v| v.borrow())
189    }
190
191    fn iter_ptr(&self) -> IterPtr<'_, T, P> {
192        self.out_list.iter_ptr().chain(LazilyReversedListIter::new(&self.in_list))
193    }
194}
195
196impl<T, P> Default for Queue<T, P>
197where
198    P: SharedPointerKind,
199{
200    fn default() -> Queue<T, P> {
201        Queue::new_with_ptr_kind()
202    }
203}
204
205impl<T: PartialEq, P, PO> PartialEq<Queue<T, PO>> for Queue<T, P>
206where
207    P: SharedPointerKind,
208    PO: SharedPointerKind,
209{
210    fn eq(&self, other: &Queue<T, PO>) -> bool {
211        self.len() == other.len() && self.iter().eq(other.iter())
212    }
213}
214
215impl<T: Eq, P> Eq for Queue<T, P> where P: SharedPointerKind {}
216
217impl<T: PartialOrd<T>, P, PO> PartialOrd<Queue<T, PO>> for Queue<T, P>
218where
219    P: SharedPointerKind,
220    PO: SharedPointerKind,
221{
222    fn partial_cmp(&self, other: &Queue<T, PO>) -> Option<Ordering> {
223        self.iter().partial_cmp(other.iter())
224    }
225}
226
227impl<T: Ord, P> Ord for Queue<T, P>
228where
229    P: SharedPointerKind,
230{
231    fn cmp(&self, other: &Queue<T, P>) -> Ordering {
232        self.iter().cmp(other.iter())
233    }
234}
235
236impl<T: Hash, P> Hash for Queue<T, P>
237where
238    P: SharedPointerKind,
239{
240    fn hash<H: Hasher>(&self, state: &mut H) {
241        // Add the hash of length so that if two collections are added one after the other it
242        // doesn't hash to the same thing as a single collection with the same elements in the same
243        // order.
244        self.len().hash(state);
245
246        for e in self {
247            e.hash(state);
248        }
249    }
250}
251
252impl<T, P> Clone for Queue<T, P>
253where
254    P: SharedPointerKind,
255{
256    fn clone(&self) -> Queue<T, P> {
257        Queue { in_list: self.in_list.clone(), out_list: self.out_list.clone() }
258    }
259}
260
261impl<T: Display, P> Display for Queue<T, P>
262where
263    P: SharedPointerKind,
264{
265    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266        let mut first = true;
267
268        fmt.write_str("Queue(")?;
269
270        for v in self {
271            if !first {
272                fmt.write_str(", ")?;
273            }
274            v.fmt(fmt)?;
275            first = false;
276        }
277
278        fmt.write_str(")")
279    }
280}
281
282impl<'a, T, P> IntoIterator for &'a Queue<T, P>
283where
284    P: SharedPointerKind,
285{
286    type Item = &'a T;
287    type IntoIter = Iter<'a, T, P>;
288
289    fn into_iter(self) -> Iter<'a, T, P> {
290        self.iter()
291    }
292}
293
294impl<T, P> FromIterator<T> for Queue<T, P>
295where
296    P: SharedPointerKind,
297{
298    fn from_iter<I: IntoIterator<Item = T>>(into_iter: I) -> Queue<T, P> {
299        Queue { out_list: List::from_iter(into_iter), in_list: List::new_with_ptr_kind() }
300    }
301}
302
303pub enum LazilyReversedListIter<'a, T: 'a, P>
304where
305    P: SharedPointerKind,
306{
307    Uninitialized { list: &'a List<T, P> },
308    Initialized { vec: Vec<&'a SharedPointer<T, P>>, current: Option<usize> },
309}
310
311impl<T, P> LazilyReversedListIter<'_, T, P>
312where
313    P: SharedPointerKind,
314{
315    fn new(list: &List<T, P>) -> LazilyReversedListIter<'_, T, P> {
316        LazilyReversedListIter::Uninitialized { list }
317    }
318}
319
320impl<'a, T, P> Iterator for LazilyReversedListIter<'a, T, P>
321where
322    P: SharedPointerKind,
323{
324    type Item = &'a SharedPointer<T, P>;
325
326    fn next(&mut self) -> Option<&'a SharedPointer<T, P>> {
327        match self {
328            LazilyReversedListIter::Uninitialized { list } => {
329                let len = list.len();
330                let mut vec: Vec<&'a SharedPointer<T, P>> = Vec::with_capacity(len);
331
332                for v in list.iter_ptr() {
333                    vec.push(v);
334                }
335
336                *self = LazilyReversedListIter::Initialized {
337                    vec,
338                    current: if len > 0 { Some(len - 1) } else { None },
339                };
340
341                self.next()
342            }
343
344            &mut LazilyReversedListIter::Initialized { ref vec, ref mut current } => {
345                let v = current.map(|i| vec[i]);
346
347                *current = match *current {
348                    Some(0) => None,
349                    Some(i) => Some(i - 1),
350                    None => None,
351                };
352
353                v
354            }
355        }
356    }
357
358    fn size_hint(&self) -> (usize, Option<usize>) {
359        let len = match self {
360            LazilyReversedListIter::Uninitialized { list } => list.len(),
361            LazilyReversedListIter::Initialized { current: Some(i), .. } => i + 1,
362            LazilyReversedListIter::Initialized { current: None, .. } => 0,
363        };
364
365        (len, Some(len))
366    }
367}
368
369impl<T, P> ExactSizeIterator for LazilyReversedListIter<'_, T, P> where P: SharedPointerKind {}
370
371#[cfg(feature = "serde")]
372pub mod serde {
373    use super::*;
374    use ::serde::de::{Deserialize, Deserializer};
375    use ::serde::ser::{Serialize, Serializer};
376
377    impl<T, P> Serialize for Queue<T, P>
378    where
379        T: Serialize,
380        P: SharedPointerKind,
381    {
382        fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
383            serializer.collect_seq(self)
384        }
385    }
386
387    impl<'de, T, P> Deserialize<'de> for Queue<T, P>
388    where
389        T: Deserialize<'de>,
390        P: SharedPointerKind,
391    {
392        fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Queue<T, P>, D::Error> {
393            Deserialize::deserialize(deserializer)
394                .map(|list| Queue { out_list: list, in_list: List::new_with_ptr_kind() })
395        }
396    }
397}
398
399#[cfg(test)]
400mod test;