Skip to content

assorted iterator/container cleanups #8503

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

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions doc/tutorial-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ iterator object. For example, vector slices several iterators available:

* `iter()` and `rev_iter()`, for immutable references to the elements
* `mut_iter()` and `mut_rev_iter()`, for mutable references to the elements
* `consume_iter()` and `consume_rev_iter`, to move the elements out by-value
* `move_iter()` and `move_rev_iter`, to move the elements out by-value

A typical mutable container will implement at least `iter()`, `mut_iter()` and
`consume_iter()` along with the reverse variants if it maintains an order.
`move_iter()` along with the reverse variants if it maintains an order.

### Freezing

Expand All @@ -139,9 +139,9 @@ and `&mut`.

## Iterator adaptors

The `IteratorUtil` trait implements common algorithms as methods extending
every `Iterator` implementation. For example, the `fold` method will accumulate
the items yielded by an `Iterator` into a single value:
The `Iterator` trait provides many common algorithms as default methods. For
example, the `fold` method will accumulate the items yielded by an `Iterator`
into a single value:

~~~
let xs = [1, 9, 2, 3, 14, 12];
Expand All @@ -154,14 +154,10 @@ Some adaptors return an adaptor object implementing the `Iterator` trait itself:
~~~
let xs = [1, 9, 2, 3, 14, 12];
let ys = [5, 2, 1, 8];
let sum = xs.iter().chain_(ys.iter()).fold(0, |a, b| a + *b);
let sum = xs.iter().chain(ys.iter()).fold(0, |a, b| a + *b);
assert_eq!(sum, 57);
~~~

Note that some adaptors like the `chain_` method above use a trailing
underscore to work around an issue with method resolve. The underscores will be
dropped when they become unnecessary.

## For loops

The `for` keyword can be used as sugar for iterating through any iterator:
Expand Down Expand Up @@ -212,7 +208,7 @@ Iterators offer generic conversion to containers with the `collect` adaptor:

~~~
let xs = [0, 1, 1, 2, 3, 5, 8];
let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~[int]>();
let ys = xs.rev_iter().skip(1).map(|&x| x * 2).collect::<~[int]>();
assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
~~~

