1 | use crate::num::NonZeroUsize; |
2 | use crate::ops::{NeverShortCircuit, Try}; |
3 | |
4 | /// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics. |
5 | /// |
6 | /// Ideally this will no longer be required, eventually, but as can be seen in |
7 | /// the benchmarks (as of Feb 2022 at least) `by_ref` can have performance cost. |
8 | #[unstable (feature = "std_internals" , issue = "none" )] |
9 | #[derive (Debug)] |
10 | pub struct ByRefSized<'a, I>(pub &'a mut I); |
11 | |
12 | // The following implementations use UFCS-style, rather than trusting autoderef, |
13 | // to avoid accidentally calling the `&mut Iterator` implementations. |
14 | |
15 | #[unstable (feature = "std_internals" , issue = "none" )] |
16 | impl<I: Iterator> Iterator for ByRefSized<'_, I> { |
17 | type Item = I::Item; |
18 | |
19 | #[inline ] |
20 | fn next(&mut self) -> Option<Self::Item> { |
21 | I::next(self.0) |
22 | } |
23 | |
24 | #[inline ] |
25 | fn size_hint(&self) -> (usize, Option<usize>) { |
26 | I::size_hint(self.0) |
27 | } |
28 | |
29 | #[inline ] |
30 | fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { |
31 | I::advance_by(self.0, n) |
32 | } |
33 | |
34 | #[inline ] |
35 | fn nth(&mut self, n: usize) -> Option<Self::Item> { |
36 | I::nth(self.0, n) |
37 | } |
38 | |
39 | #[inline ] |
40 | fn fold<B, F>(self, init: B, f: F) -> B |
41 | where |
42 | F: FnMut(B, Self::Item) -> B, |
43 | { |
44 | // `fold` needs ownership, so this can't forward directly. |
45 | I::try_fold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0 |
46 | } |
47 | |
48 | #[inline ] |
49 | fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R |
50 | where |
51 | F: FnMut(B, Self::Item) -> R, |
52 | R: Try<Output = B>, |
53 | { |
54 | I::try_fold(self.0, init, f) |
55 | } |
56 | } |
57 | |
58 | #[unstable (feature = "std_internals" , issue = "none" )] |
59 | impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> { |
60 | #[inline ] |
61 | fn next_back(&mut self) -> Option<Self::Item> { |
62 | I::next_back(self.0) |
63 | } |
64 | |
65 | #[inline ] |
66 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { |
67 | I::advance_back_by(self.0, n) |
68 | } |
69 | |
70 | #[inline ] |
71 | fn nth_back(&mut self, n: usize) -> Option<Self::Item> { |
72 | I::nth_back(self.0, n) |
73 | } |
74 | |
75 | #[inline ] |
76 | fn rfold<B, F>(self, init: B, f: F) -> B |
77 | where |
78 | F: FnMut(B, Self::Item) -> B, |
79 | { |
80 | // `rfold` needs ownership, so this can't forward directly. |
81 | I::try_rfold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0 |
82 | } |
83 | |
84 | #[inline ] |
85 | fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R |
86 | where |
87 | F: FnMut(B, Self::Item) -> R, |
88 | R: Try<Output = B>, |
89 | { |
90 | I::try_rfold(self.0, init, f) |
91 | } |
92 | } |
93 | |