Auto merge of #35656 - Stebalien:fused, r=alexcrichton

Implement 1581 (FusedIterator)

* [ ] Implement on patterns. See https://github.com/rust-lang/rust/issues/27721#issuecomment-239638642.
* [ ] Handle OS Iterators. A bunch of iterators (`Args`, `Env`, etc.) in libstd wrap platform specific iterators. The current ones all appear to be well-behaved but can we assume that future ones will be?
* [ ] Does someone want to audit this? On first glance, all of the iterators on which I implemented `FusedIterator` appear to be well-behaved but there are a *lot* of them so a second pair of eyes would be nice.
* I haven't touched rustc internal iterators (or the internal rand) because rustc doesn't actually call `fuse()`.
* `FusedIterator` can't be implemented on `std::io::{Bytes, Chars}`.

Closes: #35602 (Tracking Issue)
Implements: rust-lang/rfcs#1581
This commit is contained in:
bors 2016-08-23 07:46:52 -07:00 committed by GitHub
commit 0bd99f9d5c
29 changed files with 437 additions and 24 deletions

View File

@ -61,6 +61,7 @@ use core::borrow;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::iter::FusedIterator;
use core::marker::{self, Unsize};
use core::mem;
use core::ops::{CoerceUnsized, Deref, DerefMut};
@ -529,6 +530,9 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
/// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a

View File

@ -91,7 +91,7 @@
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(unsize)]
#![cfg_attr(not(test), feature(raw, fn_traits, placement_new_protocol))]
#![cfg_attr(not(test), feature(fused, raw, fn_traits, placement_new_protocol))]
#![cfg_attr(test, feature(test, box_heap))]
// Allow testing this library

View File