Expand Down Expand Up @@ -307,13 +303,13 @@ for &x in it.invert() {
The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
version of the standard immutable and mutable vector iterators.

The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are
The `chain`, `map`, `filter`, `filter_map` and `inspect` adaptors are
`DoubleEndedIterator` implementations if the underlying iterators are.

~~~
let xs = [1, 2, 3, 4];
let ys = [5, 6, 7, 8];
let mut it = xs.iter().chain_(ys.iter()).transform(|&x| x * 2);
let mut it = xs.iter().chain(ys.iter()).map(|&x| x * 2);

printfln!("%?", it.next()); // prints `Some(2)`

Expand All @@ -329,13 +325,13 @@ The `RandomAccessIterator` trait represents an iterator offering random access
to the whole range. The `indexable` method retrieves the number of elements
accessible with the `idx` method.

The `chain_` adaptor is an implementation of `RandomAccessIterator` if the
The `chain` adaptor is an implementation of `RandomAccessIterator` if the
underlying iterators are.

~~~
let xs = [1, 2, 3, 4, 5];
let ys = ~[7, 9, 11];
let mut it = xs.iter().chain_(ys.iter());
let mut it = xs.iter().chain(ys.iter());
printfln!("%?", it.idx(0)); // prints `Some(&1)`
printfln!("%?", it.idx(5)); // prints `Some(&7)`
printfln!("%?", it.idx(7)); // prints `Some(&11)`
Expand Down
7 changes: 1 addition & 6 deletions src/libextra/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,11 +782,8 @@ mod test_qsort3 {

#[cfg(test)]
mod test_qsort {

use sort::*;

use std::vec;

fn check_sort(v1: &mut [int], v2: &mut [int]) {
let len = v1.len();
fn leual(a: &int, b: &int) -> bool { *a <= *b }
Expand Down Expand Up @@ -835,9 +832,7 @@ mod test_qsort {

let immut_names = names;

let pairs = vec::zip_slice(expected, immut_names);
for p in pairs.iter() {
let (a, b) = *p;
for (&a, &b) in expected.iter().zip(immut_names.iter()) {
debug!("%d %d", a, b);
assert_eq!(a, b);
}
Expand Down
11 changes: 2 additions & 9 deletions src/libextra/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,6 @@ mod tests {

use std::either;
use std::comm::{stream, SharedChan};
use std::vec;
use tempfile;
use std::os;

Expand Down Expand Up @@ -1309,14 +1308,8 @@ mod tests {
~"test::parse_ignored_flag",
~"test::sort_tests"];

let pairs = vec::zip(expected, filtered);

for p in pairs.iter() {
match *p {
(ref a, ref b) => {
assert!(*a == b.desc.name.to_str());
}
}
for (a, b) in expected.iter().zip(filtered.iter()) {
assert!(*a == b.desc.name.to_str());
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/libstd/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub trait Iterator<A> {
/// assert!(it.peek().is_none());
/// assert!(it.next().is_none());
/// ~~~
#[inline]
fn peekable(self) -> Peekable<A, Self> {
Peekable{iter: self, peeked: None}
}
Expand Down Expand Up @@ -931,17 +932,15 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
}
}

impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
for Map<'self, A, B, T> {
impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B> for Map<'self, A, B, T> {
#[inline]
fn next_back(&mut self) -> Option<B> {
let next = self.iter.next_back();
self.do_map(next)
}
}

impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B>
for Map<'self, A, B, T> {
impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'self, A, B, T> {
#[inline]
fn indexable(&self) -> uint {
self.iter.indexable()
Expand Down
12 changes: 3 additions & 9 deletions src/libstd/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,21 @@ intrinsic properties of the type. These classifications, often called
They cannot be implemented by user code, but are instead implemented
by the compiler automatically for the types to which they apply.

The 2 kinds are

* Send - owned types and types containing owned types. These types
may be transferred across task boundaries.

* Freeze - types that are deeply immutable.

*/

#[allow(missing_doc)];

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
// empty.
}

/// Types that are either immutable or have inherited mutability.
#[lang="freeze"]
pub trait Freeze {
// empty.
}

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
// Empty.
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub use str::{Str, StrVector, StrSlice, OwnedStr};
pub use from_str::FromStr;
pub use to_bytes::IterBytes;
pub use to_str::{ToStr, ToStrConsume};
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use tuple::{CopyableTuple, ImmutableTuple};
pub use tuple::{CloneableTuple1, ImmutableTuple1};
pub use tuple::{CloneableTuple2, CloneableTuple3, CloneableTuple4, CloneableTuple5};
pub use tuple::{CloneableTuple6, CloneableTuple7, CloneableTuple8, CloneableTuple9};
Expand Down
1 change: 1 addition & 0 deletions src/libstd/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub unsafe fn buf_len<T>(buf: **T) -> uint {
}

impl<T> Clone for *T {
#[inline]
fn clone(&self) -> *T {
*self
}
Expand Down
52 changes: 0 additions & 52 deletions src/libstd/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
#[allow(missing_doc)];

use clone::Clone;
use vec;
use vec::ImmutableVector;
use iterator::Iterator;

pub use self::inner::*;

Expand Down Expand Up @@ -79,55 +76,6 @@ impl<T, U> ImmutableTuple<T, U> for (T, U) {
}
}

pub trait ExtendedTupleOps<A,B> {
fn zip(&self) -> ~[(A, B)];
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
}

impl<'self,
A:Clone,
B:Clone>
ExtendedTupleOps<A,B> for
(&'self [A], &'self [B]) {
#[inline]
fn zip(&self) -> ~[(A, B)] {
match *self {
(ref a, ref b) => {
vec::zip_slice(*a, *b)
}
}
}

#[inline]
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
match *self {
(ref a, ref b) => {
a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
}
}
}
}

impl<A:Clone, B:Clone> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
#[inline]
fn zip(&self) -> ~[(A, B)] {
match *self {
(ref a, ref b) => {
vec::zip_slice(*a, *b)
}
}
}

#[inline]
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
match *self {
(ref a, ref b) => {
a.iter().zip(b.iter()).map(|(aa, bb)| f(aa, bb)).collect()
}
}
}
}

// macro for implementing n-ary tuple functions and operations

macro_rules! tuple_impls {
Expand Down
54 changes: 1 addition & 53 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,39 +390,6 @@ pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
(ts, us)
}

/**
* Convert two vectors to a vector of pairs, by reference. As zip().
*/
pub fn zip_slice<T:Clone,U:Clone>(v: &[T], u: &[U]) -> ~[(T, U)] {
let mut zipped = ~[];
let sz = v.len();
let mut i = 0u;
assert_eq!(sz, u.len());
while i < sz {
zipped.push((v[i].clone(), u[i].clone()));
i += 1u;
}
zipped
}

/**
* Convert two vectors to a vector of pairs.
*
* Returns a vector of tuples, where the i-th tuple contains the
* i-th elements from each of the input vectors.
*/
pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
let mut i = v.len();
assert_eq!(i, u.len());
let mut w = with_capacity(i);
while i > 0 {
w.push((v.pop(),u.pop()));
i -= 1;
}
w.reverse();
w
}

/**
* Iterate over all permutations of vector `v`.
*
Expand Down Expand Up @@ -724,12 +691,6 @@ impl<T> Vector<T> for @[T] {
}

impl<'self, T> Container for &'self [T] {
/// Returns true if a vector contains no elements
#[inline]
fn is_empty(&self) -> bool {
self.as_imm_buf(|_p, len| len == 0u)
}

/// Returns the length of a vector
#[inline]
fn len(&self) -> uint {
Expand All @@ -738,12 +699,6 @@ impl<'self, T> Container for &'self [T] {
}

impl<T> Container for ~[T] {
/// Returns true if a vector contains no elements
#[inline]
fn is_empty(&self) -> bool {
self.as_imm_buf(|_p, len| len == 0u)
}

/// Returns the length of a vector
#[inline]
fn len(&self) -> uint {
Expand Down Expand Up @@ -2865,14 +2820,7 @@ mod tests {

#[test]
fn test_zip_unzip() {
let v1 = ~[1, 2, 3];
let v2 = ~[4, 5, 6];

let z1 = zip(v1, v2);

assert_eq!((1, 4), z1[0]);
assert_eq!((2, 5), z1[1]);
assert_eq!((3, 6), z1[2]);
let z1 = ~[(1, 4), (2, 5), (3, 6)];

let (left, right) = unzip(z1);

Expand Down
44 changes: 0 additions & 44 deletions src/test/run-fail/zip-different-lengths.rs

This file was deleted.

Loading