Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce the IntoIterator trait and reimplement for-loops to use it #20790

Merged
merged 17 commits into from
Jan 31, 2015
4 changes: 4 additions & 0 deletions src/doc/trpl/unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,10 @@ extern fn panic_fmt(args: &core::fmt::Arguments,
#[lang = "eh_personality"] extern fn eh_personality() {}
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
# fn main() {}
# mod std { // for-loops
# pub use core::iter;
# pub use core::option;
# }
```

Note that there is one extra lang item here which differs from the examples
Expand Down
18 changes: 17 additions & 1 deletion src/libcollections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
use core::prelude::*;

use core::default::Default;
use core::iter::FromIterator;
use core::iter::{FromIterator, IntoIterator};
use core::mem::{zeroed, replace, swap};
use core::ptr;

Expand Down Expand Up @@ -655,6 +655,22 @@ impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
}
}

impl<T: Ord> IntoIterator for BinaryHeap<T> {
type Iter = IntoIter<T>;

fn into_iter(self) -> IntoIter<T> {
self.into_iter()
}
}

impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
type Iter = Iter<'a, T>;

fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Extend<T> for BinaryHeap<T> {
fn extend<Iter: Iterator<Item=T>>(&mut self, mut iter: Iter) {
Expand Down
17 changes: 16 additions & 1 deletion src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ use core::fmt;
use core::hash;
use core::iter::RandomAccessIterator;
use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
use core::iter::{self, FromIterator};
use core::iter::{self, FromIterator, IntoIterator};
use core::num::Int;
use core::ops::Index;
use core::slice;
Expand Down Expand Up @@ -1070,6 +1070,14 @@ impl<'a> RandomAccessIterator for Iter<'a> {
}
}

impl<'a> IntoIterator for &'a Bitv {
type Iter = Iter<'a>;

fn into_iter(self) -> Iter<'a> {
self.iter()
}
}

/// An implementation of a set using a bit vector as an underlying
/// representation for holding unsigned numerical elements.
///
Expand Down Expand Up @@ -1873,6 +1881,13 @@ impl<'a> Iterator for SymmetricDifference<'a> {
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.0.size_hint() }
}

impl<'a> IntoIterator for &'a BitvSet {
type Iter = SetIter<'a>;

fn into_iter(self) -> SetIter<'a> {
self.iter()
}
}

#[cfg(test)]
mod tests {
Expand Down
26 changes: 25 additions & 1 deletion src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use core::cmp::Ordering;
use core::default::Default;
use core::fmt::Debug;
use core::hash::{Hash, Hasher};
use core::iter::{Map, FromIterator};
use core::iter::{Map, FromIterator, IntoIterator};
use core::ops::{Index, IndexMut};
use core::{iter, fmt, mem};
use Bound::{self, Included, Excluded, Unbounded};
Expand Down Expand Up @@ -478,6 +478,30 @@ impl<K: Ord, V> BTreeMap<K, V> {
}
}

impl<K, V> IntoIterator for BTreeMap<K, V> {
type Iter = IntoIter<K, V>;

fn into_iter(self) -> IntoIter<K, V> {
self.into_iter()
}
}

impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
type Iter = Iter<'a, K, V>;

fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
}
}

impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
type Iter = IterMut<'a, K, V>;

fn into_iter(mut self) -> IterMut<'a, K, V> {
self.iter_mut()
}
}

/// A helper enum useful for deciding whether to continue a loop since we can't
/// return from a closure
enum Continuation<A, B> {
Expand Down
8 changes: 4 additions & 4 deletions src/libcollections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<T> DoubleEndedIterator for RawItems<T> {
#[unsafe_destructor]
impl<T> Drop for RawItems<T> {
fn drop(&mut self) {
for _ in *self {}
for _ in self.by_ref() {}
}
}

Expand Down Expand Up @@ -1374,9 +1374,9 @@ impl<K, V> Drop for MoveTraversalImpl<K, V> {
fn drop(&mut self) {
// We need to cleanup the stored values manually, as the RawItems destructor would run
// after our deallocation.
for _ in self.keys {}
for _ in self.vals {}
for _ in self.edges {}
for _ in self.keys.by_ref() {}
for _ in self.vals.by_ref() {}
for _ in self.edges.by_ref() {}

let (alignment, size) =
calculate_allocation_generic::<K, V>(self.capacity, self.is_leaf);
Expand Down
18 changes: 17 additions & 1 deletion src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use core::cmp::Ordering::{self, Less, Greater, Equal};
use core::default::Default;
use core::fmt::Debug;
use core::fmt;
use core::iter::{Peekable, Map, FromIterator};
use core::iter::{Peekable, Map, FromIterator, IntoIterator};
use core::ops::{BitOr, BitAnd, BitXor, Sub};

use btree_map::{BTreeMap, Keys};
Expand Down Expand Up @@ -480,6 +480,22 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
}
}

impl<T> IntoIterator for BTreeSet<T> {
type Iter = IntoIter<T>;

fn into_iter(self) -> IntoIter<T> {
self.into_iter()
}
}

impl<'a, T> IntoIterator for &'a BTreeSet<T> {
type Iter = Iter<'a, T>;

fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Extend<T> for BTreeSet<T> {
#[inline]
Expand Down
26 changes: 25 additions & 1 deletion src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use core::cmp::Ordering;
use core::default::Default;
use core::fmt;
use core::hash::{Writer, Hasher, Hash};
use core::iter::{self, FromIterator};
use core::iter::{self, FromIterator, IntoIterator};
use core::mem;
use core::ptr;

Expand Down Expand Up @@ -830,6 +830,30 @@ impl<A> FromIterator<A> for DList<A> {
}
}

impl<T> IntoIterator for DList<T> {
type Iter = IntoIter<T>;

fn into_iter(self) -> IntoIter<T> {
self.into_iter()
}
}

impl<'a, T> IntoIterator for &'a DList<T> {
type Iter = Iter<'a, T>;

fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}

impl<'a, T> IntoIterator for &'a mut DList<T> {
type Iter = IterMut<'a, T>;

fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Extend<A> for DList<A> {
fn extend<T: Iterator<Item=A>>(&mut self, mut iterator: T) {
Expand Down
10 changes: 9 additions & 1 deletion src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use core::prelude::*;
use core::fmt;
use core::num::Int;
use core::iter::FromIterator;
use core::iter::{FromIterator, IntoIterator};
use core::ops::{Sub, BitOr, BitAnd, BitXor};

// FIXME(contentions): implement union family of methods? (general design may be wrong here)
Expand Down Expand Up @@ -256,6 +256,14 @@ impl<E:CLike> FromIterator<E> for EnumSet<E> {
}
}

impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
type Iter = Iter<E>;

fn into_iter(self) -> Iter<E> {
self.iter()
}
}

impl<E:CLike> Extend<E> for EnumSet<E> {
fn extend<I: Iterator<Item=E>>(&mut self, mut iterator: I) {
for element in iterator {
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#![feature(unicode)]
#![feature(hash)]
#![cfg_attr(test, feature(test))]
// NOTE(stage0): remove after a snapshot
#![cfg_attr(not(stage0), allow(unused_mut))]

#[macro_use]
extern crate core;
Expand Down Expand Up @@ -114,6 +116,8 @@ mod std {
pub use core::marker; // derive(Copy)
pub use core::hash; // derive(Hash)
pub use core::ops; // RangeFull
// for-loops
pub use core::iter;
}

#[cfg(test)]
Expand Down
28 changes: 26 additions & 2 deletions src/libcollections/ring_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use core::prelude::*;
use core::cmp::Ordering;
use core::default::Default;
use core::fmt;
use core::iter::{self, repeat, FromIterator, RandomAccessIterator};
use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
use core::marker;
use core::mem;
use core::num::{Int, UnsignedInt};
Expand Down Expand Up @@ -1510,7 +1510,7 @@ pub struct Drain<'a, T: 'a> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: 'a> Drop for Drain<'a, T> {
fn drop(&mut self) {
for _ in *self {}
for _ in self.by_ref() {}
self.inner.head = 0;
self.inner.tail = 0;
}
Expand Down Expand Up @@ -1609,6 +1609,30 @@ impl<A> FromIterator<A> for RingBuf<A> {
}
}

impl<T> IntoIterator for RingBuf<T> {
type Iter = IntoIter<T>;

fn into_iter(self) -> IntoIter<T> {
self.into_iter()
}
}

impl<'a, T> IntoIterator for &'a RingBuf<T> {
type Iter = Iter<'a, T>;

fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}

impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
type Iter = IterMut<'a, T>;

fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Extend<A> for RingBuf<A> {
fn extend<T: Iterator<Item=A>>(&mut self, mut iterator: T) {
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1958,7 +1958,7 @@ mod tests {
let mut amt = 0;
let mut it = v.permutations();
let (min_size, max_opt) = it.size_hint();
for _perm in it {
for _perm in it.by_ref() {
amt += 1;
}
assert_eq!(amt, it.swaps.swaps_made);
Expand Down
6 changes: 3 additions & 3 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl<'a> Iterator for Decompositions<'a> {
}

if !self.sorted {
for ch in self.iter {
for ch in self.iter.by_ref() {
let buffer = &mut self.buffer;
let sorted = &mut self.sorted;
{
Expand Down Expand Up @@ -279,7 +279,7 @@ impl<'a> Iterator for Recompositions<'a> {
loop {
match self.state {
Composing => {
for ch in self.iter {
for ch in self.iter.by_ref() {
let ch_class = unicode::char::canonical_combining_class(ch);
if self.composee.is_none() {
if ch_class != 0 {
Expand Down Expand Up @@ -2154,7 +2154,7 @@ mod tests {
let s = "ศไทย中华Việt Nam";
let mut it = s.chars();
it.next();
assert!(it.zip(it.clone()).all(|(x,y)| x == y));
assert!(it.clone().zip(it).all(|(x,y)| x == y));
}

#[test]
Expand Down
Loading