Skip to content

Commit acc5aec

Browse files
authored
Unrolled build for #153097
Rollup merge of #153097 - cuviper:expand-into_flat_iter, r=joboet Expand `OptionFlatten`'s iterator methods If someone considers moving from `option.into_iter().flatten()` to `option.into_flat_iter()`, it may be important for performance that this iterator "specializes" methods the same way `Flatten` does, especially forwarding to underlying `fold`, etc.
2 parents 8b95a26 + 8c92dc8 commit acc5aec

1 file changed

Lines changed: 97 additions & 3 deletions

File tree

library/core/src/option.rs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@
581581
use crate::clone::TrivialClone;
582582
use crate::iter::{self, FusedIterator, TrustedLen};
583583
use crate::marker::Destruct;
584+
use crate::num::NonZero;
584585
use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try};
585586
use crate::panicking::{panic, panic_display};
586587
use crate::pin::Pin;
@@ -2666,18 +2667,111 @@ impl<A: Iterator> Iterator for OptionFlatten<A> {
26662667
type Item = A::Item;
26672668

26682669
fn next(&mut self) -> Option<Self::Item> {
2669-
self.iter.as_mut()?.next()
2670+
match &mut self.iter {
2671+
Some(iter) => iter.next(),
2672+
None => None,
2673+
}
26702674
}
26712675

26722676
fn size_hint(&self) -> (usize, Option<usize>) {
2673-
self.iter.as_ref().map(|i| i.size_hint()).unwrap_or((0, Some(0)))
2677+
match &self.iter {
2678+
Some(iter) => iter.size_hint(),
2679+
None => (0, Some(0)),
2680+
}
2681+
}
2682+
2683+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2684+
match &mut self.iter {
2685+
Some(iter) => iter.advance_by(n),
2686+
None => NonZero::new(n).map_or(Ok(()), Err),
2687+
}
2688+
}
2689+
2690+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
2691+
match &mut self.iter {
2692+
Some(iter) => iter.nth(n),
2693+
None => None,
2694+
}
2695+
}
2696+
2697+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2698+
where
2699+
Fold: FnMut(Acc, Self::Item) -> Acc,
2700+
{
2701+
match self.iter {
2702+
Some(iter) => iter.fold(init, fold),
2703+
None => init,
2704+
}
2705+
}
2706+
2707+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2708+
where
2709+
Fold: FnMut(Acc, Self::Item) -> R,
2710+
R: Try<Output = Acc>,
2711+
{
2712+
match &mut self.iter {
2713+
Some(iter) => iter.try_fold(init, fold),
2714+
None => try { init },
2715+
}
2716+
}
2717+
2718+
fn count(self) -> usize {
2719+
match self.iter {
2720+
Some(iter) => iter.count(),
2721+
None => 0,
2722+
}
2723+
}
2724+
2725+
fn last(self) -> Option<Self::Item> {
2726+
match self.iter {
2727+
Some(iter) => iter.last(),
2728+
None => None,
2729+
}
26742730
}
26752731
}
26762732

26772733
#[unstable(feature = "option_into_flat_iter", issue = "148441")]
26782734
impl<A: DoubleEndedIterator> DoubleEndedIterator for OptionFlatten<A> {
26792735
fn next_back(&mut self) -> Option<Self::Item> {
2680-
self.iter.as_mut()?.next_back()
2736+
match &mut self.iter {
2737+
Some(iter) => iter.next_back(),
2738+
None => None,
2739+
}
2740+
}
2741+
2742+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2743+
match &mut self.iter {
2744+
Some(iter) => iter.advance_back_by(n),
2745+
None => NonZero::new(n).map_or(Ok(()), Err),
2746+
}
2747+
}
2748+
2749+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2750+
match &mut self.iter {
2751+
Some(iter) => iter.nth_back(n),
2752+
None => None,
2753+
}
2754+
}
2755+
2756+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2757+
where
2758+
Fold: FnMut(Acc, Self::Item) -> Acc,
2759+
{
2760+
match self.iter {
2761+
Some(iter) => iter.rfold(init, fold),
2762+
None => init,
2763+
}
2764+
}
2765+
2766+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2767+
where
2768+
Fold: FnMut(Acc, Self::Item) -> R,
2769+
R: Try<Output = Acc>,
2770+
{
2771+
match &mut self.iter {
2772+
Some(iter) => iter.try_rfold(init, fold),
2773+
None => try { init },
2774+
}
26812775
}
26822776
}
26832777

0 commit comments

Comments
 (0)