Skip to main content

alloc/boxed/
iter.rs

1use core::async_iter::AsyncIterator;
2use core::iter::{FusedIterator, TrustedLen};
3use core::num::NonZero;
4use core::pin::Pin;
5use core::slice;
6use core::task::{Context, Poll};
7
8use crate::alloc::{Allocator, Global};
9#[cfg(not(no_global_oom_handling))]
10use crate::borrow::Cow;
11use crate::boxed::Box;
12#[cfg(not(no_global_oom_handling))]
13use crate::string::String;
14#[cfg(not(no_global_oom_handling))]
15use crate::vec::Vec;
16use crate::{fmt, vec};
17
18#[stable(feature = "rust1", since = "1.0.0")]
19impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> {
20    type Item = I::Item;
21    fn next(&mut self) -> Option<I::Item> {
22        (**self).next()
23    }
24    fn size_hint(&self) -> (usize, Option<usize>) {
25        (**self).size_hint()
26    }
27    fn nth(&mut self, n: usize) -> Option<I::Item> {
28        (**self).nth(n)
29    }
30    fn last(self) -> Option<I::Item> {
31        BoxIter::last(self)
32    }
33}
34
35trait BoxIter {
36    type Item;
37    fn last(self) -> Option<Self::Item>;
38}
39
40impl<I: Iterator + ?Sized, A: Allocator> BoxIter for Box<I, A> {
41    type Item = I::Item;
42    default fn last(self) -> Option<I::Item> {
43        #[inline]
44        fn some<T>(_: Option<T>, x: T) -> Option<T> {
45            Some(x)
46        }
47
48        self.fold(None, some)
49    }
50}
51
52/// Specialization for sized `I`s that uses `I`s implementation of `last()`
53/// instead of the default.
54#[stable(feature = "rust1", since = "1.0.0")]
55impl<I: Iterator, A: Allocator> BoxIter for Box<I, A> {
56    fn last(self) -> Option<I::Item> {
57        (*self).last()
58    }
59}
60
61#[stable(feature = "rust1", since = "1.0.0")]
62impl<I: DoubleEndedIterator + ?Sized, A: Allocator> DoubleEndedIterator for Box<I, A> {
63    fn next_back(&mut self) -> Option<I::Item> {
64        (**self).next_back()
65    }
66    fn nth_back(&mut self, n: usize) -> Option<I::Item> {
67        (**self).nth_back(n)
68    }
69}
70#[stable(feature = "rust1", since = "1.0.0")]
71impl<I: ExactSizeIterator + ?Sized, A: Allocator> ExactSizeIterator for Box<I, A> {
72    fn len(&self) -> usize {
73        (**self).len()
74    }
75    fn is_empty(&self) -> bool {
76        (**self).is_empty()
77    }
78}
79
80#[stable(feature = "fused", since = "1.26.0")]
81impl<I: FusedIterator + ?Sized, A: Allocator> FusedIterator for Box<I, A> {}
82
83#[unstable(feature = "async_iterator", issue = "79024")]
84impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
85    type Item = S::Item;
86
87    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
88        Pin::new(&mut **self).poll_next(cx)
89    }
90
91    fn size_hint(&self) -> (usize, Option<usize>) {
92        (**self).size_hint()
93    }
94}
95
96/// This implementation is required to make sure that the `Box<[I]>: IntoIterator`
97/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
98#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
99impl<I, A: Allocator> !Iterator for Box<[I], A> {}
100
101/// This implementation is required to make sure that the `&Box<[I]>: IntoIterator`
102/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
103#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
104impl<'a, I, A: Allocator> !Iterator for &'a Box<[I], A> {}
105
106/// This implementation is required to make sure that the `&mut Box<[I]>: IntoIterator`
107/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
108#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
109impl<'a, I, A: Allocator> !Iterator for &'a mut Box<[I], A> {}
110
111// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
112// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
113// so those calls will still resolve to the slice implementation, by reference.
114#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
115impl<I, A: Allocator> IntoIterator for Box<[I], A> {
116    type IntoIter = vec::IntoIter<I, A>;
117    type Item = I;
118    fn into_iter(self) -> vec::IntoIter<I, A> {
119        self.into_vec().into_iter()
120    }
121}
122
123#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
124impl<'a, I, A: Allocator> IntoIterator for &'a Box<[I], A> {
125    type IntoIter = slice::Iter<'a, I>;
126    type Item = &'a I;
127    fn into_iter(self) -> slice::Iter<'a, I> {
128        self.iter()
129    }
130}
131
132#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
133impl<'a, I, A: Allocator> IntoIterator for &'a mut Box<[I], A> {
134    type IntoIter = slice::IterMut<'a, I>;
135    type Item = &'a mut I;
136    fn into_iter(self) -> slice::IterMut<'a, I> {
137        self.iter_mut()
138    }
139}
140
141#[cfg(not(no_global_oom_handling))]
142#[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
143impl<I> FromIterator<I> for Box<[I]> {
144    fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
145        iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
146    }
147}
148
149#[cfg(not(no_global_oom_handling))]
150#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
151impl FromIterator<char> for Box<str> {
152    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
153        String::from_iter(iter).into_boxed_str()
154    }
155}
156
157#[cfg(not(no_global_oom_handling))]
158#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
159impl<'a> FromIterator<&'a char> for Box<str> {
160    fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
161        String::from_iter(iter).into_boxed_str()
162    }
163}
164
165#[cfg(not(no_global_oom_handling))]
166#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
167impl<'a> FromIterator<&'a str> for Box<str> {
168    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
169        String::from_iter(iter).into_boxed_str()
170    }
171}
172
173#[cfg(not(no_global_oom_handling))]
174#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
175impl FromIterator<String> for Box<str> {
176    fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
177        String::from_iter(iter).into_boxed_str()
178    }
179}
180
181#[cfg(not(no_global_oom_handling))]
182#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
183impl<A: Allocator> FromIterator<Box<str, A>> for Box<str> {
184    fn from_iter<T: IntoIterator<Item = Box<str, A>>>(iter: T) -> Self {
185        String::from_iter(iter).into_boxed_str()
186    }
187}
188
189#[cfg(not(no_global_oom_handling))]
190#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
191impl<'a> FromIterator<Cow<'a, str>> for Box<str> {
192    fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
193        String::from_iter(iter).into_boxed_str()
194    }
195}
196
197/// This implementation is required to make sure that the `Box<[I; N]>: IntoIterator`
198/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
199#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
200impl<I, const N: usize, A: Allocator> !Iterator for Box<[I; N], A> {}
201
202/// This implementation is required to make sure that the `&Box<[I; N]>: IntoIterator`
203/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
204#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
205impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a Box<[I; N], A> {}
206
207/// This implementation is required to make sure that the `&mut Box<[I; N]>: IntoIterator`
208/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
209#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
210impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a mut Box<[I; N], A> {}
211
212#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
213impl<'a, T, const N: usize, A: Allocator> IntoIterator for &'a Box<[T; N], A> {
214    type IntoIter = slice::Iter<'a, T>;
215    type Item = &'a T;
216    fn into_iter(self) -> slice::Iter<'a, T> {
217        self.iter()
218    }
219}
220
221#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
222impl<'a, T, const N: usize, A: Allocator> IntoIterator for &'a mut Box<[T; N], A> {
223    type IntoIter = slice::IterMut<'a, T>;
224    type Item = &'a mut T;
225    fn into_iter(self) -> slice::IterMut<'a, T> {
226        self.iter_mut()
227    }
228}
229
230/// A by-value `Box<[T; N]>` iterator.
231#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
232#[rustc_insignificant_dtor]
233pub struct BoxedArrayIntoIter<T, const N: usize, A: Allocator = Global> {
234    // FIXME: make a more efficient implementation (without the need to store capacity)
235    inner: vec::IntoIter<T, A>,
236}
237
238impl<T, const N: usize, A: Allocator> BoxedArrayIntoIter<T, N, A> {
239    /// Returns an immutable slice of all elements that have not been yielded
240    /// yet.
241    #[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
242    pub fn as_slice(&self) -> &[T] {
243        self.inner.as_slice()
244    }
245
246    /// Returns a mutable slice of all elements that have not been yielded yet.
247    #[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
248    pub fn as_mut_slice(&mut self) -> &mut [T] {
249        self.inner.as_mut_slice()
250    }
251}
252
253#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
254impl<T, const N: usize, A: Allocator> Iterator for BoxedArrayIntoIter<T, N, A> {
255    type Item = T;
256    fn next(&mut self) -> Option<Self::Item> {
257        self.inner.next()
258    }
259
260    fn size_hint(&self) -> (usize, Option<usize>) {
261        let len = self.len();
262        (len, Some(len))
263    }
264
265    #[inline]
266    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
267    where
268        Fold: FnMut(Acc, Self::Item) -> Acc,
269    {
270        self.inner.fold(init, fold)
271    }
272
273    fn count(self) -> usize {
274        self.len()
275    }
276
277    fn last(mut self) -> Option<Self::Item> {
278        self.next_back()
279    }
280
281    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
282        self.inner.advance_by(n)
283    }
284}
285
286#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
287impl<T, const N: usize, A: Allocator> DoubleEndedIterator for BoxedArrayIntoIter<T, N, A> {
288    fn next_back(&mut self) -> Option<Self::Item> {
289        self.inner.next_back()
290    }
291
292    #[inline]
293    fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
294    where
295        Fold: FnMut(Acc, Self::Item) -> Acc,
296    {
297        self.inner.rfold(init, rfold)
298    }
299
300    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
301        self.inner.advance_back_by(n)
302    }
303}
304
305#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
306impl<T, const N: usize, A: Allocator> ExactSizeIterator for BoxedArrayIntoIter<T, N, A> {
307    fn len(&self) -> usize {
308        self.inner.len()
309    }
310
311    fn is_empty(&self) -> bool {
312        self.inner.is_empty()
313    }
314}
315
316#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
317impl<T, const N: usize, A: Allocator> FusedIterator for BoxedArrayIntoIter<T, N, A> {}
318
319#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
320unsafe impl<T, const N: usize, A: Allocator> TrustedLen for BoxedArrayIntoIter<T, N, A> {}
321
322#[cfg(not(no_global_oom_handling))]
323#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
324impl<T: Clone, const N: usize, A: Clone + Allocator> Clone for BoxedArrayIntoIter<T, N, A> {
325    fn clone(&self) -> Self {
326        Self { inner: self.inner.clone() }
327    }
328}
329
330#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
331impl<T: fmt::Debug, const N: usize, A: Allocator> fmt::Debug for BoxedArrayIntoIter<T, N, A> {
332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333        // Only print the elements that were not yielded yet: we cannot
334        // access the yielded elements anymore.
335        f.debug_tuple("BoxedArrayIntoIter").field(&self.as_slice()).finish()
336    }
337}
338
339#[stable(feature = "boxed_array_value_iter", since = "CURRENT_RUSTC_VERSION")]
340impl<T, const N: usize, A: Allocator> IntoIterator for Box<[T; N], A> {
341    type IntoIter = BoxedArrayIntoIter<T, N, A>;
342    type Item = T;
343    fn into_iter(self) -> BoxedArrayIntoIter<T, N, A> {
344        BoxedArrayIntoIter { inner: (self as Box<[T], A>).into_vec().into_iter() }
345    }
346}