rune_alloc/vec_deque/
into_iter.rs

1use core::fmt;
2use core::iter::FusedIterator;
3use core::ptr;
4
5use crate::alloc::{Allocator, Global};
6use crate::clone::TryClone;
7use crate::error::Error;
8
9use super::VecDeque;
10
11/// An owning iterator over the elements of a `VecDeque`.
12///
13/// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
14/// (provided by the [`IntoIterator`] trait). See its documentation for more.
15///
16/// [`into_iter`]: VecDeque::into_iter
17pub struct IntoIter<T, A: Allocator = Global> {
18    inner: VecDeque<T, A>,
19}
20
21impl<T, A: Allocator + Clone> TryClone for IntoIter<T, A>
22where
23    T: TryClone,
24{
25    #[inline]
26    fn try_clone(&self) -> Result<Self, Error> {
27        Ok(IntoIter {
28            inner: self.inner.try_clone()?,
29        })
30    }
31
32    #[inline]
33    fn try_clone_from(&mut self, source: &Self) -> Result<(), Error> {
34        self.inner.try_clone_from(&source.inner)
35    }
36}
37
38impl<T, A> IntoIter<T, A>
39where
40    A: Allocator,
41{
42    #[inline]
43    pub(super) fn new(inner: VecDeque<T, A>) -> Self {
44        IntoIter { inner }
45    }
46}
47
48impl<T, A> fmt::Debug for IntoIter<T, A>
49where
50    T: fmt::Debug,
51    A: Allocator,
52{
53    #[inline]
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        f.debug_tuple("IntoIter").field(&self.inner).finish()
56    }
57}
58
59impl<T, A> Iterator for IntoIter<T, A>
60where
61    A: Allocator,
62{
63    type Item = T;
64
65    #[inline]
66    fn next(&mut self) -> Option<T> {
67        self.inner.pop_front()
68    }
69
70    #[inline]
71    fn size_hint(&self) -> (usize, Option<usize>) {
72        let len = self.inner.len();
73        (len, Some(len))
74    }
75
76    #[inline]
77    fn count(self) -> usize {
78        self.inner.len
79    }
80
81    #[inline]
82    fn fold<B, F>(mut self, mut init: B, mut f: F) -> B
83    where
84        F: FnMut(B, Self::Item) -> B,
85    {
86        struct Guard<'a, T, A>
87        where
88            A: Allocator,
89        {
90            deque: &'a mut VecDeque<T, A>,
91            // `consumed <= deque.len` always holds.
92            consumed: usize,
93        }
94
95        impl<T, A> Drop for Guard<'_, T, A>
96        where
97            A: Allocator,
98        {
99            fn drop(&mut self) {
100                self.deque.len -= self.consumed;
101                self.deque.head = self.deque.to_physical_idx(self.consumed);
102            }
103        }
104
105        let mut guard = Guard {
106            deque: &mut self.inner,
107            consumed: 0,
108        };
109
110        let (head, tail) = guard.deque.as_slices();
111
112        init = head
113            .iter()
114            .map(|elem| {
115                guard.consumed += 1;
116                // SAFETY: Because we incremented `guard.consumed`, the
117                // deque effectively forgot the element, so we can take
118                // ownership
119                unsafe { ptr::read(elem) }
120            })
121            .fold(init, &mut f);
122
123        tail.iter()
124            .map(|elem| {
125                guard.consumed += 1;
126                // SAFETY: Same as above.
127                unsafe { ptr::read(elem) }
128            })
129            .fold(init, &mut f)
130    }
131
132    #[inline]
133    fn last(mut self) -> Option<Self::Item> {
134        self.inner.pop_back()
135    }
136}
137
138impl<T, A> DoubleEndedIterator for IntoIter<T, A>
139where
140    A: Allocator,
141{
142    #[inline]
143    fn next_back(&mut self) -> Option<T> {
144        self.inner.pop_back()
145    }
146
147    #[inline]
148    fn rfold<B, F>(mut self, mut init: B, mut f: F) -> B
149    where
150        F: FnMut(B, Self::Item) -> B,
151    {
152        struct Guard<'a, T, A>
153        where
154            A: Allocator,
155        {
156            deque: &'a mut VecDeque<T, A>,
157            // `consumed <= deque.len` always holds.
158            consumed: usize,
159        }
160
161        impl<T, A> Drop for Guard<'_, T, A>
162        where
163            A: Allocator,
164        {
165            fn drop(&mut self) {
166                self.deque.len -= self.consumed;
167            }
168        }
169
170        let mut guard = Guard {
171            deque: &mut self.inner,
172            consumed: 0,
173        };
174
175        let (head, tail) = guard.deque.as_slices();
176
177        init = tail
178            .iter()
179            .map(|elem| {
180                guard.consumed += 1;
181                // SAFETY: See `try_fold`'s safety comment.
182                unsafe { ptr::read(elem) }
183            })
184            .fold(init, &mut f);
185
186        head.iter()
187            .map(|elem| {
188                guard.consumed += 1;
189                // SAFETY: Same as above.
190                unsafe { ptr::read(elem) }
191            })
192            .fold(init, &mut f)
193    }
194}
195
196impl<T, A> ExactSizeIterator for IntoIter<T, A>
197where
198    A: Allocator,
199{
200    #[inline]
201    fn len(&self) -> usize {
202        self.inner.len()
203    }
204}
205
206impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}