Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 81 additions & 113 deletions src/libcore/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2261,17 +2261,60 @@ where
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Fuse<I> {
iter: I,
done: bool,
done: <I as fuse_flag::FlagType>::Flag,
}
impl<I> Fuse<I> {
pub(super) fn new(iter: I) -> Fuse<I> {
Fuse { iter, done: false }
Fuse { iter, done: <_>::default() }
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}

mod fuse_flag {
pub trait Flag: Clone + crate::fmt::Debug + Default {
fn is_set(&self) -> bool;
fn set(&mut self);
}

impl Flag for bool {
fn is_set(&self) -> bool {
*self
}

fn set(&mut self) {
*self = true
}
}

#[derive(Clone, Debug, Default)]
pub struct False;

impl Flag for False {
fn is_set(&self) -> bool {
false
}

fn set(&mut self) {
/* intenionally does nothing */
}
}

pub trait FlagType {
type Flag: Flag;
}

impl<I> FlagType for I {
default type Flag = bool;
}

impl<I: super::FusedIterator> FlagType for I {
type Flag = False;
}
}
use fuse_flag::Flag;

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Fuse<I>
where
Expand All @@ -2280,64 +2323,68 @@ where
type Item = <I as Iterator>::Item;

#[inline]
default fn next(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
fn next(&mut self) -> Option<<I as Iterator>::Item> {
if self.done.is_set() {
None
} else {
let next = self.iter.next();
self.done = next.is_none();
if next.is_none() {
self.done.set();
}
next
}
}

#[inline]
default fn nth(&mut self, n: usize) -> Option<I::Item> {
if self.done {
fn nth(&mut self, n: usize) -> Option<I::Item> {
if self.done.is_set() {
None
} else {
let nth = self.iter.nth(n);
self.done = nth.is_none();
if nth.is_none() {
self.done.set();
}
nth
}
}

#[inline]
default fn last(self) -> Option<I::Item> {
if self.done { None } else { self.iter.last() }
fn last(self) -> Option<I::Item> {
if self.done.is_set() { None } else { self.iter.last() }
}

#[inline]
default fn count(self) -> usize {
if self.done { 0 } else { self.iter.count() }
fn count(self) -> usize {
if self.done.is_set() { 0 } else { self.iter.count() }
}

#[inline]
default fn size_hint(&self) -> (usize, Option<usize>) {
if self.done { (0, Some(0)) } else { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) {
if self.done.is_set() { (0, Some(0)) } else { self.iter.size_hint() }
}

#[inline]
default fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
if self.done {
if self.done.is_set() {
Try::from_ok(init)
} else {
let acc = self.iter.try_fold(init, fold)?;
self.done = true;
self.done.set();
Try::from_ok(acc)
}
}

#[inline]
default fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
if self.done { init } else { self.iter.fold(init, fold) }
if self.done.is_set() { init } else { self.iter.fold(init, fold) }
}
}

Expand All @@ -2347,49 +2394,53 @@ where
I: DoubleEndedIterator,
{
#[inline]
default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
if self.done.is_set() {
None
} else {
let next = self.iter.next_back();
self.done = next.is_none();
if next.is_none() {
self.done.set();
}
next
}
}

#[inline]
default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
if self.done {
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
if self.done.is_set() {
None
} else {
let nth = self.iter.nth_back(n);
self.done = nth.is_none();
if nth.is_none() {
self.done.set();
}
nth
}
}

#[inline]
default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
if self.done {
if self.done.is_set() {
Try::from_ok(init)
} else {
let acc = self.iter.try_rfold(init, fold)?;
self.done = true;
self.done.set();
Try::from_ok(acc)
}
}

#[inline]
default fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
if self.done { init } else { self.iter.rfold(init, fold) }
if self.done.is_set() { init } else { self.iter.rfold(init, fold) }
}
}

Expand All @@ -2406,89 +2457,6 @@ where
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> Iterator for Fuse<I>
where
I: FusedIterator,
{
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next()
}

#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
self.iter.nth(n)
}

#[inline]
fn last(self) -> Option<I::Item> {
self.iter.last()
}

#[inline]
fn count(self) -> usize {
self.iter.count()
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

#[inline]
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_fold(init, fold)
}

#[inline]
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(init, fold)
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> DoubleEndedIterator for Fuse<I>
where
I: DoubleEndedIterator + FusedIterator,
{
#[inline]
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
self.iter.next_back()
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
self.iter.nth_back(n)
}

#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
self.iter.try_rfold(init, fold)
}

#[inline]
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
where
Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.rfold(init, fold)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I>
where
Expand Down