From f0f0ae99384b6385f014075e8ce9c99d33658881 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 11 Apr 2016 22:34:04 -0400 Subject: [PATCH 1/2] Add a FusedIterator trait. This trait can be used to avoid the overhead of a fuse wrapper (which is pretty high). --- src/libcore/iter.rs | 64 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index b4378a5fec58d..a2043bb49d321 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -4077,6 +4077,17 @@ impl DoubleEndedIterator for FlatMap wher } } +/// An iterator that always continues to yield `None` when exhausted. +/// +/// Calling next on a fused iterator that has returned `None` once is guaranteed +/// to return `None` again. This trait is should be implemented by all iterators +/// that behave this way because it allows for some significant optimizations. +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +pub trait FusedIterator: Iterator {} + +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {} + /// An iterator that yields `None` forever after the underlying iterator /// yields `None` once. /// @@ -4093,12 +4104,15 @@ pub struct Fuse { done: bool } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Fuse where I: Iterator {} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Fuse where I: Iterator { type Item = ::Item; #[inline] - fn next(&mut self) -> Option<::Item> { + default fn next(&mut self) -> Option<::Item> { if self.done { None } else { @@ -4109,7 +4123,7 @@ impl Iterator for Fuse where I: Iterator { } #[inline] - fn nth(&mut self, n: usize) -> Option { + default fn nth(&mut self, n: usize) -> Option { if self.done { None } else { @@ -4120,7 +4134,7 @@ impl Iterator for Fuse where I: Iterator { } #[inline] - fn last(self) -> Option { + default fn last(self) -> Option { if self.done { None } else { @@ -4129,7 +4143,7 @@ impl Iterator for Fuse where I: Iterator { } #[inline] - fn count(self) -> usize { + default fn count(self) -> usize { if self.done { 0 } else { @@ -4138,7 +4152,7 @@ impl Iterator for Fuse where I: Iterator { } #[inline] - fn size_hint(&self) -> (usize, Option) { + default fn size_hint(&self) -> (usize, Option) { if self.done { (0, Some(0)) } else { @@ -4150,7 +4164,7 @@ impl Iterator for Fuse where I: Iterator { #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { #[inline] - fn next_back(&mut self) -> Option<::Item> { + default fn next_back(&mut self) -> Option<::Item> { if self.done { None } else { @@ -4164,6 +4178,44 @@ impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Fuse where I: ExactSizeIterator {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl Iterator for Fuse where I: FusedIterator { + #[inline] + fn next(&mut self) -> Option<::Item> { + self.iter.next() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.iter.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.iter.last() + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl DoubleEndedIterator for Fuse + where I: DoubleEndedIterator + FusedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<::Item> { + self.iter.next_back() + } +} + /// An iterator that calls a function with a reference to each element before /// yielding it. /// From 2c6d008246336964926d2fa2b518e019a33e40ee Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 15 Apr 2016 13:17:18 -0400 Subject: [PATCH 2/2] Implement FusedIterator for core. --- src/libcore/char.rs | 14 +++++- src/libcore/iter.rs | 110 +++++++++++++++++++++++++++++++++++++++++ src/libcore/option.rs | 11 ++++- src/libcore/result.rs | 18 ++++++- src/libcore/slice.rs | 26 ++++++++++ src/libcore/str/mod.rs | 26 +++++++++- 6 files changed, 201 insertions(+), 4 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index b2b1dc5178e2e..086ba8f63e92c 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -15,7 +15,7 @@ #![allow(non_snake_case)] #![stable(feature = "core_char", since = "1.2.0")] -use iter::Iterator; +use iter::{Iterator, FusedIterator}; use mem::transmute; use option::Option::{None, Some}; use option::Option; @@ -461,6 +461,9 @@ impl Iterator for EscapeUnicode { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for EscapeUnicode {} + /// An iterator that yields the literal escape code of a `char`. /// /// This `struct` is created by the [`escape_default()`] method on [`char`]. See @@ -556,6 +559,9 @@ impl Iterator for EscapeDefault { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for EscapeDefault {} + /// An iterator over `u8` entries represending the UTF-8 encoding of a `char` /// value. /// @@ -594,6 +600,9 @@ impl Iterator for EncodeUtf8 { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for EncodeUtf8 {} + /// An iterator over `u16` entries represending the UTF-16 encoding of a `char` /// value. /// @@ -632,3 +641,6 @@ impl Iterator for EncodeUtf16 { self.as_slice().iter().size_hint() } } + +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for EncodeUtf16 {} diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index a2043bb49d321..e6902131c85a6 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2953,6 +2953,9 @@ impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { fn next_back(&mut self) -> Option<::Item> { self.iter.next() } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Rev where I: DoubleEndedIterator + FusedIterator {} + /// An iterator that clones the elements of an underlying iterator. /// /// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its @@ -2996,6 +2999,11 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned where I: ExactSizeIterator, T: Clone {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, I, T: 'a> FusedIterator for Cloned + where I: FusedIterator, T: Clone +{} + /// An iterator that repeats endlessly. /// /// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its @@ -3034,6 +3042,11 @@ impl Iterator for Cycle where I: Clone + Iterator { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Cycle + where I: Clone + FusedIterator +{} + /// An iterator that strings two iterators together. /// /// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its @@ -3178,6 +3191,12 @@ impl DoubleEndedIterator for Chain where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Chain + where A: Iterator, + B: FusedIterator, +{} + /// An iterator that iterates two other iterators simultaneously. /// /// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its @@ -3250,6 +3269,12 @@ impl DoubleEndedIterator for Zip where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Zip + where A: FusedIterator, + B: FusedIterator, +{} + /// An iterator that maps the values of `iter` with `f`. /// /// This `struct` is created by the [`map()`] method on [`Iterator`]. See its @@ -3342,6 +3367,9 @@ impl DoubleEndedIterator for Map where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Map where F: FnMut(I::Item) -> B {} + /// An iterator that filters the elements of `iter` with `predicate`. /// /// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its @@ -3402,6 +3430,11 @@ impl DoubleEndedIterator for Filter } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Filter + where P: FnMut(&I::Item) -> bool, +{} + /// An iterator that uses `f` to both filter and map elements from `iter`. /// /// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its @@ -3464,6 +3497,11 @@ impl DoubleEndedIterator for FilterMap } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for FilterMap + where F: FnMut(I::Item) -> Option, +{} + /// An iterator that yields the current count and the element during iteration. /// /// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its @@ -3537,6 +3575,9 @@ impl DoubleEndedIterator for Enumerate where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Enumerate where I: FusedIterator {} + /// An iterator with a `peek()` that returns an optional reference to the next /// element. /// @@ -3688,6 +3729,9 @@ impl Peekable { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Peekable where I: FusedIterator {} + /// An iterator that rejects elements while `predicate` is true. /// /// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its @@ -3738,6 +3782,12 @@ impl Iterator for SkipWhile } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for SkipWhile + where I: FusedIterator, + P: FnMut(&I::Item) -> bool, +{} + /// An iterator that only accepts elements while `predicate` is true. /// /// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its @@ -3793,6 +3843,12 @@ impl Iterator for TakeWhile } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for TakeWhile + where I: FusedIterator, + P: FnMut(&I::Item) -> bool, +{} + /// An iterator that skips over `n` elements of `iter`. /// /// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its @@ -3884,6 +3940,9 @@ impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSize } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Skip where I: FusedIterator {} + /// An iterator that only iterates over the first `n` iterations of `iter`. /// /// This `struct` is created by the [`take()`] method on [`Iterator`]. See its @@ -3945,6 +4004,8 @@ impl Iterator for Take where I: Iterator{ #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Take where I: ExactSizeIterator {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Take where I: FusedIterator {} /// An iterator to maintain state while iterating another iterator. /// @@ -3991,6 +4052,12 @@ impl Iterator for Scan where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Scan + where I: FusedIterator, + F: FnMut(&mut St, I::Item) -> Option, +{} + /// An iterator that maps each element to an iterator, and yields the elements /// of the produced iterators. /// @@ -4077,6 +4144,13 @@ impl DoubleEndedIterator for FlatMap wher } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for FlatMap + where I: FusedIterator, + U: IntoIterator, + F: FnMut(I::Item) -> U, +{} + /// An iterator that always continues to yield `None` when exhausted. /// /// Calling next on a fused iterator that has returned `None` once is guaranteed @@ -4279,6 +4353,11 @@ impl DoubleEndedIterator for Inspect } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Inspect + where F: FnMut(&I::Item), +{} + /// Objects that can be stepped over in both directions. /// /// The `steps_between` function provides a way to efficiently compare @@ -4633,6 +4712,9 @@ impl Iterator for StepBy> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for StepBy> {} + macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] @@ -4691,6 +4773,13 @@ impl DoubleEndedIterator for ops::Range where } } +// Obviously, this assumes that self.start < self.end always returns the same +// answer. +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for ops::Range where + for<'a> &'a A: Add<&'a A, Output = A> +{} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for ops::RangeFrom where for<'a> &'a A: Add<&'a A, Output = A> @@ -4705,6 +4794,13 @@ impl Iterator for ops::RangeFrom where } } +// Fused because it *never* returns `None` +#[stable(feature = "rust1", since = "1.0.0")] +impl FusedIterator for ops::RangeFrom where + for<'a> &'a A: Add<&'a A, Output = A> +{} + + #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] impl Iterator for ops::RangeInclusive where for<'a> &'a A: Add<&'a A, Output = A> @@ -4806,6 +4902,11 @@ impl DoubleEndedIterator for ops::RangeInclusive where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for ops::RangeInclusive where + for<'a> &'a A: Add<&'a A, Output = A> +{} + /// An iterator that repeats an element endlessly. /// /// This `struct` is created by the [`repeat()`] function. See its documentation for more. @@ -4833,6 +4934,9 @@ impl DoubleEndedIterator for Repeat { fn next_back(&mut self) -> Option { Some(self.element.clone()) } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Repeat {} + /// Creates a new iterator that endlessly repeats a single element. /// /// The `repeat()` function repeats a single value over and over and over and @@ -4927,6 +5031,9 @@ impl ExactSizeIterator for Empty { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Empty {} + // not #[derive] because that adds a Clone bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] @@ -5002,6 +5109,9 @@ impl ExactSizeIterator for Once { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for Once {} + /// Creates an iterator that yields an element exactly once. /// /// This is commonly used to adapt a single value into a [`chain()`] of other diff --git a/src/libcore/option.rs b/src/libcore/option.rs index beed2075d0494..ac7444e3dc4be 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -145,7 +145,7 @@ use clone::Clone; use cmp::{Eq, Ord}; use default::Default; use iter::ExactSizeIterator; -use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator}; +use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator, FusedIterator}; use mem; use ops::FnOnce; use result::Result::{Ok, Err}; @@ -814,6 +814,9 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, A> ExactSizeIterator for Iter<'a, A> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, A> FusedIterator for Iter<'a, A> {} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, A> Clone for Iter<'a, A> { fn clone(&self) -> Iter<'a, A> { @@ -845,6 +848,9 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, A> ExactSizeIterator for IterMut<'a, A> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, A> FusedIterator for IterMut<'a, A> {} + /// An iterator over the item contained inside an Option. #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] @@ -869,6 +875,9 @@ impl DoubleEndedIterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for IntoIter {} + ///////////////////////////////////////////////////////////////////////////// // FromIterator ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 4d9f042fddedc..00567c56301e4 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -237,7 +237,14 @@ use self::Result::{Ok, Err}; use clone::Clone; use fmt; -use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator}; +use iter::{ + Iterator, + DoubleEndedIterator, + FromIterator, + ExactSizeIterator, + IntoIterator, + FusedIterator +}; use ops::FnOnce; use option::Option::{self, None, Some}; @@ -866,6 +873,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Iter<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, A> FusedIterator for Iter<'a, A> {} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } } @@ -898,6 +908,9 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, A> FusedIterator for IterMut<'a, A> {} + /// An iterator over the value in a `Ok` variant of a `Result`. #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] @@ -925,6 +938,9 @@ impl DoubleEndedIterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl FusedIterator for IntoIter {} + ///////////////////////////////////////////////////////////////////////////// // FromIterator ///////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 2e91238bff3cc..8515cc2c1b427 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -962,6 +962,9 @@ iterator!{struct Iter -> *const T, &'a T} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Iter<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T> FusedIterator for Iter<'a, T> {} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } @@ -1068,6 +1071,9 @@ iterator!{struct IterMut -> *mut T, &'a mut T} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T> FusedIterator for IterMut<'a, T> {} + /// An internal abstraction over the splitting iterators, so that /// splitn, splitn_mut etc can be implemented once. #[doc(hidden)] @@ -1160,6 +1166,9 @@ impl<'a, T, P> SplitIter for Split<'a, T, P> where P: FnMut(&T) -> bool { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T, P> FusedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool {} + /// An iterator over the subslices of the vector which are separated /// by elements that match `pred`. #[stable(feature = "rust1", since = "1.0.0")] @@ -1250,6 +1259,9 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {} + /// An private iterator over subslices separated by elements that /// match a predicate function, splitting at most a fixed number of /// times. @@ -1366,6 +1378,11 @@ macro_rules! forward_iterator { self.inner.size_hint() } } + + #[unstable(feature = "fused", reason = "recently added", issue = "0")] + impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P> where + P: FnMut(&T) -> bool + {} } } @@ -1464,6 +1481,9 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Windows<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T> FusedIterator for Windows<'a, T> {} + /// An iterator over a slice in (non-overlapping) chunks (`size` elements at a /// time). /// @@ -1567,6 +1587,9 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Chunks<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T> FusedIterator for Chunks<'a, T> {} + /// An iterator over a slice in (non-overlapping) mutable chunks (`size` /// elements at a time). When the slice len is not evenly divided by the chunk /// size, the last slice of the iteration will be the remainder. @@ -1662,6 +1685,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {} +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a, T> FusedIterator for ChunksMut<'a, T> {} + // // Free functions // diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f3c31d59fc467..b648870d75343 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -24,7 +24,7 @@ use convert::AsRef; use default::Default; use fmt; use iter::ExactSizeIterator; -use iter::{Map, Cloned, Iterator, DoubleEndedIterator}; +use iter::{Map, Cloned, Iterator, DoubleEndedIterator, FusedIterator}; use marker::Sized; use mem; use ops::{Fn, FnMut, FnOnce}; @@ -454,6 +454,9 @@ impl<'a> DoubleEndedIterator for Chars<'a> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a> FusedIterator for Chars<'a> {} + impl<'a> Chars<'a> { /// View the underlying data as a subslice of the original data. /// @@ -513,6 +516,9 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a> FusedIterator for CharIndices<'a> {} + impl<'a> CharIndices<'a> { /// View the underlying data as a subslice of the original data. /// @@ -573,6 +579,9 @@ impl<'a> DoubleEndedIterator for Bytes<'a> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a> FusedIterator for Bytes<'a> {} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a> ExactSizeIterator for Bytes<'a> { #[inline] @@ -727,6 +736,14 @@ macro_rules! generate_pattern_iterators { } } + #[unstable(feature = "fused", reason = "recently added", issue = "0")] + impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {} + + #[unstable(feature = "fused", reason = "recently added", issue = "0")] + impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P> + where P::Searcher: ReverseSearcher<'a> + {} + generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*, $forward_iterator, $reverse_iterator, $iterty); @@ -1076,6 +1093,9 @@ impl<'a> DoubleEndedIterator for Lines<'a> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +impl<'a> FusedIterator for Lines<'a> {} + /// Created with the method [`lines_any()`]. /// /// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any @@ -1139,6 +1159,10 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> { } } +#[unstable(feature = "fused", reason = "recently added", issue = "0")] +#[allow(deprecated)] +impl<'a> FusedIterator for LinesAny<'a> {} + /* Section: Comparing strings */