From 062747b9c969d18544e4a376077499613394e757 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 20:37:05 -0400 Subject: [PATCH 1/8] ptr: inline the Clone implementation --- src/libstd/ptr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index b13d46d540d4a..50c25a2f722f8 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -47,6 +47,7 @@ pub unsafe fn buf_len(buf: **T) -> uint { } impl Clone for *T { + #[inline] fn clone(&self) -> *T { *self } From af9ddd7563d2eb66147a9de126453034938af46a Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 20:46:50 -0400 Subject: [PATCH 2/8] kinds: update documentation --- src/libstd/kinds.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index 6b45ddddf7e93..6a48e18a3cc2a 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -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. From 6a21f22767596fc80fa55eade9824290d14cd85a Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 00:37:50 -0400 Subject: [PATCH 3/8] update the iterator tutorial --- doc/tutorial-container.md | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md index 8d0e8e200d092..1f47c3df14f89 100644 --- a/doc/tutorial-container.md +++ b/doc/tutorial-container.md @@ -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 @@ -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]; @@ -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: @@ -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]); ~~~ @@ -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)` @@ -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)` From 1f89eb867a33b25c3df0078eb2ec18d1fc00bc43 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 21:00:58 -0400 Subject: [PATCH 4/8] tuple: remove obsolete ExtendedTupleOps replaced by iterators (generic composable `map` and `zip` adaptors) --- src/libstd/prelude.rs | 2 +- src/libstd/tuple.rs | 52 ------------------------------------------- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index deee49bc47235..63f7300200931 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -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}; diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 8a3c024ede50d..12073a1f4f095 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -13,9 +13,6 @@ #[allow(missing_doc)]; use clone::Clone; -use vec; -use vec::ImmutableVector; -use iterator::Iterator; pub use self::inner::*; @@ -79,55 +76,6 @@ impl ImmutableTuple for (T, U) { } } -pub trait ExtendedTupleOps { - fn zip(&self) -> ~[(A, B)]; - fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C]; -} - -impl<'self, - A:Clone, - B:Clone> - ExtendedTupleOps 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(&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 ExtendedTupleOps for (~[A], ~[B]) { - #[inline] - fn zip(&self) -> ~[(A, B)] { - match *self { - (ref a, ref b) => { - vec::zip_slice(*a, *b) - } - } - } - - #[inline] - fn map(&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 { From 45426c3b4c20b69b51e7f1866f3e893be273f34c Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 21:29:16 -0400 Subject: [PATCH 5/8] vec: rm obsolete zip and zip_slice These are obsoleted by the generic iterator `zip` adaptor. Unlike these, it does not clone the elements or allocate a new vector by default. --- src/libextra/sort.rs | 7 +---- src/libextra/test.rs | 11 ++----- src/libstd/vec.rs | 42 +------------------------- src/test/run-pass/zip-same-length.rs | 44 ---------------------------- 4 files changed, 4 insertions(+), 100 deletions(-) delete mode 100644 src/test/run-pass/zip-same-length.rs diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index c7920e7270890..bea7868fd32b7 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -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 } @@ -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); } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index a9c3bf98cb659..9778248f00542 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -1121,7 +1121,6 @@ mod tests { use std::either; use std::comm::{stream, SharedChan}; - use std::vec; use tempfile; use std::os; @@ -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()); } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index a605ea4373f3d..996b00096a29f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -390,39 +390,6 @@ pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { (ts, us) } -/** - * Convert two vectors to a vector of pairs, by reference. As zip(). - */ -pub fn zip_slice(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(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`. * @@ -2865,14 +2832,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); diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs deleted file mode 100644 index d97148746d01b..0000000000000 --- a/src/test/run-pass/zip-same-length.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// In this case, the code should compile and should -// succeed at runtime - -use std::vec; - -fn enum_chars(start: u8, end: u8) -> ~[char] { - assert!(start < end); - let mut i = start; - let mut r = ~[]; - while i <= end { r.push(i as char); i += 1u as u8; } - return r; -} - -fn enum_uints(start: uint, end: uint) -> ~[uint] { - assert!(start < end); - let mut i = start; - let mut r = ~[]; - while i <= end { r.push(i); i += 1u; } - return r; -} - -pub fn main() { - let a = 'a' as u8; - let j = 'j' as u8; - let k = 1u; - let l = 10u; - let chars = enum_chars(a, j); - let ints = enum_uints(k, l); - - let ps = vec::zip(chars, ints); - - assert_eq!(ps.head(), &('a', 1u)); - assert_eq!(ps.last(), &(j as char, 10u)); -} From fe047e07ba52279dfba23992d3d1e1aafba78d10 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 21:41:50 -0400 Subject: [PATCH 6/8] iterator: cleanup --- src/libstd/iterator.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 1a5e364542b3e..34bbe9292a5cb 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -174,6 +174,7 @@ pub trait Iterator { /// assert!(it.peek().is_none()); /// assert!(it.next().is_none()); /// ~~~ + #[inline] fn peekable(self) -> Peekable { Peekable{iter: self, peeked: None} } @@ -931,8 +932,7 @@ impl<'self, A, B, T: Iterator> Iterator for Map<'self, A, B, T> { } } -impl<'self, A, B, T: DoubleEndedIterator> DoubleEndedIterator -for Map<'self, A, B, T> { +impl<'self, A, B, T: DoubleEndedIterator> DoubleEndedIterator for Map<'self, A, B, T> { #[inline] fn next_back(&mut self) -> Option { let next = self.iter.next_back(); @@ -940,8 +940,7 @@ for Map<'self, A, B, T> { } } -impl<'self, A, B, T: RandomAccessIterator> RandomAccessIterator -for Map<'self, A, B, T> { +impl<'self, A, B, T: RandomAccessIterator> RandomAccessIterator for Map<'self, A, B, T> { #[inline] fn indexable(&self) -> uint { self.iter.indexable() From 486501963a85a4f593bb0a0b98a412b58b9a200b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 13 Aug 2013 22:06:10 -0400 Subject: [PATCH 7/8] vec: rm redundant is_empty implementations --- src/libstd/vec.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 996b00096a29f..7748c040a1ddc 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -691,12 +691,6 @@ impl Vector 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 { @@ -705,12 +699,6 @@ impl<'self, T> Container for &'self [T] { } impl 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 { From 3cec67bbf2ced2b01ef158ebb5ccc828e852d595 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 15 Aug 2013 21:12:54 -0400 Subject: [PATCH 8/8] rm obsolete test --- src/test/run-fail/zip-different-lengths.rs | 44 ---------------------- 1 file changed, 44 deletions(-) delete mode 100644 src/test/run-fail/zip-different-lengths.rs diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs deleted file mode 100644 index f31fea526391c..0000000000000 --- a/src/test/run-fail/zip-different-lengths.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// In this case, the code should compile but -// the assert should fail at runtime -// error-pattern:assertion failed -extern mod extra; -use std::vec::{same_length, zip}; - -fn enum_chars(start: u8, end: u8) -> ~[char] { - assert!(start < end); - let mut i = start; - let mut r = ~[]; - while i <= end { r.push(i as char); i += 1 as u8; } - return r; -} - -fn enum_uints(start: uint, end: uint) -> ~[uint] { - assert!(start < end); - let mut i = start; - let mut r = ~[]; - while i <= end { r.push(i); i += 1; } - return r; -} - -fn main() { - let a = 'a' as u8; - let j = 'j' as u8; - let k = 1; - let l = 9; - let chars = enum_chars(a, j); - let ints = enum_uints(k, l); - - assert!(same_length(chars, ints)); - let ps = zip(chars, ints); - fail!("the impossible happened"); -}