Skip to content

Commit

Permalink
Add a FusedIterator trait.
Browse files Browse the repository at this point in the history
This trait can be used to avoid the overhead of a fuse wrapper when an iterator
is already well-behaved.

Conforming to: RFC 1581
Closes: #35602
  • Loading branch information
Stebalien committed Aug 18, 2016
1 parent 43c090e commit de91872
Show file tree
Hide file tree
Showing 29 changed files with 437 additions and 24 deletions.
4 changes: 4 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/libcollections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -981,6 +981,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)]
Expand Down Expand Up @@ -1014,6 +1017,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> {
Expand Down Expand Up @@ -1046,6 +1052,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> {
Expand Down
27 changes: 26 additions & 1 deletion src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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>;
Expand Down Expand Up @@ -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;

Expand All @@ -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() }
Expand Down Expand Up @@ -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() }
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
21 changes: 20 additions & 1 deletion src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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> {
Expand All @@ -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> {
Expand All @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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> {}
5 changes: 4 additions & 1 deletion src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#![feature(core_intrinsics)]
#![feature(dropck_parametricity)]
#![feature(fmt_internals)]
#![feature(fused)]
#![feature(heap_api)]
#![feature(inclusive_range)]
#![feature(lang_items)]
Expand Down
11 changes: 10 additions & 1 deletion src/libcollections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -757,6 +757,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;
Expand Down Expand Up @@ -801,6 +804,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.
Expand Down Expand Up @@ -908,6 +914,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 {
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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> {}
8 changes: 7 additions & 1 deletion src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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> {}
Loading

0 comments on commit de91872

Please sign in to comment.