Skip to content

Commit 8c92dc8

Browse files
committed
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.
1 parent 3f98535 commit 8c92dc8

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
@@ -584,6 +584,7 @@
584584
use crate::clone::TrivialClone;
585585
use crate::iter::{self, FusedIterator, TrustedLen};
586586
use crate::marker::Destruct;
587+
use crate::num::NonZero;
587588
use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try};
588589
use crate::panicking::{panic, panic_display};
589590
use crate::pin::Pin;
@@ -2651,18 +2652,111 @@ impl<A: Iterator> Iterator for OptionFlatten<A> {
26512652
type Item = A::Item;
26522653

26532654
fn next(&mut self) -> Option<Self::Item> {
2654-
self.iter.as_mut()?.next()
2655+
match &mut self.iter {
2656+
Some(iter) => iter.next(),
2657+
None => None,
2658+
}
26552659
}
26562660

26572661
fn size_hint(&self) -> (usize, Option<usize>) {
2658-
self.iter.as_ref().map(|i| i.size_hint()).unwrap_or((0, Some(0)))
2662+
match &self.iter {
2663+
Some(iter) => iter.size_hint(),
2664+
None => (0, Some(0)),
2665+
}
2666+
}
2667+
2668+
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2669+
match &mut self.iter {
2670+
Some(iter) => iter.advance_by(n),
2671+
None => NonZero::new(n).map_or(Ok(()), Err),
2672+
}
2673+
}
2674+
2675+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
2676+
match &mut self.iter {
2677+
Some(iter) => iter.nth(n),
2678+
None => None,
2679+
}
2680+
}
2681+
2682+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2683+
where
2684+
Fold: FnMut(Acc, Self::Item) -> Acc,
2685+
{
2686+
match self.iter {
2687+
Some(iter) => iter.fold(init, fold),
2688+
None => init,
2689+
}
2690+
}
2691+
2692+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2693+
where
2694+
Fold: FnMut(Acc, Self::Item) -> R,
2695+
R: Try<Output = Acc>,
2696+
{
2697+
match &mut self.iter {
2698+
Some(iter) => iter.try_fold(init, fold),
2699+
None => try { init },
2700+
}
2701+
}
2702+
2703+
fn count(self) -> usize {
2704+
match self.iter {
2705+
Some(iter) => iter.count(),
2706+
None => 0,
2707+
}
2708+
}
2709+
2710+
fn last(self) -> Option<Self::Item> {
2711+
match self.iter {
2712+
Some(iter) => iter.last(),
2713+
None => None,
2714+
}
26592715
}
26602716
}
26612717

26622718
#[unstable(feature = "option_into_flat_iter", issue = "148441")]
26632719
impl<A: DoubleEndedIterator> DoubleEndedIterator for OptionFlatten<A> {
26642720
fn next_back(&mut self) -> Option<Self::Item> {
2665-
self.iter.as_mut()?.next_back()
2721+
match &mut self.iter {
2722+
Some(iter) => iter.next_back(),
2723+
None => None,
2724+
}
2725+
}
2726+
2727+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2728+
match &mut self.iter {
2729+
Some(iter) => iter.advance_back_by(n),
2730+
None => NonZero::new(n).map_or(Ok(()), Err),
2731+
}
2732+
}
2733+
2734+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2735+
match &mut self.iter {
2736+
Some(iter) => iter.nth_back(n),
2737+
None => None,
2738+
}
2739+
}
2740+
2741+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2742+
where
2743+
Fold: FnMut(Acc, Self::Item) -> Acc,
2744+
{
2745+
match self.iter {
2746+
Some(iter) => iter.rfold(init, fold),
2747+
None => init,
2748+
}
2749+
}
2750+
2751+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2752+
where
2753+
Fold: FnMut(Acc, Self::Item) -> R,
2754+
R: Try<Output = Acc>,
2755+
{
2756+
match &mut self.iter {
2757+
Some(iter) => iter.try_rfold(init, fold),
2758+
None => try { init },
2759+
}
26662760
}
26672761
}
26682762

0 commit comments

Comments
 (0)