@ -152,7 +152,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use core::ops::{Drop, Deref, DerefMut};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem::swap;
use core::mem::size_of;
use core::ptr;
@ -980,6 +980,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", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}
/// An iterator that moves out of a `BinaryHeap`.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
@ -1013,6 +1016,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
/// An iterator that drains a `BinaryHeap`.
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
@ -1045,6 +1051,9 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
fn from(vec: Vec<T>) -> BinaryHeap<T> {

View File

@ -11,7 +11,7 @@
use core::cmp::Ordering;
use core::fmt::Debug;
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, Peekable};
use core::iter::{FromIterator, Peekable, FusedIterator};
use core::marker::PhantomData;
use core::ops::Index;
use core::{fmt, intrinsics, mem, ptr};
@ -1147,6 +1147,9 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> {
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
if self.length == 0 {
@ -1216,6 +1219,9 @@ impl<'a, K: 'a, V: 'a> ExactSizeIterator for IterMut<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
impl<K, V> IntoIterator for BTreeMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
@ -1338,6 +1344,9 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<K, V> FusedIterator for IntoIter<K, V> {}
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
@ -1362,6 +1371,9 @@ impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
impl<'a, K, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> {
Keys { inner: self.inner.clone() }
@ -1392,6 +1404,9 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
impl<'a, K, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> {
Values { inner: self.inner.clone() }
@ -1437,6 +1452,10 @@ impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}
impl<'a, K, V> Range<'a, K, V> {
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
let handle = self.front;
@ -1511,6 +1530,9 @@ impl<'a, K, V> Range<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Range<'a, K, V> {}
impl<'a, K, V> Clone for Range<'a, K, V> {
fn clone(&self) -> Range<'a, K, V> {
Range {
@ -1574,6 +1596,9 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for RangeMut<'a, K, V> {}
impl<'a, K, V> RangeMut<'a, K, V> {
unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
let handle = ptr::read(&self.back);

View File

@ -15,7 +15,7 @@ use core::cmp::Ordering::{self, Less, Greater, Equal};
use core::cmp::{min, max};
use core::fmt::Debug;
use core::fmt;
use core::iter::{Peekable, FromIterator};
use core::iter::{Peekable, FromIterator, FusedIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub};
use borrow::Borrow;
@ -805,6 +805,8 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Iterator for IntoIter<T> {
@ -828,6 +830,8 @@ impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
impl<'a, T> Clone for Range<'a, T> {
fn clone(&self) -> Range<'a, T> {
@ -847,6 +851,9 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Range<'a, T> {}
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
@ -890,6 +897,9 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Difference<'a, T> {}
impl<'a, T> Clone for SymmetricDifference<'a, T> {
fn clone(&self) -> SymmetricDifference<'a, T> {
SymmetricDifference {
@ -920,6 +930,9 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for SymmetricDifference<'a, T> {}
impl<'a, T> Clone for Intersection<'a, T> {
fn clone(&self) -> Intersection<'a, T> {
Intersection {
@ -960,6 +973,9 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Intersection<'a, T> {}
impl<'a, T> Clone for Union<'a, T> {
fn clone(&self) -> Union<'a, T> {
Union {
@ -991,3 +1007,6 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
(max(a_len, b_len), Some(a_len + b_len))
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: Ord> FusedIterator for Union<'a, T> {}

View File

@ -20,7 +20,7 @@
use core::marker;
use core::fmt;
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::ops::{Sub, BitOr, BitAnd, BitXor};
// FIXME(contentions): implement union family of methods? (general design may be
@ -266,6 +266,9 @@ impl<E: CLike> Iterator for Iter<E> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<E: CLike> FusedIterator for Iter<E> {}
impl<E: CLike> FromIterator<E> for EnumSet<E> {
fn from_iter<I: IntoIterator<Item = E>>(iter: I) -> EnumSet<E> {
let mut ret = EnumSet::new();

View File

@ -37,6 +37,7 @@
#![feature(core_intrinsics)]
#![feature(dropck_parametricity)]
#![feature(fmt_internals)]
#![feature(fused)]
#![feature(heap_api)]
#![feature(inclusive_range)]
#![feature(lang_items)]

View File

@ -19,7 +19,7 @@ use alloc::boxed::{Box, IntermediateBox};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hasher, Hash};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem;
use core::ops::{BoxPlace, InPlace, Place, Placer};
@ -754,6 +754,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", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
@ -798,6 +801,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", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}
impl<'a, T> IterMut<'a, T> {
/// Inserts the given element just after the element most recently returned by `.next()`.
/// The inserted element does not appear in the iteration.
@ -905,6 +911,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> FromIterator<T> for LinkedList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {

View File

@ -23,6 +23,7 @@ use core::str as core_str;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
use core::iter::FusedIterator;
use rustc_unicode::str::{UnicodeStr, Utf16Encoder};
use vec_deque::VecDeque;
@ -136,6 +137,9 @@ impl<'a> Iterator for EncodeUtf16<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for EncodeUtf16<'a> {}
// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4

View File

@ -57,7 +57,7 @@
use core::fmt;
use core::hash;
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem;
use core::ops::{self, Add, AddAssign, Index, IndexMut};
use core::ptr;
@ -1995,3 +1995,6 @@ impl<'a> DoubleEndedIterator for Drain<'a> {
self.iter.next_back()
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Drain<'a> {}

View File

@ -68,7 +68,7 @@ use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::intrinsics::{arith_offset, assume};
use core::iter::FromIterator;
use core::iter::{FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut};
use core::ops;
@ -1845,6 +1845,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
impl<T: Clone> Clone for IntoIter<T> {
fn clone(&self) -> IntoIter<T> {
@ -1932,3 +1935,6 @@ impl<'a, T> Drop for Drain<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T> FusedIterator for Drain<'a, T> {}

View File

@ -20,7 +20,7 @@
use core::cmp::Ordering;
use core::fmt;
use core::iter::{repeat, FromIterator};
use core::iter::{repeat, FromIterator, FusedIterator};
use core::mem;
use core::ops::{Index, IndexMut};
use core::ptr;
@ -1891,6 +1891,10 @@ 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", issue = "35602")]
impl<'a, T> FusedIterator for Iter<'a, T> {}
/// `VecDeque` mutable iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
@ -1943,6 +1947,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", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}
/// A by-value VecDeque iterator
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
@ -1977,6 +1984,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
/// A draining VecDeque iterator
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
@ -2066,6 +2076,9 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PartialEq> PartialEq for VecDeque<A> {
fn eq(&self, other: &VecDeque<A>) -> bool {

View File

@ -18,6 +18,7 @@
use prelude::v1::*;
use char_private::is_printable;
use iter::FusedIterator;
use mem::transmute;
// UTF-8 ranges and tags for encoding characters
@ -516,6 +517,9 @@ impl ExactSizeIterator for EscapeUnicode {
}
}
#[unstable(feature = "fused", issue = "35602")]
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
@ -616,6 +620,9 @@ impl ExactSizeIterator for EscapeDefault {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}
/// An iterator that yields the literal escape code of a `char`.
///
/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its
@ -637,6 +644,9 @@ impl Iterator for EscapeDebug {
#[unstable(feature = "char_escape_debug", issue = "35068")]
impl ExactSizeIterator for EscapeDebug { }
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDebug {}
/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
/// value.
///
@ -675,6 +685,9 @@ impl Iterator for EncodeUtf8 {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EncodeUtf8 {}
/// An iterator over `u16` entries represending the UTF-16 encoding of a `char`
/// value.
///
@ -714,6 +727,8 @@ impl Iterator for EncodeUtf16 {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EncodeUtf16 {}
/// An iterator over an iterator of bytes of the characters the bytes represent
/// as UTF-8
@ -760,3 +775,6 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
})
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator<Item = u8>> FusedIterator for DecodeUtf8<I> {}

View File

@ -330,6 +330,8 @@ pub use self::sources::{Once, once};
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{ExactSizeIterator, Sum, Product};
#[unstable(feature = "fused", issue = "35602")]
pub use self::traits::FusedIterator;
mod iterator;
mod range;
@ -370,6 +372,10 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
impl<I> ExactSizeIterator for Rev<I>
where I: ExactSizeIterator + DoubleEndedIterator {}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Rev<I>
where I: FusedIterator + DoubleEndedIterator {}
/// An iterator that clones the elements of an underlying iterator.
///
/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its
@ -413,6 +419,11 @@ impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
where I: ExactSizeIterator<Item=&'a T>, T: Clone
{}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, I, T: 'a> FusedIterator for Cloned<I>
where I: FusedIterator<Item=&'a T>, T: Clone
{}
/// An iterator that repeats endlessly.
///
/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its
@ -451,6 +462,9 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
/// An iterator that strings two iterators together.
///
/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its
@ -613,6 +627,13 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
}
}
// Note: *both* must be fused to handle double-ended iterators.
#[unstable(feature = "fused", issue = "35602")]
impl<A, B> FusedIterator for Chain<A, B>
where A: FusedIterator,
B: FusedIterator<Item=A::Item>,
{}
/// An iterator that iterates two other iterators simultaneously.
///
/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its
@ -823,6 +844,10 @@ unsafe impl<A, B> TrustedRandomAccess for Zip<A, B>
}
#[unstable(feature = "fused", issue = "35602")]
impl<A, B> FusedIterator for Zip<A, B>
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
@ -919,6 +944,10 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
where F: FnMut(I::Item) -> B {}
#[unstable(feature = "fused", issue = "35602")]
impl<B, I: FusedIterator, F> FusedIterator for Map<I, F>
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
@ -979,6 +1008,10 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator, P> FusedIterator for Filter<I, P>
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
@ -1041,6 +1074,10 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F>
where F: FnMut(I::Item) -> Option<B> {}
/// An iterator that yields the current count and the element during iteration.
///
/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its
@ -1128,6 +1165,9 @@ unsafe impl<I> TrustedRandomAccess for Enumerate<I>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
/// An iterator with a `peek()` that returns an optional reference to the next
/// element.
///
@ -1195,6 +1235,9 @@ impl<I: Iterator> Iterator for Peekable<I> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator> FusedIterator for Peekable<I> {}
impl<I: Iterator> Peekable<I> {
/// Returns a reference to the next() value without advancing the iterator.
///
@ -1296,6 +1339,10 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I, P> FusedIterator for SkipWhile<I, P>
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
@ -1351,6 +1398,10 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I, P> FusedIterator for TakeWhile<I, P>
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
@ -1442,6 +1493,9 @@ impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSize
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Skip<I> 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
@ -1503,6 +1557,8 @@ impl<I> Iterator for Take<I> where I: Iterator{
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}
/// An iterator to maintain state while iterating another iterator.
///
@ -1549,6 +1605,10 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<B, I, St, F> FusedIterator for Scan<I, St, F>
where I: FusedIterator, F: FnMut(&mut St, I::Item) -> Option<B> {}
/// An iterator that maps each element to an iterator, and yields the elements
/// of the produced iterators.
///
@ -1635,6 +1695,10 @@ impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> wher
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I, U, F> FusedIterator for FlatMap<I, U, F>
where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
@ -1651,12 +1715,15 @@ pub struct Fuse<I> {
done: bool
}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Fuse<I> where I: Iterator {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Fuse<I> where I: Iterator {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<<I as Iterator>::Item> {
default fn next(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
None
} else {
@ -1667,7 +1734,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
default fn nth(&mut self, n: usize) -> Option<I::Item> {
if self.done {
None
} else {
@ -1678,7 +1745,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}
#[inline]
fn last(self) -> Option<I::Item> {
default fn last(self) -> Option<I::Item> {
if self.done {
None
} else {
@ -1687,7 +1754,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}
#[inline]
fn count(self) -> usize {
default fn count(self) -> usize {
if self.done {
0
} else {
@ -1696,7 +1763,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
default fn size_hint(&self) -> (usize, Option<usize>) {
if self.done {
(0, Some(0))
} else {
@ -1708,7 +1775,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
#[inline]
fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
if self.done {
None
} else {
@ -1719,6 +1786,53 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
}
}
unsafe impl<I> TrustedRandomAccess for Fuse<I>
where I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
self.iter.get_unchecked(i)
}
}
#[unstable(feature = "fused", issue = "35602")]
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()
}
}
#[unstable(feature = "fused", reason = "recently added", issue = "35602")]
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()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {}
@ -1788,3 +1902,7 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
where F: FnMut(&I::Item) {}
#[unstable(feature = "fused", issue = "35602")]
impl<I: FusedIterator, F> FusedIterator for Inspect<I, F>
where F: FnMut(&I::Item) {}

View File

@ -16,7 +16,7 @@ use option::Option::{self, Some, None};
use marker::Sized;
use usize;
use super::{DoubleEndedIterator, ExactSizeIterator, Iterator};
use super::{DoubleEndedIterator, ExactSizeIterator, Iterator, FusedIterator};
/// Objects that can be stepped over in both directions.
///
@ -364,6 +364,10 @@ impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for StepBy<A, ops::RangeFrom<A>>
where A: Clone, for<'a> &'a A: Add<&'a A, Output = A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
type Item = A;
@ -401,6 +405,9 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::Range<A>> {}
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
@ -468,6 +475,9 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A: Step + Clone> FusedIterator for StepBy<A, ops::RangeInclusive<A>> {}
macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
@ -526,6 +536,10 @@ impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::Range<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> where
for<'a> &'a A: Add<&'a A, Output = A>
@ -540,6 +554,10 @@ impl<A: Step> Iterator for ops::RangeFrom<A> where
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::RangeFrom<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> where
for<'a> &'a A: Add<&'a A, Output = A>
@ -638,3 +656,7 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
n
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for ops::RangeInclusive<A>
where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}

View File

@ -15,7 +15,7 @@ use marker;
use option::Option::{self, Some, None};
use usize;
use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator};
use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator, FusedIterator};
/// An iterator that repeats an element endlessly.
///
@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) }
}
#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}
/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
@ -138,6 +141,9 @@ impl<T> ExactSizeIterator for Empty<T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Empty<T> {}
// not #[derive] because that adds a Clone bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
@ -213,6 +219,9 @@ impl<T> ExactSizeIterator for Once<T> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for Once<T> {}
/// Creates an iterator that yields an element exactly once.
///
/// This is commonly used to adapt a single value into a [`chain()`] of other

View File

@ -660,3 +660,19 @@ macro_rules! float_sum_product {
integer_sum_product! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
float_sum_product! { f32 f64 }
/// 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.
///
/// Note: In general, you should not use `FusedIterator` in generic bounds if
/// you need a fused iterator. Instead, you should just call `Iterator::fused()`
/// on the iterator. If the iterator is already fused, the additional `Fuse`
/// wrapper will be a no-op with no performance penalty.
#[unstable(feature = "fused", issue = "35602")]
pub trait FusedIterator: Iterator {}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}

View File

@ -144,8 +144,8 @@ use self::Option::*;
use clone::Clone;
use convert::From;
use default::Default;
use iter::ExactSizeIterator;
use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
use iter::{Iterator, FromIterator, IntoIterator, ExactSizeIterator, DoubleEndedIterator};
use iter::FusedIterator;
use mem;
use ops::FnOnce;
use result::Result::{Ok, Err};
@ -796,6 +796,7 @@ impl<A> DoubleEndedIterator for Item<A> {
}
impl<A> ExactSizeIterator for Item<A> {}
impl<A> FusedIterator for Item<A> {}
/// An iterator over a reference of the contained item in an Option.
#[stable(feature = "rust1", since = "1.0.0")]
@ -821,6 +822,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", issue = "35602")]
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> {
@ -852,6 +856,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", issue = "35602")]
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")]
@ -876,6 +883,9 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> ExactSizeIterator for IntoIter<A> {}
#[unstable(feature = "fused", issue = "35602")]
impl<A> FusedIterator for IntoIter<A> {}
/////////////////////////////////////////////////////////////////////////////
// FromIterator
/////////////////////////////////////////////////////////////////////////////

View File

@ -241,6 +241,7 @@ use self::Result::{Ok, Err};
use clone::Clone;
use fmt;
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
use iter::FusedIterator;
use ops::FnOnce;
use option::Option::{self, None, Some};
@ -869,6 +870,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", issue = "35602")]
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 { inner: self.inner } }
@ -901,6 +905,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", issue = "35602")]
impl<'a, T> FusedIterator for IterMut<'a, T> {}
/// An iterator over the value in a `Ok` variant of a `Result`.
#[derive(Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
@ -928,6 +935,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
#[unstable(feature = "fused", issue = "35602")]
impl<T> FusedIterator for IntoIter<T> {}
/////////////////////////////////////////////////////////////////////////////
// FromIterator
/////////////////////////////////////////////////////////////////////////////

View File

@ -992,6 +992,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", issue = "35602")]
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 } }
@ -1110,6 +1113,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", issue = "35602")]
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)]
@ -1202,6 +1208,9 @@ impl<'a, T, P> SplitIter for Split<'a, T, P> where P: FnMut(&T) -> bool {
}
}
#[unstable(feature = "fused", issue = "35602")]
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")]
@ -1292,6 +1301,9 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where
}
}
#[unstable(feature = "fused", issue = "35602")]
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.
@ -1408,6 +1420,10 @@ macro_rules! forward_iterator {
self.inner.size_hint()
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P>
where P: FnMut(&T) -> bool {}
}
}
@ -1506,6 +1522,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", issue = "35602")]
impl<'a, T> FusedIterator for Windows<'a, T> {}
/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a
/// time).
///
@ -1609,6 +1628,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", issue = "35602")]
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.
@ -1704,6 +1726,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", issue = "35602")]
impl<'a, T> FusedIterator for ChunksMut<'a, T> {}
//
// Free functions
//

View File

@ -23,7 +23,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", issue = "35602")]
impl<'a> FusedIterator for Chars<'a> {}
impl<'a> Chars<'a> {
/// View the underlying data as a subslice of the original data.
///
@ -525,6 +528,9 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for CharIndices<'a> {}
impl<'a> CharIndices<'a> {
/// View the underlying data as a subslice of the original data.
///
@ -593,6 +599,9 @@ impl<'a> ExactSizeIterator for Bytes<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Bytes<'a> {}
/// This macro generates a Clone impl for string pattern API
/// wrapper types of the form X<'a, P>
macro_rules! derive_pattern_clone {
@ -739,6 +748,13 @@ macro_rules! generate_pattern_iterators {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
#[unstable(feature = "fused", issue = "35602")]
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);
@ -1088,6 +1104,9 @@ impl<'a> DoubleEndedIterator for Lines<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Lines<'a> {}
/// Created with the method [`lines_any()`].
///
/// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any
@ -1151,6 +1170,10 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
#[allow(deprecated)]
impl<'a> FusedIterator for LinesAny<'a> {}
/*
Section: Comparing strings
*/

View File

@ -29,6 +29,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use core::char::CharExt as C;
use core::iter::FusedIterator;
use core::fmt;
use tables::{conversions, derived_property, general_category, property};
@ -62,6 +63,9 @@ impl Iterator for ToLowercase {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for ToLowercase {}
/// Returns an iterator that yields the uppercase equivalent of a `char`.
///
/// This `struct` is created by the [`to_uppercase()`] method on [`char`]. See
@ -80,6 +84,8 @@ impl Iterator for ToUppercase {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for ToUppercase {}
enum CaseMappingIter {
Three(char, char, char),

View File

@ -35,6 +35,7 @@
#![feature(char_escape_debug)]
#![feature(core_char_ext)]
#![feature(decode_utf8)]
#![feature(fused)]
#![feature(lang_items)]
#![feature(staged_api)]
#![feature(unicode)]

View File

@ -14,7 +14,7 @@
//! methods provided by the unicode parts of the CharExt trait.
use core::char;
use core::iter::Filter;
use core::iter::{Filter, FusedIterator};
use core::str::Split;
/// An iterator over the non-whitespace substrings of a string,
@ -177,6 +177,10 @@ impl<I> Iterator for Utf16Encoder<I>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Utf16Encoder<I>
where I: FusedIterator<Item = char> {}
impl<'a> Iterator for SplitWhitespace<'a> {
type Item = &'a str;
@ -189,3 +193,6 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
self.inner.next_back()
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for SplitWhitespace<'a> {}

View File

@ -16,6 +16,7 @@ use prelude::v1::*;
use mem;
use ops::Range;
use iter::FusedIterator;
/// Extension methods for ASCII-subset only operations on string slices.
///
@ -368,6 +369,9 @@ impl DoubleEndedIterator for EscapeDefault {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for EscapeDefault {}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}
static ASCII_LOWERCASE_MAP: [u8; 256] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,

View File

@ -15,7 +15,7 @@ use borrow::Borrow;
use cmp::max;
use fmt::{self, Debug};
use hash::{Hash, Hasher, BuildHasher, SipHasher13};
use iter::FromIterator;
use iter::{FromIterator, FusedIterator};
use mem::{self, replace};
use ops::{Deref, Index};
use rand::{self, Rng};
@ -1484,6 +1484,9 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
@ -1495,6 +1498,8 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> Iterator for IntoIter<K, V> {
@ -1507,6 +1512,8 @@ impl<K, V> Iterator for IntoIter<K, V> {
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<K, V> FusedIterator for IntoIter<K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Keys<'a, K, V> {
@ -1519,6 +1526,8 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Values<'a, K, V> {
@ -1531,6 +1540,8 @@ impl<'a, K, V> Iterator for Values<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
#[stable(feature = "map_values_mut", since = "1.10.0")]
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
@ -1543,6 +1554,8 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Drain<'a, K, V> {
@ -1555,6 +1568,8 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
#[inline] fn len(&self) -> usize { self.inner.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Drain<'a, K, V> {}
impl<'a, K, V> Entry<'a, K, V> {
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -11,7 +11,7 @@
use borrow::Borrow;
use fmt;
use hash::{Hash, BuildHasher};
use iter::{Chain, FromIterator};
use iter::{Chain, FromIterator, FusedIterator};
use ops::{BitOr, BitAnd, BitXor, Sub};
use super::Recover;
@ -906,6 +906,8 @@ impl<'a, K> Iterator for Iter<'a, K> {
impl<'a, K> ExactSizeIterator for Iter<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Iter<'a, K> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<K> Iterator for IntoIter<K> {
@ -918,6 +920,8 @@ impl<K> Iterator for IntoIter<K> {
impl<K> ExactSizeIterator for IntoIter<K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<K> FusedIterator for IntoIter<K> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K> Iterator for Drain<'a, K> {
@ -930,6 +934,8 @@ impl<'a, K> Iterator for Drain<'a, K> {
impl<'a, K> ExactSizeIterator for Drain<'a, K> {
fn len(&self) -> usize { self.iter.len() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Drain<'a, K> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Intersection<'a, T, S> {
@ -961,6 +967,11 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Intersection<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Difference<'a, T, S> {
fn clone(&self) -> Difference<'a, T, S> {
@ -991,6 +1002,11 @@ impl<'a, T, S> Iterator for Difference<'a, T, S>
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Difference<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> {
fn clone(&self) -> SymmetricDifference<'a, T, S> {
@ -1008,11 +1024,21 @@ impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Clone for Union<'a, T, S> {
fn clone(&self) -> Union<'a, T, S> { Union { iter: self.iter.clone() } }
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T, S> FusedIterator for Union<'a, T, S>
where T: Eq + Hash, S: BuildHasher
{}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, S> Iterator for Union<'a, T, S>
where T: Eq + Hash, S: BuildHasher

View File

@ -232,6 +232,7 @@
#![feature(float_from_str_radix)]
#![feature(fn_traits)]
#![feature(fnbox)]
#![feature(fused)]
#![feature(hashmap_hasher)]
#![feature(heap_api)]
#![feature(inclusive_range)]

View File

@ -107,7 +107,7 @@ use fmt;
use fs;
use hash::{Hash, Hasher};
use io;
use iter;
use iter::{self, FusedIterator};
use mem;
use ops::{self, Deref};
use string::String;
@ -858,6 +858,9 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Iter<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Components<'a> {
type Item = Component<'a>;
@ -958,6 +961,9 @@ impl<'a> DoubleEndedIterator for Components<'a> {
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for Components<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> cmp::PartialEq for Components<'a> {
fn eq(&self, other: &Components<'a>) -> bool {