2 use core
::iter
::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}
;
3 use core
::mem
::MaybeUninit
;
6 use super::{count, wrap_index, RingSlices}
;
8 /// An iterator over the elements of a `VecDeque`.
10 /// This `struct` is created by the [`iter`] method on [`super::VecDeque`]. See its
11 /// documentation for more.
13 /// [`iter`]: super::VecDeque::iter
14 #[stable(feature = "rust1", since = "1.0.0")]
15 pub struct Iter
<'a
, T
: 'a
> {
16 pub(crate) ring
: &'a
[MaybeUninit
<T
>],
17 pub(crate) tail
: usize,
18 pub(crate) head
: usize,
21 #[stable(feature = "collection_debug", since = "1.17.0")]
22 impl<T
: fmt
::Debug
> fmt
::Debug
for Iter
<'_
, T
> {
23 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
24 let (front
, back
) = RingSlices
::ring_slices(self.ring
, self.head
, self.tail
);
26 // - `self.head` and `self.tail` in a ring buffer are always valid indices.
27 // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
30 .field(&MaybeUninit
::slice_assume_init_ref(front
))
31 .field(&MaybeUninit
::slice_assume_init_ref(back
))
37 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
38 #[stable(feature = "rust1", since = "1.0.0")]
39 impl<T
> Clone
for Iter
<'_
, T
> {
40 fn clone(&self) -> Self {
41 Iter { ring: self.ring, tail: self.tail, head: self.head }
45 #[stable(feature = "rust1", since = "1.0.0")]
46 impl<'a
, T
> Iterator
for Iter
<'a
, T
> {
50 fn next(&mut self) -> Option
<&'a T
> {
51 if self.tail
== self.head
{
55 self.tail
= wrap_index(self.tail
.wrapping_add(1), self.ring
.len());
57 // - `self.tail` in a ring buffer is always a valid index.
58 // - `self.head` and `self.tail` equality is checked above.
59 unsafe { Some(self.ring.get_unchecked(tail).assume_init_ref()) }
63 fn size_hint(&self) -> (usize, Option
<usize>) {
64 let len
= count(self.tail
, self.head
, self.ring
.len());
68 fn fold
<Acc
, F
>(self, mut accum
: Acc
, mut f
: F
) -> Acc
70 F
: FnMut(Acc
, Self::Item
) -> Acc
,
72 let (front
, back
) = RingSlices
::ring_slices(self.ring
, self.head
, self.tail
);
74 // - `self.head` and `self.tail` in a ring buffer are always valid indices.
75 // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
77 accum
= MaybeUninit
::slice_assume_init_ref(front
).iter().fold(accum
, &mut f
);
78 MaybeUninit
::slice_assume_init_ref(back
).iter().fold(accum
, &mut f
)
82 fn try_fold
<B
, F
, R
>(&mut self, init
: B
, mut f
: F
) -> R
85 F
: FnMut(B
, Self::Item
) -> R
,
88 let (mut iter
, final_res
);
89 if self.tail
<= self.head
{
90 // Safety: single slice self.ring[self.tail..self.head] is initialized.
91 iter
= unsafe { MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]) }
93 final_res
= iter
.try_fold(init
, &mut f
);
95 // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
96 let (front
, back
) = self.ring
.split_at(self.tail
);
98 let mut back_iter
= unsafe { MaybeUninit::slice_assume_init_ref(back).iter() }
;
99 let res
= back_iter
.try_fold(init
, &mut f
);
100 let len
= self.ring
.len();
101 self.tail
= (self.ring
.len() - back_iter
.len()) & (len
- 1);
102 iter
= unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() }
;
103 final_res
= iter
.try_fold(res?
, &mut f
);
105 self.tail
= self.head
- iter
.len();
109 fn nth(&mut self, n
: usize) -> Option
<Self::Item
> {
110 if n
>= count(self.tail
, self.head
, self.ring
.len()) {
111 self.tail
= self.head
;
114 self.tail
= wrap_index(self.tail
.wrapping_add(n
), self.ring
.len());
120 fn last(mut self) -> Option
<&'a T
> {
126 unsafe fn __iterator_get_unchecked(&mut self, idx
: usize) -> Self::Item
{
127 // Safety: The TrustedRandomAccess contract requires that callers only pass an index
128 // that is in bounds.
130 let idx
= wrap_index(self.tail
.wrapping_add(idx
), self.ring
.len());
131 self.ring
.get_unchecked(idx
).assume_init_ref()
136 #[stable(feature = "rust1", since = "1.0.0")]
137 impl<'a
, T
> DoubleEndedIterator
for Iter
<'a
, T
> {
139 fn next_back(&mut self) -> Option
<&'a T
> {
140 if self.tail
== self.head
{
143 self.head
= wrap_index(self.head
.wrapping_sub(1), self.ring
.len());
145 // - `self.head` in a ring buffer is always a valid index.
146 // - `self.head` and `self.tail` equality is checked above.
147 unsafe { Some(self.ring.get_unchecked(self.head).assume_init_ref()) }
150 fn rfold
<Acc
, F
>(self, mut accum
: Acc
, mut f
: F
) -> Acc
152 F
: FnMut(Acc
, Self::Item
) -> Acc
,
154 let (front
, back
) = RingSlices
::ring_slices(self.ring
, self.head
, self.tail
);
156 // - `self.head` and `self.tail` in a ring buffer are always valid indices.
157 // - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
159 accum
= MaybeUninit
::slice_assume_init_ref(back
).iter().rfold(accum
, &mut f
);
160 MaybeUninit
::slice_assume_init_ref(front
).iter().rfold(accum
, &mut f
)
164 fn try_rfold
<B
, F
, R
>(&mut self, init
: B
, mut f
: F
) -> R
167 F
: FnMut(B
, Self::Item
) -> R
,
170 let (mut iter
, final_res
);
171 if self.tail
<= self.head
{
172 // Safety: single slice self.ring[self.tail..self.head] is initialized.
174 MaybeUninit
::slice_assume_init_ref(&self.ring
[self.tail
..self.head
]).iter()
176 final_res
= iter
.try_rfold(init
, &mut f
);
178 // Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
179 let (front
, back
) = self.ring
.split_at(self.tail
);
182 unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() }
;
183 let res
= front_iter
.try_rfold(init
, &mut f
);
184 self.head
= front_iter
.len();
185 iter
= unsafe { MaybeUninit::slice_assume_init_ref(back).iter() }
;
186 final_res
= iter
.try_rfold(res?
, &mut f
);
188 self.head
= self.tail
+ iter
.len();
193 #[stable(feature = "rust1", since = "1.0.0")]
194 impl<T
> ExactSizeIterator
for Iter
<'_
, T
> {
195 fn is_empty(&self) -> bool
{
196 self.head
== self.tail
200 #[stable(feature = "fused", since = "1.26.0")]
201 impl<T
> FusedIterator
for Iter
<'_
, T
> {}
203 #[unstable(feature = "trusted_len", issue = "37572")]
204 unsafe impl<T
> TrustedLen
for Iter
<'_
, T
> {}
207 #[unstable(feature = "trusted_random_access", issue = "none")]
208 unsafe impl<T
> TrustedRandomAccess
for Iter
<'_
, T
> {}
211 #[unstable(feature = "trusted_random_access", issue = "none")]
212 unsafe impl<T
> TrustedRandomAccessNoCoerce
for Iter
<'_
, T
> {
213 const MAY_HAVE_SIDE_EFFECT
: bool
= false;