From 5e9f006c5b95ea98893b0398decd458fd642f38f Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 7 Jun 2013 23:42:35 +1000 Subject: [PATCH 1/4] std: more dummy type parameters on iterators to work around #6967. --- src/libstd/iterator.rs | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 7f723e44c2b..4bc545f607d 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -55,7 +55,7 @@ pub trait IteratorUtil { /// assert_eq!(it.next().get(), &1); /// assert!(it.next().is_none()); /// ~~~ - fn chain>(self, other: U) -> ChainIterator; + fn chain>(self, other: U) -> ChainIterator; /// Creates an iterator which iterates over both this and the specified /// iterators simultaneously, yielding the two elements as pairs. When @@ -73,7 +73,7 @@ pub trait IteratorUtil { /// assert_eq!(it.next().get(), (&0, &1)); /// assert!(it.next().is_none()); /// ~~~ - fn zip>(self, other: U) -> ZipIterator; + fn zip>(self, other: U) -> ZipIterator; // FIXME: #5898: should be called map /// Creates a new iterator which will apply the specified function to each @@ -139,7 +139,7 @@ pub trait IteratorUtil { /// assert_eq!(it.next().get(), (1, &200)); /// assert!(it.next().is_none()); /// ~~~ - fn enumerate(self) -> EnumerateIterator; + fn enumerate(self) -> EnumerateIterator; /// Creates an iterator which invokes the predicate on elements until it /// returns true. Once the predicate returns true, all further elements are @@ -349,12 +349,12 @@ pub trait IteratorUtil { /// In the future these will be default methods instead of a utility trait. impl> IteratorUtil for T { #[inline(always)] - fn chain>(self, other: U) -> ChainIterator { + fn chain>(self, other: U) -> ChainIterator { ChainIterator{a: self, b: other, flag: false} } #[inline(always)] - fn zip>(self, other: U) -> ZipIterator { + fn zip>(self, other: U) -> ZipIterator { ZipIterator{a: self, b: other} } @@ -375,7 +375,7 @@ impl> IteratorUtil for T { } #[inline(always)] - fn enumerate(self) -> EnumerateIterator { + fn enumerate(self) -> EnumerateIterator { EnumerateIterator{iter: self, count: 0} } @@ -570,13 +570,14 @@ impl> OrdIterator for T { } /// An iterator which strings two iterators together -pub struct ChainIterator { +// FIXME #6967: Dummy A parameter to get around type inference bug +pub struct ChainIterator { priv a: T, priv b: U, priv flag: bool } -impl, U: Iterator> Iterator for ChainIterator { +impl, U: Iterator> Iterator for ChainIterator { #[inline] fn next(&mut self) -> Option { if self.flag { @@ -593,12 +594,13 @@ impl, U: Iterator> Iterator for ChainIterator { } /// An iterator which iterates two other iterators simultaneously -pub struct ZipIterator { +// FIXME #6967: Dummy A & B parameters to get around type inference bug +pub struct ZipIterator { priv a: T, priv b: U } -impl, U: Iterator> Iterator<(A, B)> for ZipIterator { +impl, U: Iterator> Iterator<(A, B)> for ZipIterator { #[inline] fn next(&mut self) -> Option<(A, B)> { match (self.a.next(), self.b.next()) { @@ -664,12 +666,13 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } /// An iterator which yields the current count and the element during iteration -pub struct EnumerateIterator { +// FIXME #6967: Dummy A parameter to get around type inference bug +pub struct EnumerateIterator { priv iter: T, priv count: uint } -impl> Iterator<(uint, A)> for EnumerateIterator { +impl> Iterator<(uint, A)> for EnumerateIterator { #[inline] fn next(&mut self) -> Option<(uint, A)> { match self.iter.next() { @@ -887,7 +890,7 @@ mod tests { let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60]; let mut it = xs.iter().chain(ys.iter()); let mut i = 0; - for it.advance |&x: &uint| { + for it.advance |&x| { assert_eq!(x, expected[i]); i += 1; } @@ -896,7 +899,7 @@ mod tests { let ys = Counter::new(30u, 10).take(4); let mut it = xs.iter().transform(|&x| x).chain(ys); let mut i = 0; - for it.advance |x: uint| { + for it.advance |x| { assert_eq!(x, expected[i]); i += 1; } @@ -906,7 +909,7 @@ mod tests { #[test] fn test_filter_map() { let mut it = Counter::new(0u, 1u).take(10) - .filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None }); + .filter_map(|x| if x.is_even() { Some(x*x) } else { None }); assert_eq!(it.collect::<~[uint]>(), ~[0*0, 2*2, 4*4, 6*6, 8*8]); } @@ -914,7 +917,7 @@ mod tests { fn test_iterator_enumerate() { let xs = [0u, 1, 2, 3, 4, 5]; let mut it = xs.iter().enumerate(); - for it.advance |(i, &x): (uint, &uint)| { + for it.advance |(i, &x)| { assert_eq!(i, x); } } @@ -925,7 +928,7 @@ mod tests { let ys = [0u, 1, 2, 3, 5, 13]; let mut it = xs.iter().take_while(|&x| *x < 15u); let mut i = 0; - for it.advance |&x: &uint| { + for it.advance |&x| { assert_eq!(x, ys[i]); i += 1; } @@ -938,7 +941,7 @@ mod tests { let ys = [15, 16, 17, 19]; let mut it = xs.iter().skip_while(|&x| *x < 15u); let mut i = 0; - for it.advance |&x: &uint| { + for it.advance |&x| { assert_eq!(x, ys[i]); i += 1; } From f661a15b2bd5c2a9ea984c72c28caf970317d8a3 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 8 Jun 2013 01:20:47 +1000 Subject: [PATCH 2/4] std: remove vec::each2 and vec::each2_mut in favour of iterators --- src/librustc/middle/kind.rs | 5 +-- src/librustc/middle/trans/inline.rs | 3 +- src/librustc/middle/trans/type_use.rs | 5 +-- src/librustc/middle/typeck/check/_match.rs | 4 +-- src/librustc/middle/typeck/check/mod.rs | 6 ++-- src/librustc/middle/typeck/coherence.rs | 7 ++-- src/libstd/vec.rs | 38 -------------------- src/libsyntax/ext/deriving/generic.rs | 5 +-- src/test/bench/shootout-fannkuch-redux.rs | 6 ++-- src/test/run-pass/vec-each2_mut.rs | 42 ---------------------- 10 files changed, 24 insertions(+), 97 deletions(-) delete mode 100644 src/test/run-pass/vec-each2_mut.rs diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 736e98dc6ec..543264ba11e 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -17,6 +17,7 @@ use middle::typeck; use util::ppaux::{Repr, ty_to_str}; use util::ppaux::UserString; +use core::iterator::IteratorUtil; use core::vec; use syntax::ast::*; use syntax::attr::attrs_contains_name; @@ -268,7 +269,7 @@ pub fn check_expr(e: @expr, cx: Context, v: visit::vt) { ts.repr(cx.tcx), type_param_defs.repr(cx.tcx)); } - for vec::each2(**ts, *type_param_defs) |&ty, type_param_def| { + for ts.iter().zip(type_param_defs.iter()).advance |(&ty, type_param_def)| { check_bounds(cx, type_parameter_id, e.span, ty, type_param_def) } } @@ -309,7 +310,7 @@ fn check_ty(aty: @Ty, cx: Context, v: visit::vt) { let did = ast_util::def_id_of_def(cx.tcx.def_map.get_copy(&id)); let type_param_defs = ty::lookup_item_type(cx.tcx, did).generics.type_param_defs; - for vec::each2(**ts, *type_param_defs) |&ty, type_param_def| { + for ts.iter().zip(type_param_defs.iter()).advance |(&ty, type_param_def)| { check_bounds(cx, aty.id, aty.span, ty, type_param_def) } } diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 1f9bdcb5abb..88f97cfa0b8 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -19,6 +19,7 @@ use middle::trans::common::*; use middle::ty; use util::ppaux::ty_to_str; +use core::iterator::IteratorUtil; use core::vec; use syntax::ast; use syntax::ast_map::path_name; @@ -75,7 +76,7 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::def_id, ast::item_enum(_, _) => { let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id)); let vs_there = ty::enum_variants(ccx.tcx, parent_id); - for vec::each2(*vs_here, *vs_there) |here, there| { + for vs_here.iter().zip(vs_there.iter()).advance |(here, there)| { if there.id == fn_id { my_id = here.id.node; } ccx.external.insert(there.id, Some(here.id.node)); } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 9c84b4ffa99..b1b1b5212af 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -33,6 +33,7 @@ use middle::trans::inline; use middle::ty; use middle::typeck; +use core::iterator::IteratorUtil; use core::option::{Some, None}; use core::uint; use core::vec; @@ -264,7 +265,7 @@ pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) { for opt_static_did.each |&did| { for cx.ccx.tcx.node_type_substs.find_copy(&callee_id).each |ts| { let type_uses = type_uses_for(cx.ccx, did, ts.len()); - for vec::each2(*type_uses, *ts) |uses, subst| { + for type_uses.iter().zip(ts.iter()).advance |(uses, subst)| { type_needs(cx, *uses, *subst) } } @@ -302,7 +303,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) { for opt_ts.each |ts| { let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get_copy(&e.id)); let uses_for_ts = type_uses_for(cx.ccx, id, ts.len()); - for vec::each2(*uses_for_ts, *ts) |uses, subst| { + for uses_for_ts.iter().zip(ts.iter()).advance |(uses, subst)| { type_needs(cx, *uses, *subst) } } diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 03803a64fc3..13f41c06e18 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -18,8 +18,8 @@ use middle::typeck::check::{instantiate_path, lookup_def}; use middle::typeck::check::{structure_of, valid_range_bounds}; use middle::typeck::require_same_types; +use core::iterator::IteratorUtil; use core::hashmap::{HashMap, HashSet}; -use core::vec; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; @@ -232,7 +232,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, if !error_happened { for subpats.each |pats| { - for vec::each2(*pats, arg_types) |subpat, arg_ty| { + for pats.iter().zip(arg_types.iter()).advance |(subpat, arg_ty)| { check_pat(pcx, *subpat, *arg_ty); } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c69aeeb4aa8..1e5f8970448 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -110,6 +110,8 @@ use util::common::{block_query, indenter, loop_query}; use util::ppaux::{bound_region_to_str}; use util::ppaux; + +use core::iterator::IteratorUtil; use core::cast::transmute; use core::hashmap::HashMap; use core::result; @@ -412,7 +414,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, for opt_self_info.each |self_info| { fcx.write_ty(self_info.self_id, self_info.self_ty); } - for vec::each2(decl.inputs, arg_tys) |input, arg| { + for decl.inputs.iter().zip(arg_tys.iter()).advance |(input, arg)| { fcx.write_ty(input.id, *arg); } @@ -449,7 +451,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, } // Add formal parameters. - for vec::each2(arg_tys, decl.inputs) |arg_ty, input| { + for arg_tys.iter().zip(decl.inputs.iter()).advance |(arg_ty, input)| { // Create type variables for each argument. do pat_util::pat_bindings(tcx.def_map, input.pat) |_bm, pat_id, _sp, _path| { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 9d25430d80b..dcf165b0496 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -54,6 +54,7 @@ use syntax::visit::{Visitor, SimpleVisitor}; use syntax::visit::{visit_mod}; use util::ppaux::ty_to_str; +use core::iterator::IteratorUtil; use core::hashmap::{HashMap, HashSet}; use core::old_iter; use core::result::Ok; @@ -617,9 +618,9 @@ impl CoherenceChecker { // Check to ensure that each parameter binding respected its // kind bounds. for [ a, b ].each |result| { - for vec::each2(result.type_variables, - *result.type_param_defs) - |ty_var, type_param_def| + for result.type_variables.iter() + .zip(result.type_param_defs.iter()) + .advance |(ty_var, type_param_def)| { if type_param_def.bounds.builtin_bounds.contains_elem( ty::BoundCopy) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 8340b956b65..54efd35b91e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1666,44 +1666,6 @@ pub fn eachi_reverse<'r,T>(v: &'r [T], return true; } -/** - * Iterates over two vectors simultaneously - * - * # Failure - * - * Both vectors must have the same length - */ -#[inline] -pub fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool { - assert_eq!(v1.len(), v2.len()); - for uint::range(0u, v1.len()) |i| { - if !f(&v1[i], &v2[i]) { - return false; - } - } - return true; -} - -/** - * - * Iterates over two vector with mutable. - * - * # Failure - * - * Both vectors must have the same length - */ -#[inline] -pub fn each2_mut(v1: &mut [U], v2: &mut [T], - f: &fn(u: &mut U, t: &mut T) -> bool) -> bool { - assert_eq!(v1.len(), v2.len()); - for uint::range(0u, v1.len()) |i| { - if !f(&mut v1[i], &mut v2[i]) { - return false; - } - } - return true; -} - /** * Iterate over all permutations of vector `v`. * diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 52a2d9ff9de..b36d4496492 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -174,6 +174,7 @@ use opt_vec; use core::uint; use core::vec; +use core::iterator::IteratorUtil; pub use self::ty::*; mod ty; @@ -616,7 +617,7 @@ impl<'self> MethodDef<'self> { // make a series of nested matches, to destructure the // structs. This is actually right-to-left, but it shoudn't // matter. - for vec::each2(self_args, patterns) |&arg_expr, &pat| { + for self_args.iter().zip(patterns.iter()).advance |(&arg_expr, &pat)| { body = cx.expr_match(span, arg_expr, ~[ cx.arm(span, ~[pat], body) ]) } @@ -951,7 +952,7 @@ fn create_struct_pattern(cx: @ExtCtxt, // must be nonempty to reach here let pattern = if struct_type == Record { let field_pats = do vec::build |push| { - for vec::each2(subpats, ident_expr) |&pat, &(id, _)| { + for subpats.iter().zip(ident_expr.iter()).advance |(&pat, &(id, _))| { // id is guaranteed to be Some push(ast::field_pat { ident: id.get(), pat: pat }) } diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index b1db5843b7c..4dd4d2b5847 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -1,3 +1,4 @@ +use std::iterator::*; use std::from_str::FromStr; use std::i32::range; use std::os; @@ -29,9 +30,8 @@ fn fannkuch_redux(n: i32) -> i32 { r -= 1; } - // XXX: Need each2_mut. - for vec::eachi_mut(perm) |i, perm_i| { - *perm_i = perm1.unsafe_get(i); + for perm.mut_iter().zip(perm1.iter()).advance |(perm_i, perm1_i)| { + *perm_i = *perm1_i; } let mut flips_count: i32 = 0; diff --git a/src/test/run-pass/vec-each2_mut.rs b/src/test/run-pass/vec-each2_mut.rs deleted file mode 100644 index 73e0418993c..00000000000 --- a/src/test/run-pass/vec-each2_mut.rs +++ /dev/null @@ -1,42 +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. - -// -*- rust -*- - -use std::io; -use std::vec; - -fn main(){ - let mut t1 = ~[]; - t1.push('a'); - - let mut t2 = ~[]; - t2.push('b'); - - for vec::each2_mut(t1, t2) | i1, i2 | { - assert_eq!(*i1, 'a'); - assert_eq!(*i2, 'b'); - } - - for vec::each2(t1, t2) | i1, i2 | { - io::println(fmt!("after t1: %?, t2: %?", i1, i2)); - } - - for vec::each2_mut(t1, t2) | i1, i2 | { - *i1 = 'b'; - *i2 = 'a'; - assert_eq!(*i1, 'b'); - assert_eq!(*i2, 'a'); - } - - for vec::each2(t1, t2) | i1, i2 | { - io::println(fmt!("before t1: %?, t2: %?", i1, i2)); - } -} From 54d914a9a932a0e9e65195f0f5be91e5e8b7f342 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 8 Jun 2013 03:24:27 +1000 Subject: [PATCH 3/4] std: remove each[i]_mut functions, in favour of iterators. --- src/libextra/sha1.rs | 3 +- src/librustc/middle/dataflow.rs | 3 +- src/libstd/pipes.rs | 12 ++--- src/libstd/prelude.rs | 1 - src/libstd/trie.rs | 3 +- src/libstd/vec.rs | 53 ++----------------- src/libsyntax/ext/pipes/pipec.rs | 4 +- src/libsyntax/ext/tt/macro_parser.rs | 3 +- src/test/bench/shootout-fasta-redux.rs | 3 +- src/test/bench/shootout-nbody.rs | 3 +- src/test/bench/shootout-spectralnorm.rs | 9 ++-- ...ility-inherits-through-fixed-length-vec.rs | 4 +- 12 files changed, 32 insertions(+), 69 deletions(-) diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs index 80b4ab02e5f..a845d326142 100644 --- a/src/libextra/sha1.rs +++ b/src/libextra/sha1.rs @@ -24,6 +24,7 @@ use core::prelude::*; +use core::iterator::IteratorUtil; use core::str; use core::uint; use core::vec; @@ -173,7 +174,7 @@ pub fn sha1() -> @Sha1 { fn mk_result(st: &mut Sha1State) -> ~[u8] { if !(*st).computed { pad_msg(st); (*st).computed = true; } let mut rs: ~[u8] = ~[]; - for vec::each_mut((*st).h) |ptr_hpart| { + for st.h.mut_iter().advance |ptr_hpart| { let hpart = *ptr_hpart; let a = (hpart >> 24u32 & 0xFFu32) as u8; let b = (hpart >> 16u32 & 0xFFu32) as u8; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 349deef2998..1f9fff14ba2 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -18,6 +18,7 @@ use core::prelude::*; +use core::iterator::IteratorUtil; use core::cast; use core::io; use core::str; @@ -895,7 +896,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { fn reset(&mut self, bits: &mut [uint]) { let e = if self.dfcx.oper.initial_value() {uint::max_value} else {0}; - for vec::each_mut(bits) |b| { *b = e; } + for bits.mut_iter().advance |b| { *b = e; } } fn add_to_entry_set(&mut self, id: ast::node_id, pred_bits: &[uint]) { diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index fe1b834813e..1137540ae70 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -87,6 +87,7 @@ bounded and unbounded protocols allows for less code duplication. use container::Container; use cast::{forget, transmute, transmute_copy}; use either::{Either, Left, Right}; +use iterator::IteratorUtil; use kinds::Owned; use libc; use ops::Drop; @@ -96,8 +97,7 @@ use unstable::intrinsics; use ptr; use ptr::RawPtr; use task; -use vec; -use vec::OwnedVector; +use vec::{OwnedVector, MutableVector}; use util::replace; static SPIN_COUNT: uint = 0; @@ -600,7 +600,7 @@ pub fn wait_many(pkts: &mut [T]) -> uint { let mut data_avail = false; let mut ready_packet = pkts.len(); - for vec::eachi_mut(pkts) |i, p| { + for pkts.mut_iter().enumerate().advance |(i, p)| { unsafe { let p = &mut *p.header(); let old = p.mark_blocked(this); @@ -622,7 +622,7 @@ pub fn wait_many(pkts: &mut [T]) -> uint { let event = wait_event(this) as *PacketHeader; let mut pos = None; - for vec::eachi_mut(pkts) |i, p| { + for pkts.mut_iter().enumerate().advance |(i, p)| { if p.header() == event { pos = Some(i); break; @@ -640,7 +640,7 @@ pub fn wait_many(pkts: &mut [T]) -> uint { debug!("%?", &mut pkts[ready_packet]); - for vec::each_mut(pkts) |p| { + for pkts.mut_iter().advance |p| { unsafe { (*p.header()).unblock() } @@ -853,7 +853,7 @@ pub fn select(mut endpoints: ~[RecvPacketBuffered]) Option, ~[RecvPacketBuffered]) { let mut endpoint_headers = ~[]; - for vec::each_mut(endpoints) |endpoint| { + for endpoints.mut_iter().advance |endpoint| { endpoint_headers.push(endpoint.header()); } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index bb10cec30ed..89992003026 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -82,4 +82,3 @@ pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; // Reexported runtime types pub use comm::{stream, Port, Chan, GenericChan, GenericSmartChan, GenericPort, Peekable}; pub use task::spawn; - diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index aea03b437ca..7899edbfcb9 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -11,6 +11,7 @@ //! An ordered map and set for integer keys implemented as a radix trie use prelude::*; +use iterator::IteratorUtil; use uint; use util::{swap, replace}; use vec; @@ -277,7 +278,7 @@ impl TrieNode { } fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool { - for vec::each_mut(self.children) |child| { + for self.children.mut_iter().advance |child| { match *child { Internal(ref mut x) => if !x.mutate_values(f) { return false diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 54efd35b91e..d8424f4a29e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -19,7 +19,7 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use old_iter::BaseIter; use old_iter; -use iterator::Iterator; +use iterator::{Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; use libc; @@ -1568,28 +1568,6 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { return !broke; } -/// Like `each()`, but for the case where you have -/// a vector with mutable contents and you would like -/// to mutate the contents as you iterate. -#[inline(always)] -pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool { - let mut broke = false; - do as_mut_buf(v) |p, n| { - let mut n = n; - let mut p = p; - while n > 0 { - unsafe { - let q: &'r mut T = cast::transmute_mut_region(&mut *p); - if !f(q) { break; } - p = p.offset(1); - } - n -= 1; - } - broke = n > 0; - } - return !broke; -} - /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] @@ -1620,24 +1598,6 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { return true; } -/** - * Iterates over a mutable vector's elements and indices - * - * Return true to continue, false to break. - */ -#[inline(always)] -pub fn eachi_mut<'r,T>(v: &'r mut [T], - f: &fn(uint, v: &'r mut T) -> bool) -> bool { - let mut i = 0; - for each_mut(v) |p| { - if !f(i, p) { - return false; - } - i += 1; - } - return true; -} - /** * Iterates over a vector's elements in reverse * @@ -2700,7 +2660,7 @@ impl old_iter::BaseIter for @[A] { impl<'self,A> old_iter::MutableIter for &'self mut [A] { #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { - each_mut(*self, blk) + self.mut_iter().advance(blk) } } @@ -2708,7 +2668,7 @@ impl<'self,A> old_iter::MutableIter for &'self mut [A] { impl old_iter::MutableIter for ~[A] { #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { - each_mut(*self, blk) + self.mut_iter().advance(blk) } } @@ -2716,7 +2676,7 @@ impl old_iter::MutableIter for ~[A] { impl old_iter::MutableIter for @mut [A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) -> bool { - each_mut(*self, blk) + self.mut_iter().advance(blk) } } @@ -2748,7 +2708,7 @@ impl<'self,A> old_iter::ExtendedIter for &'self [A] { impl<'self,A> old_iter::ExtendedMutableIter for &'self mut [A] { #[inline(always)] pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) -> bool { - eachi_mut(*self, blk) + self.mut_iter().enumerate().advance(|(i, v)| blk(i, v)) } } @@ -3608,16 +3568,13 @@ mod tests { fn test_each_ret_len0() { let mut a0 : [int, .. 0] = []; assert_eq!(each(a0, |_p| fail!()), true); - assert_eq!(each_mut(a0, |_p| fail!()), true); } #[test] fn test_each_ret_len1() { let mut a1 = [17]; assert_eq!(each(a1, |_p| true), true); - assert_eq!(each_mut(a1, |_p| true), true); assert_eq!(each(a1, |_p| false), false); - assert_eq!(each_mut(a1, |_p| false), false); } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 1e5b3c3ee7e..a5725613d58 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -23,6 +23,7 @@ use ext::quote::rt::*; use opt_vec; use opt_vec::OptVec; +use core::iterator::IteratorUtil; use core::str; use core::vec; @@ -258,8 +259,7 @@ impl to_type_decls for state { let mut items = ~[]; { - let messages = &mut *self.messages; - for vec::each_mut(*messages) |m| { + for self.messages.mut_iter().advance |m| { if dir == send { items.push(m.gen_send(cx, true)); items.push(m.gen_send(cx, false)); diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 9fb9def84e9..5f43452cc83 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -22,6 +22,7 @@ use parse::parser::Parser; use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str}; use parse::token; +use core::iterator::IteratorUtil; use core::hashmap::HashMap; use core::str; use core::uint; @@ -358,7 +359,7 @@ pub fn parse( if tok == EOF { if eof_eis.len() == 1u { let mut v = ~[]; - for vec::each_mut(eof_eis[0u].matches) |dv| { + for eof_eis[0u].matches.mut_iter().advance |dv| { v.push(dv.pop()); } return success(nameize(sess, ms, v)); diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index cb9972a709f..bc1685a1092 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -1,3 +1,4 @@ +use std::iterator::IteratorUtil; use std::cast::transmute; use std::from_str::FromStr; use std::libc::{FILE, STDOUT_FILENO, c_int, fdopen, fputc, fputs, fwrite, size_t}; @@ -134,7 +135,7 @@ impl RandomFasta { fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] { let mut lookup = [ NULL_AMINO_ACID, ..LOOKUP_SIZE ]; let mut j = 0; - for vec::eachi_mut(lookup) |i, slot| { + for lookup.mut_iter().enumerate().advance |(i, slot)| { while a[j].p < (i as f32) { j += 1; } diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index 242b3a3f7a4..f1fff7ea0ac 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -1,3 +1,4 @@ +use std::iterator::IteratorUtil; use std::f64; use std::from_str::FromStr; use std::os; @@ -104,7 +105,7 @@ fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: i32) { } } - for vec::each_mut(*bodies) |a| { + for bodies.mut_iter().advance |a| { a.x[0] += dt * a.v[0]; a.x[1] += dt * a.v[1]; a.x[2] += dt * a.v[2]; diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 1623eaaa7d3..7356e848ba3 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -1,3 +1,4 @@ +use std::iterator::IteratorUtil; use std::f64; use std::from_str::FromStr; use std::iter::ExtendedMutableIter; @@ -18,9 +19,9 @@ fn dot(v: &[f64], u: &[f64]) -> f64 { } fn mult_Av(v: &mut [f64], out: &mut [f64]) { - for vec::eachi_mut(out) |i, out_i| { + for out.mut_iter().enumerate().advance |(i, out_i)| { let mut sum = 0.0; - for vec::eachi_mut(v) |j, &v_j| { + for v.mut_iter().enumerate().advance |(j, &v_j)| { sum += v_j / (A(i as i32, j as i32) as f64); } *out_i = sum; @@ -28,9 +29,9 @@ fn mult_Av(v: &mut [f64], out: &mut [f64]) { } fn mult_Atv(v: &mut [f64], out: &mut [f64]) { - for vec::eachi_mut(out) |i, out_i| { + for out.mut_iter().enumerate().advance |(i, out_i)| { let mut sum = 0.0; - for vec::eachi_mut(v) |j, &v_j| { + for v.mut_iter().enumerate().advance |(j, &v_j)| { sum += v_j / (A(j as i32, i as i32) as f64); } *out_i = sum; diff --git a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs index 0b4f92f1d7c..d2c8e465c11 100644 --- a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs +++ b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; +use std::iterator::IteratorUtil; fn test1() { let mut ints = [0, ..32]; @@ -18,7 +18,7 @@ fn test1() { fn test2() { let mut ints = [0, ..32]; - for vec::each_mut(ints) |i| { *i += 22; } + for ints.mut_iter().advance |i| { *i += 22; } for ints.each |i| { assert!(*i == 22); } } From 07e4d69baa5b1bd3d4cc4a6c9e17c90168d6f058 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 7 Jun 2013 14:45:31 -0400 Subject: [PATCH 4/4] iterator: work around method resolve bug (#5898) --- src/libstd/iterator.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 4bc545f607d..4ed82f63b39 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -285,7 +285,8 @@ pub trait IteratorUtil { /// let a = [1, 2, 3, 4, 5]; /// assert!(a.iter().last().get() == &5); /// ~~~ - fn last(&mut self) -> Option; + // FIXME: #5898: should be called `last` + fn last_(&mut self) -> Option; /// Performs a fold operation over the entire iterator, returning the /// eventual state at the end of the iteration. @@ -437,7 +438,7 @@ impl> IteratorUtil for T { /// Return the last item yielded by an iterator. #[inline(always)] - fn last(&mut self) -> Option { + fn last_(&mut self) -> Option { let mut last = None; for self.advance |x| { last = Some(x); } last @@ -1025,8 +1026,8 @@ mod tests { #[test] fn test_iterator_last() { let v = &[0, 1, 2, 3, 4]; - assert_eq!(v.iter().last().unwrap(), &4); - assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0); + assert_eq!(v.iter().last_().unwrap(), &4); + assert_eq!(v.slice(0, 1).iter().last_().unwrap(), &0); } #[test]