diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md index 66bd0b9c1319f..5ed61d6930143 100644 --- a/doc/tutorial-container.md +++ b/doc/tutorial-container.md @@ -108,7 +108,7 @@ impl Iterator for ZeroStream { ## Container iterators Containers implement iteration over the contained elements by returning an -iterator object. For example, vectors have four iterators available: +iterator object. For example, vector slices have four iterators available: * `vector.iter()`, for immutable references to the elements * `vector.mut_iter()`, for mutable references to the elements diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 06422a49b65f0..8e493fd5396f9 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -601,9 +601,8 @@ fn make_run_args(config: &config, _props: &TestProps, testfile: &Path) -> ProcArgs { // If we've got another tool to run under (valgrind), // then split apart its command - let toolargs = split_maybe_args(&config.runtool); - - let mut args = toolargs + [make_exe_name(config, testfile).to_str()]; + let mut args = split_maybe_args(&config.runtool); + args.push(make_exe_name(config, testfile).to_str()); let prog = args.shift(); return ProcArgs {prog: prog, args: args}; } diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 238e4a4d238d4..0f2d44f57e34c 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -240,7 +240,6 @@ impl Digest for Sha1 { #[cfg(test)] mod tests { - use std::vec; use digest::{Digest, DigestUtil}; use sha1::Sha1; @@ -337,7 +336,7 @@ mod tests { for tests.iter().advance |t| { (*sh).input_str(t.input); sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); @@ -357,7 +356,7 @@ mod tests { left = left - take; } sh.result(out); - assert!(vec::eq(t.output, out)); + assert!(t.output.as_slice() == out); let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index f249feeb4403d..88c61e60d86b4 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -45,7 +45,7 @@ static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal" static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best" pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = @@ -63,7 +63,7 @@ pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { } pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] { - do vec::as_imm_buf(bytes) |b, len| { + do bytes.as_imm_buf |b, len| { unsafe { let mut outsz : size_t = 0; let res = diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index e8bdc951ca4e7..de0a988f94c8e 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -55,7 +55,6 @@ use std::io; use std::comm::GenericChan; use std::comm::GenericPort; use std::sys::size_of; -use std::vec; /** A FlatPort, consisting of a `BytePort` that receives byte vectors, @@ -274,7 +273,7 @@ impl,P:BytePort> GenericPort for FlatPort { } }; - if vec::eq(command, CONTINUE) { + if CONTINUE.as_slice() == command { let msg_len = match self.byte_port.try_recv(size_of::()) { Some(bytes) => { io::u64_from_be_bytes(bytes, 0, size_of::()) @@ -931,7 +930,7 @@ mod test { fn test_try_recv_none3(loader: PortLoader

) { static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by garbage - let bytes = CONTINUE.to_owned() + [0]; + let bytes = CONTINUE.to_owned() + &[0u8]; let port = loader(bytes); let res: Option = port.try_recv(); assert!(res.is_none()); @@ -955,7 +954,7 @@ mod test { 1, sys::size_of::()) |len_bytes| { len_bytes.to_owned() }; - let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0]; + let bytes = CONTINUE.to_owned() + len_bytes + &[0u8, 0, 0, 0]; let port = loader(bytes); diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 210921aa3d762..71d99479693fa 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -24,7 +24,6 @@ use std::io::{WriterUtil, ReaderUtil}; use std::io; use std::str; use std::to_str; -use std::vec; use serialize::Encodable; use serialize; @@ -941,7 +940,7 @@ impl serialize::Decoder for Decoder { let name = match self.stack.pop() { String(s) => s, List(list) => { - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } match self.stack.pop() { @@ -1059,7 +1058,7 @@ impl serialize::Decoder for Decoder { let len = match self.stack.pop() { List(list) => { let len = list.len(); - do vec::consume_reverse(list) |_i, v| { + for list.consume_rev_iter().advance |v| { self.stack.push(v); } len diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 25aeccdcbed03..a0b95924e09dc 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -207,7 +207,7 @@ impl Add for BigUint { let new_len = uint::max(self.data.len(), other.data.len()); let mut carry = 0; - let sum = do vec::from_fn(new_len) |i| { + let mut sum = do vec::from_fn(new_len) |i| { let ai = if i < self.data.len() { self.data[i] } else { 0 }; let bi = if i < other.data.len() { other.data[i] } else { 0 }; let (hi, lo) = BigDigit::from_uint( @@ -216,8 +216,8 @@ impl Add for BigUint { carry = hi; lo }; - if carry == 0 { return BigUint::new(sum) }; - return BigUint::new(sum + [carry]); + if carry != 0 { sum.push(carry); } + return BigUint::new(sum); } } @@ -284,15 +284,15 @@ impl Mul for BigUint { if n == 1 { return copy *a; } let mut carry = 0; - let prod = do a.data.iter().transform |ai| { + let mut prod = do a.data.iter().transform |ai| { let (hi, lo) = BigDigit::from_uint( (*ai as uint) * (n as uint) + (carry as uint) ); carry = hi; lo }.collect::<~[BigDigit]>(); - if carry == 0 { return BigUint::new(prod) }; - return BigUint::new(prod + [carry]); + if carry != 0 { prod.push(carry); } + return BigUint::new(prod); } @@ -520,10 +520,12 @@ impl ToStrRadix for BigUint { fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str { if v.is_empty() { return ~"0" } - let s = vec::reversed(v).map(|n| { - let s = uint::to_str_radix(*n as uint, radix); - str::from_chars(vec::from_elem(l - s.len(), '0')) + s - }).concat(); + let mut s = str::with_capacity(v.len() * l); + for v.rev_iter().advance |n| { + let ss = uint::to_str_radix(*n as uint, radix); + s.push_str("0".repeat(l - ss.len())); + s.push_str(ss); + } s.trim_left_chars(&'0').to_owned() } } @@ -619,15 +621,15 @@ impl BigUint { if n_bits == 0 || self.is_zero() { return copy *self; } let mut carry = 0; - let shifted = do self.data.iter().transform |elem| { + let mut shifted = do self.data.iter().transform |elem| { let (hi, lo) = BigDigit::from_uint( (*elem as uint) << n_bits | (carry as uint) ); carry = hi; lo }.collect::<~[BigDigit]>(); - if carry == 0 { return BigUint::new(shifted); } - return BigUint::new(shifted + [carry]); + if carry != 0 { shifted.push(carry); } + return BigUint::new(shifted); } @@ -1629,7 +1631,6 @@ mod bigint_tests { use std::int; use std::num::{IntConvertible, Zero, One, FromStrRadix}; use std::uint; - use std::vec; #[test] fn test_from_biguint() { @@ -1646,9 +1647,11 @@ mod bigint_tests { #[test] fn test_cmp() { - let vs = [ &[2], &[1, 1], &[2, 1], &[1, 1, 1] ]; - let mut nums = vec::reversed(vs) - .map(|s| BigInt::from_slice(Minus, *s)); + let vs = [ &[2 as BigDigit], &[1, 1], &[2, 1], &[1, 1, 1] ]; + let mut nums = ~[]; + for vs.rev_iter().advance |s| { + nums.push(BigInt::from_slice(Minus, *s)); + } nums.push(Zero::zero()); nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 2d82736568159..d56f7b32ae7d8 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -53,7 +53,7 @@ fn map_slices( info!("spawning tasks"); while base < len { let end = uint::min(len, base + items_per_task); - do vec::as_imm_buf(xs) |p, _len| { + do xs.as_imm_buf |p, _len| { let f = f(); let base = base; let f = do future_spawn() || { @@ -78,11 +78,10 @@ fn map_slices( info!("num_tasks: %?", (num_tasks, futures.len())); assert_eq!(num_tasks, futures.len()); - let r = do vec::map_consume(futures) |ys| { + do futures.consume_iter().transform |ys| { let mut ys = ys; ys.get() - }; - r + }.collect() } } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 59aed0055d87e..97793ce440c2b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -477,7 +477,7 @@ fn run_tests(opts: &TestOpts, } // All benchmarks run at the end, in serial. - do vec::consume(filtered_benchs) |_, b| { + for filtered_benchs.consume_iter().advance |b| { callback(TeWait(copy b.desc)); run_test(!opts.run_benchmarks, b, ch.clone()); let (test, result) = p.recv(); @@ -523,7 +523,7 @@ pub fn filter_tests( } else { return option::None; } } - vec::filter_map(filtered, |x| filter_fn(x, filter_str)) + filtered.consume_iter().filter_map(|x| filter_fn(x, filter_str)).collect() }; // Maybe pull out the ignored test and unignore them @@ -541,7 +541,7 @@ pub fn filter_tests( None } }; - vec::filter_map(filtered, |x| filter(x)) + filtered.consume_iter().filter_map(|x| filter(x)).collect() }; // Sort the tests alphabetically @@ -720,9 +720,9 @@ impl BenchHarness { // Eliminate outliers let med = samples.median(); let mad = samples.median_abs_dev(); - let samples = do vec::filter(samples) |f| { + let samples = do samples.consume_iter().filter |f| { num::abs(*f - med) <= 3.0 * mad - }; + }.collect::<~[f64]>(); debug!("%u samples, median %f, MAD=%f, %u survived filter", n_samples, med as float, mad as float, diff --git a/src/libextra/uv_ll.rs b/src/libextra/uv_ll.rs index db960f334fdc9..69ff100784077 100644 --- a/src/libextra/uv_ll.rs +++ b/src/libextra/uv_ll.rs @@ -1046,7 +1046,7 @@ pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str { // ipv4 addr max size: 15 + 1 trailing null byte let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { rust_uv_ip4_name(to_unsafe_ptr(src), dst_buf, size as libc::size_t); // seems that checking the result of uv_ip4_name @@ -1066,7 +1066,7 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8]; - do vec::as_imm_buf(dst) |dst_buf, size| { + do dst.as_imm_buf |dst_buf, size| { let src_unsafe_ptr = to_unsafe_ptr(src); let result = rust_uv_ip6_name(src_unsafe_ptr, dst_buf, size as libc::size_t); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 61d39421b7fd0..a7abc61908038 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -893,7 +893,7 @@ pub fn link_args(sess: Session, // Add all the link args for external crates. do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); - do vec::consume(link_args) |_, link_arg| { + for link_args.consume_iter().advance |link_arg| { args.push(link_arg); } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index a32f54fe7bba4..3c50754744886 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -123,10 +123,10 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) -> // Convert strings provided as --cfg [cfgspec] into a crate_cfg fn parse_cfgspecs(cfgspecs: ~[~str], demitter: diagnostic::Emitter) -> ast::crate_cfg { - do vec::map_consume(cfgspecs) |s| { + do cfgspecs.consume_iter().transform |s| { let sess = parse::new_parse_sess(Some(demitter)); parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess) - } + }.collect() } pub enum input { diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index b1d4820f062eb..7d478afee41a1 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -10,7 +10,6 @@ use std::option; -use std::vec; use syntax::{ast, fold, attr}; type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool; @@ -61,13 +60,15 @@ fn filter_view_item(cx: @Context, view_item: @ast::view_item } fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod { - let filtered_items = - m.items.filter_mapped(|a| filter_item(cx, *a)); - let filtered_view_items = - m.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = do m.items.iter().filter_map |a| { + filter_item(cx, *a).chain(|x| fld.fold_item(x)) + }.collect(); + let filtered_view_items = do m.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::_mod { - view_items: filtered_view_items.map(|x| fld.fold_view_item(*x)), - items: vec::filter_map(filtered_items, |x| fld.fold_item(x)) + view_items: filtered_view_items, + items: filtered_items } } @@ -83,14 +84,14 @@ fn fold_foreign_mod( nm: &ast::foreign_mod, fld: @fold::ast_fold ) -> ast::foreign_mod { - let filtered_items = - nm.items.filter_mapped(|a| filter_foreign_item(cx, *a)); - let filtered_view_items = - nm.view_items.filter_mapped(|a| filter_view_item(cx, *a)); + let filtered_items = nm.items.iter().filter_map(|a| filter_foreign_item(cx, *a)).collect(); + let filtered_view_items = do nm.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: filtered_view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), + view_items: filtered_view_items, items: filtered_items } } @@ -99,11 +100,13 @@ fn fold_item_underscore(cx: @Context, item: &ast::item_, fld: @fold::ast_fold) -> ast::item_ { let item = match *item { ast::item_impl(ref a, b, c, ref methods) => { - let methods = methods.filtered(|m| method_in_cfg(cx, *m) ); + let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) + .transform(|x| *x).collect(); ast::item_impl(/*bad*/ copy *a, b, c, methods) } ast::item_trait(ref a, ref b, ref methods) => { - let methods = methods.filtered(|m| trait_method_in_cfg(cx, m) ); + let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) ) + .transform(|x| /* bad */copy *x).collect(); ast::item_trait(/*bad*/copy *a, /*bad*/copy *b, methods) } ref item => /*bad*/ copy *item @@ -134,19 +137,12 @@ fn fold_block( b: &ast::blk_, fld: @fold::ast_fold ) -> ast::blk_ { - let filtered_stmts = - b.stmts.filter_mapped(|a| filter_stmt(cx, *a)); - let filtered_view_items = - b.view_items.filter_mapped(|a| filter_view_item(cx, *a)); - let filtered_view_items = - filtered_view_items.map(|x| fld.fold_view_item(*x)); - let mut resulting_stmts = ~[]; - for filtered_stmts.iter().advance |stmt| { - match fld.fold_stmt(*stmt) { - None => {} - Some(stmt) => resulting_stmts.push(stmt), - } - } + let resulting_stmts = do b.stmts.iter().filter_map |a| { + filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt)) + }.collect(); + let filtered_view_items = do b.view_items.iter().filter_map |a| { + filter_view_item(cx, *a).map(|x| fld.fold_view_item(*x)) + }.collect(); ast::blk_ { view_items: filtered_view_items, stmts: resulting_stmts, @@ -193,7 +189,9 @@ pub fn metas_in_cfg(cfg: &[@ast::meta_item], // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // so we can match against them. This is the list of configurations for // which the item is valid - let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i)); + let cfg_metas = cfg_metas.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>(); if cfg_metas.iter().all(|c| c.is_empty()) { return true; } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 41c70c4c5b417..91000d68aad09 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -109,9 +109,11 @@ fn fold_mod(cx: @mut TestCtxt, fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item { if !*cx.sess.building_library { - @ast::item{attrs: item.attrs.filtered(|attr| { - "main" != attr::get_attr_name(attr) - }),.. copy *item} + @ast::item{ + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), + .. copy *item} } else { item } } @@ -229,10 +231,10 @@ fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool { let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore"); let ignoreitems = attr::attr_metas(ignoreattrs); return if !ignoreitems.is_empty() { - let cfg_metas = - vec::concat( - vec::filter_map(ignoreitems, - |i| attr::get_meta_item_list(i))); + let cfg_metas = ignoreitems.consume_iter() + .filter_map(|i| attr::get_meta_item_list(i)) + .collect::<~[~[@ast::meta_item]]>() + .concat_vec(); config::metas_in_cfg(/*bad*/copy cx.crate.node.config, cfg_metas) } else { false diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c6d7314f1cd9f..72b6f8e1c805b 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -291,16 +291,16 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) { // inlined items. fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { fn drop_nested_items(blk: &ast::blk_, fld: @fold::ast_fold) -> ast::blk_ { - let stmts_sans_items = do blk.stmts.filtered |stmt| { + let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| { match stmt.node { ast::stmt_expr(_, _) | ast::stmt_semi(_, _) | - ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), - span: _}, _) => true, - ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), - span: _}, _) => false, + ast::stmt_decl(@codemap::spanned { node: ast::decl_local(_), span: _}, _) + => Some(*stmt), + ast::stmt_decl(@codemap::spanned { node: ast::decl_item(_), span: _}, _) + => None, ast::stmt_mac(*) => fail!("unexpanded macro in astencode") } - }; + }.collect(); let blk_sans_items = ast::blk_ { view_items: ~[], // I don't know if we need the view_items here, // but it doesn't break tests! diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 72896258b2d32..740499bbf25e6 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -95,7 +95,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { } _ => { /* We assume only enum types can be uninhabited */ } } - let arms = vec::concat(arms.filter_mapped(unguarded_pat)); + let arms = arms.iter().filter_map(unguarded_pat).collect::<~[~[@pat]]>().concat_vec(); if arms.is_empty() { cx.tcx.sess.span_err(ex.span, "non-exhaustive patterns"); } else { @@ -265,7 +265,7 @@ pub fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } Some(ref ctor) => { match is_useful(cx, - &m.filter_mapped(|r| default(cx, *r)), + &m.iter().filter_map(|r| default(cx, *r)).collect::(), v.tail()) { useful_ => useful(left_ty, /*bad*/copy *ctor), ref u => (/*bad*/copy *u) @@ -287,7 +287,7 @@ pub fn is_useful_specialized(cx: &MatchCheckCtxt, arity: uint, lty: ty::t) -> useful { - let ms = m.filter_mapped(|r| specialize(cx, *r, &ctor, arity, lty)); + let ms = m.iter().filter_map(|r| specialize(cx, *r, &ctor, arity, lty)).collect::(); let could_be_useful = is_useful( cx, &ms, specialize(cx, v, &ctor, arity, lty).get()); match could_be_useful { @@ -397,14 +397,14 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { // Find the lengths and slices of all vector patterns. - let vec_pat_lens = do m.filter_mapped |r| { + let vec_pat_lens = do m.iter().filter_map |r| { match r[0].node { pat_vec(ref before, ref slice, ref after) => { Some((before.len() + after.len(), slice.is_some())) } _ => None } - }; + }.collect::<~[(uint, bool)]>(); // Sort them by length such that for patterns of the same length, // those with a destructured slice come first. diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index e345a9d703c9c..ce9ab790b11b8 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -24,7 +24,6 @@ use std::u16; use std::u32; use std::u64; use std::u8; -use std::vec; use extra::smallintmap::SmallIntMap; use syntax::attr; use syntax::codemap::span; @@ -987,7 +986,7 @@ fn lint_session() -> visit::vt<@mut Context> { match cx.tcx.sess.lints.pop(&id) { None => {}, Some(l) => { - do vec::consume(l) |_, (lint, span, msg)| { + for l.consume_iter().advance |(lint, span, msg)| { cx.span_lint(lint, span, msg) } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6847e298a2cbd..ebd11e2f66856 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -41,7 +41,6 @@ use syntax::opt_vec::OptVec; use std::str; use std::uint; -use std::vec; use std::hashmap::{HashMap, HashSet}; use std::util; @@ -5360,7 +5359,7 @@ impl Resolver { if idents.len() == 0 { return ~"???"; } - return self.idents_to_str(vec::reversed(idents)); + return self.idents_to_str(idents.consume_rev_iter().collect::<~[ast::ident]>()); } pub fn dump_module(@mut self, module_: @mut Module) { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index ab813c0ffc546..4755f7629511e 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -131,13 +131,13 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let ftys = do fields.map |field| { + let mut ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) }; let packed = ty::lookup_packed(cx.tcx, def_id); let dtor = ty::ty_dtor(cx.tcx, def_id).has_drop_flag(); - let ftys = - if dtor { ftys + [ty::mk_bool()] } else { ftys }; + if dtor { ftys.push(ty::mk_bool()); } + return Univariant(mk_struct(cx, ftys, packed), dtor) } ty::ty_enum(def_id, ref substs) => { @@ -263,7 +263,7 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let padding = largest_size - most_aligned.size; struct_llfields(cx, most_aligned, sizing) - + [Type::array(&Type::i8(), padding)] + + &[Type::array(&Type::i8(), padding)] } } } @@ -512,7 +512,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int, let discr_ty = C_int(ccx, discr); let contents = build_const_struct(ccx, case, ~[discr_ty] + vals); - C_struct(contents + [padding(max_sz - case.size)]) + C_struct(contents + &[padding(max_sz - case.size)]) } NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { if discr == nndiscr { diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 8535c84c5cb5e..811138c6dbddf 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -565,7 +565,7 @@ pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong, let min = llvm::LLVMConstInt(t, lo, signed); let max = llvm::LLVMConstInt(t, hi, signed); - do vec::as_imm_buf([min, max]) |ptr, len| { + do [min, max].as_imm_buf |ptr, len| { llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint, llvm::LLVMMDNodeInContext(cx.fcx.ccx.llcx, ptr, len as c_uint)); @@ -942,7 +942,7 @@ pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { cx.val_to_str(Fn), Args.map(|arg| cx.val_to_str(*arg))); - do vec::as_imm_buf(Args) |ptr, len| { + do Args.as_imm_buf |ptr, len| { llvm::LLVMBuildCall(B(cx), Fn, ptr, len as c_uint, noname()) } } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 5b3052a1e1f4c..865fb26b94558 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -774,7 +774,7 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { pub fn C_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False) } } @@ -782,7 +782,7 @@ pub fn C_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True) } } @@ -790,7 +790,7 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef { unsafe { - do vec::as_imm_buf(elts) |ptr, len| { + do elts.as_imm_buf |ptr, len| { llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint) } } @@ -826,7 +826,7 @@ pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef { pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint]) -> ValueRef { unsafe { - let r = do vec::as_imm_buf(us) |p, len| { + let r = do us.as_imm_buf |p, len| { llvm::LLVMConstExtractValue(v, p, len as c_uint) }; diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index dc88ecbe936b0..75b1830778b1b 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -26,7 +26,6 @@ use util::ppaux; use middle::trans::type_::Type; use std::str; -use std::vec; use syntax::ast; use syntax::ast::ident; use syntax::ast_map::path_mod; @@ -190,9 +189,13 @@ pub fn trans_log(log_ex: &ast::expr, let (modpath, modname) = { let path = &mut bcx.fcx.path; - let modpath = vec::append( - ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))], - path.filtered(|e| match *e { path_mod(_) => true, _ => false })); + let mut modpath = ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))]; + for path.iter().advance |e| { + match *e { + path_mod(_) => { modpath.push(*e) } + _ => {} + } + } let modname = path_str(ccx.sess, modpath); (modpath, modname) }; diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index c01f01db5fd15..0a3b6d881e47c 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -113,7 +113,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { _ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type") }; let llsig = foreign_signature(ccx, &fn_sig); - let bundle_ty = Type::struct_(llsig.llarg_tys + [llsig.llret_ty.ptr_to()], false); + let bundle_ty = Type::struct_(llsig.llarg_tys + &[llsig.llret_ty.ptr_to()], false); let ret_def = !ty::type_is_bot(fn_sig.output) && !ty::type_is_nil(fn_sig.output); let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 9e227da49f837..04133bfe79acb 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -278,7 +278,7 @@ impl Reflector { let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm }); let make_get_disr = || { - let sub_path = bcx.fcx.path + [path_name(special_idents::anon)]; + let sub_path = bcx.fcx.path + &[path_name(special_idents::anon)]; let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, "get_disr"); diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index e52d33fc6e9ae..7878e17f7fc68 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -245,7 +245,7 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [*ty], false) + Type::struct_(Type::box_header_fields(ctx) + &[*ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 7655e173e4e26..0681cf867f13a 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -45,9 +45,9 @@ pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { } pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { - let doc_strs = do doc_metas(attrs).filter_mapped |meta| { - attr::get_meta_item_value_str(*meta).map(|s| s.to_owned()) - }; + let doc_strs = do doc_metas(attrs).consume_iter().filter_map |meta| { + attr::get_meta_item_value_str(meta).map(|s| s.to_owned()) + }.collect::<~[~str]>(); if doc_strs.is_empty() { None } else { diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index 2077516a9b56b..3fd6ad1699876 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -141,7 +141,7 @@ fn first_sentence_(s: &str) -> ~str { pub fn paragraphs(s: &str) -> ~[~str] { let mut whitespace_lines = 0; let mut accum = ~""; - let paras = do s.any_line_iter().fold(~[]) |paras, line| { + let mut paras = do s.any_line_iter().fold(~[]) |paras, line| { let mut res = paras; if line.is_whitespace() { @@ -166,11 +166,8 @@ pub fn paragraphs(s: &str) -> ~[~str] { res }; - if !accum.is_empty() { - paras + [accum] - } else { - paras - } + if !accum.is_empty() { paras.push(accum); } + paras } #[cfg(test)] diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index b45550c06e44a..ffb4642be8107 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -13,8 +13,6 @@ use doc; -use std::vec; - pub type AstId = int; #[deriving(Eq)] @@ -186,87 +184,64 @@ impl Doc { } } +macro_rules! filt_mapper { + ($vec:expr, $pat:pat) => { + do ($vec).iter().filter_map |thing| { + match thing { + &$pat => Some(copy *x), + _ => None + } + }.collect() + } +} + +macro_rules! md { + ($id:ident) => { + filt_mapper!(self.items, $id(ref x)) + } +} /// Some helper methods on ModDoc, mostly for testing impl ModDoc { pub fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ModTag(ModDoc) => Some(ModDoc), - _ => None - } - } + md!(ModTag) } pub fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - NmodTag(nModDoc) => Some(nModDoc), - _ => None - } - } + md!(NmodTag) } pub fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - FnTag(FnDoc) => Some(FnDoc), - _ => None - } - } + md!(FnTag) } pub fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ConstTag(ConstDoc) => Some(ConstDoc), - _ => None - } - } + md!(ConstTag) } pub fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - EnumTag(EnumDoc) => Some(EnumDoc), - _ => None - } - } + md!(EnumTag) } pub fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TraitTag(TraitDoc) => Some(TraitDoc), - _ => None - } - } + md!(TraitTag) } pub fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - ImplTag(ImplDoc) => Some(ImplDoc), - _ => None - } - } + md!(ImplTag) } pub fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - TyTag(TyDoc) => Some(TyDoc), - _ => None - } - } + md!(TyTag) } pub fn structs(&self) -> ~[StructDoc] { - do vec::filter_mapped(self.items) |itemtag| { - match copy *itemtag { - StructTag(StructDoc) => Some(StructDoc), - _ => None - } - } + md!(StructTag) + } +} + +macro_rules! pu { + ($id:ident) => { + filt_mapper!(*self, ItemPage($id(ref x))) } } @@ -284,75 +259,35 @@ pub trait PageUtils { impl PageUtils for ~[Page] { fn mods(&self) -> ~[ModDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ModTag(ModDoc)) => Some(ModDoc), - _ => None - } - } + pu!(ModTag) } fn nmods(&self) -> ~[NmodDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(NmodTag(nModDoc)) => Some(nModDoc), - _ => None - } - } + pu!(NmodTag) } fn fns(&self) -> ~[FnDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(FnTag(FnDoc)) => Some(FnDoc), - _ => None - } - } + pu!(FnTag) } fn consts(&self) -> ~[ConstDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), - _ => None - } - } + pu!(ConstTag) } fn enums(&self) -> ~[EnumDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), - _ => None - } - } + pu!(EnumTag) } fn traits(&self) -> ~[TraitDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), - _ => None - } - } + pu!(TraitTag) } fn impls(&self) -> ~[ImplDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), - _ => None - } - } + pu!(ImplTag) } fn types(&self) -> ~[TyDoc] { - do vec::filter_mapped(*self) |page| { - match copy *page { - ItemPage(TyTag(TyDoc)) => Some(TyDoc), - _ => None - } - } + pu!(TyTag) } } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index d5d2b4ce6286c..01b77a985fedb 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -15,7 +15,6 @@ use astsrv; use doc::ItemUtils; use doc; -use std::vec; use syntax::ast; use syntax::parse::token::{ident_interner, ident_to_str}; use syntax::parse::token; @@ -83,7 +82,7 @@ fn moddoc_from_mod( ) -> doc::ModDoc { doc::ModDoc { item: itemdoc, - items: do vec::filter_mapped(module_.items) |item| { + items: do module_.items.iter().filter_map |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match copy item.node { ast::item_mod(m) => { @@ -133,7 +132,7 @@ fn moddoc_from_mod( } _ => None } - }, + }.collect(), index: None } } diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 0705a5c17233e..f800a8ab946fe 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -172,7 +172,7 @@ pub fn header_kind(doc: doc::ItemTag) -> ~str { } pub fn header_name(doc: doc::ItemTag) -> ~str { - let fullpath = (doc.path() + [doc.name()]).connect("::"); + let fullpath = (doc.path() + &[doc.name()]).connect("::"); match &doc { &doc::ModTag(_) if doc.id() != syntax::ast::crate_node_id => { fullpath diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 9621ea0892b94..d757547d8f76f 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -163,7 +163,7 @@ pub fn make_filename( } } doc::ItemPage(doc) => { - (doc.path() + [doc.name()]).connect("_") + (doc.path() + &[doc.name()]).connect("_") } } }; diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 508cf302ede56..83a0d44978ec4 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -128,13 +128,12 @@ fn fold_mod( fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc { doc::ModDoc { - items: do doc.items.filtered |item| { - match *item { - doc::ModTag(_) => false, - doc::NmodTag(_) => false, + items: do doc.items.iter().filter |item| { + match **item { + doc::ModTag(_) | doc::NmodTag(_) => false, _ => true } - }, + }.transform(|x| copy *x).collect::<~[doc::ItemTag]>(), .. copy doc } } diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs index 484eb8c7980dc..96c5df10680cc 100644 --- a/src/librustdoc/prune_hidden_pass.rs +++ b/src/librustdoc/prune_hidden_pass.rs @@ -41,9 +41,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: do doc.items.filtered |ItemTag| { - !is_hidden(fold.ctxt.clone(), ItemTag.item()) - }, + items: do doc.items.iter().filter |item_tag| { + !is_hidden(fold.ctxt.clone(), item_tag.item()) + }.transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index cb7da801e96ec..aeb6e02f244f1 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -80,7 +80,7 @@ fn strip_priv_methods( methods: &[@ast::method], item_vis: ast::visibility ) -> doc::ImplDoc { - let methods = do (&doc.methods).filtered |method| { + let methods = do doc.methods.iter().filter |method| { let ast_method = do methods.iter().find_ |m| { extract::to_str(m.ident) == method.name }; @@ -91,7 +91,7 @@ fn strip_priv_methods( ast::private => false, ast::inherited => item_vis == ast::public } - }; + }.transform(|x| copy *x).collect(); doc::ImplDoc { methods: methods, @@ -106,9 +106,9 @@ fn fold_mod( let doc = fold::default_any_fold_mod(fold, doc); doc::ModDoc { - items: doc.items.filtered(|ItemTag| { - match ItemTag { - &doc::ImplTag(ref doc) => { + items: doc.items.iter().filter(|item_tag| { + match item_tag { + & &doc::ImplTag(ref doc) => { if doc.trait_types.is_empty() { // This is an associated impl. We have already pruned the // non-visible methods. If there are any left then @@ -123,10 +123,10 @@ fn fold_mod( } } _ => { - is_visible(fold.ctxt.clone(), ItemTag.item()) + is_visible(fold.ctxt.clone(), item_tag.item()) } } - }), + }).transform(|x| copy *x).collect(), .. doc } } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 669e5042d3bf5..1e99a3fa4bcda 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -77,9 +77,9 @@ fn fold_mod(_ctx: @mut ReadyCtx, fold: @fold::ast_fold) -> ast::_mod { fn strip_main(item: @ast::item) -> @ast::item { @ast::item { - attrs: do item.attrs.filtered |attr| { - "main" != attr::get_attr_name(attr) - }, + attrs: do item.attrs.iter().filter_map |attr| { + if "main" != attr::get_attr_name(attr) {Some(*attr)} else {None} + }.collect(), .. copy *item } } diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index dd2cf445302a4..5876dbdc9dea1 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -34,6 +34,7 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b } pub fn pkg_parent_workspaces(pkgid: &PkgId) -> ~[Path] { - rust_path().filtered(|ws| - workspace_contains_package_id(pkgid, ws)) + rust_path().consume_iter() + .filter(|ws| workspace_contains_package_id(pkgid, ws)) + .collect() } diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 325ce097cd5a0..37a32d6b0f008 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -17,8 +17,7 @@ use kinds::Copy; use option::Option; use sys; use uint; -use vec; -use vec::ImmutableVector; +use vec::{ImmutableVector, OwnedVector}; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. @@ -159,7 +158,7 @@ pub fn to_managed_consume(v: ~[T]) -> @[T] { let mut av = @[]; unsafe { raw::reserve(&mut av, v.len()); - do vec::consume(v) |_i, x| { + for v.consume_iter().advance |x| { raw::push(&mut av, x); } transmute(av) @@ -177,13 +176,14 @@ pub fn to_managed(v: &[T]) -> @[T] { #[cfg(not(test))] pub mod traits { use at_vec::append; + use vec::Vector; use kinds::Copy; use ops::Add; - impl<'self,T:Copy> Add<&'self [T],@[T]> for @[T] { + impl<'self,T:Copy, V: Vector> Add for @[T] { #[inline] - fn add(&self, rhs: & &'self [T]) -> @[T] { - append(*self, (*rhs)) + fn add(&self, rhs: &V) -> @[T] { + append(*self, rhs.as_slice()) } } } @@ -313,7 +313,7 @@ mod test { #[test] fn append_test() { - assert_eq!(@[1,2,3] + [4,5,6], @[1,2,3,4,5,6]); + assert_eq!(@[1,2,3] + &[4,5,6], @[1,2,3,4,5,6]); } #[test] diff --git a/src/libstd/either.rs b/src/libstd/either.rs index b6da93f9d40ab..8b9b3102831c6 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -73,7 +73,7 @@ pub fn rights(eithers: &[Either]) -> ~[U] { pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { let mut lefts: ~[T] = ~[]; let mut rights: ~[U] = ~[]; - do vec::consume(eithers) |_i, elt| { + for eithers.consume_iter().advance |elt| { match elt { Left(l) => lefts.push(l), Right(r) => rights.push(r) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 85dca1154bc09..2d80dc2be152d 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -24,7 +24,7 @@ use rand::RngUtil; use rand; use uint; use vec; -use vec::{ImmutableVector, MutableVector}; +use vec::{ImmutableVector, MutableVector, OwnedVector}; use kinds::Copy; use util::{replace, unreachable}; @@ -175,7 +175,8 @@ impl HashMap { vec::from_fn(new_capacity, |_| None)); self.size = 0; - do vec::consume(old_buckets) |_, bucket| { + // consume_rev_iter is more efficient + for old_buckets.consume_rev_iter().advance |bucket| { self.insert_opt_bucket(bucket); } } @@ -441,7 +442,7 @@ impl HashMap { vec::from_fn(INITIAL_CAPACITY, |_| None)); self.size = 0; - do vec::consume(buckets) |_, bucket| { + for buckets.consume_iter().advance |bucket| { match bucket { None => {}, Some(Bucket{key, value, _}) => { diff --git a/src/libstd/io.rs b/src/libstd/io.rs index bdcad15f45c44..38826dd411b68 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -917,7 +917,7 @@ fn convert_whence(whence: SeekStyle) -> i32 { impl Reader for *libc::FILE { fn read(&self, bytes: &mut [u8], len: uint) -> uint { unsafe { - do vec::as_mut_buf(bytes) |buf_p, buf_len| { + do bytes.as_mut_buf |buf_p, buf_len| { assert!(buf_len >= len); let count = libc::fread(buf_p as *mut c_void, 1u as size_t, @@ -1152,7 +1152,7 @@ impl Writer for Wrapper { impl Writer for *libc::FILE { fn write(&self, v: &[u8]) { unsafe { - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, @@ -1203,7 +1203,7 @@ impl Writer for fd_t { fn write(&self, v: &[u8]) { unsafe { let mut count = 0u; - do vec::as_imm_buf(v) |vbuf, len| { + do v.as_imm_buf |vbuf, len| { while count < len { let vb = ptr::offset(vbuf, count) as *c_void; let nout = libc::write(*self, vb, len as size_t); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 39041b483697a..be0c504885b31 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -92,7 +92,7 @@ pub fn as_c_charp(s: &str, f: &fn(*c_char) -> T) -> T { pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool) -> Option<~str> { let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char); - do vec::as_mut_buf(buf) |b, sz| { + do buf.as_mut_buf |b, sz| { if f(b, sz as size_t) { unsafe { Some(str::raw::from_buf(b as *u8)) @@ -122,7 +122,7 @@ pub mod win32 { while !done { let mut k: DWORD = 0; let mut buf = vec::from_elem(n as uint, 0u16); - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { k = f(b, TMPBUF_SZ as DWORD); if k == (0 as DWORD) { done = true; @@ -147,7 +147,7 @@ pub mod win32 { let mut t = s.to_utf16(); // Null terminate before passing on. t.push(0u16); - vec::as_imm_buf(t, |buf, _len| f(buf)) + t.as_imm_buf(|buf, _len| f(buf)) } } @@ -777,9 +777,9 @@ pub fn list_dir(p: &Path) -> ~[~str] { strings } } - do get_list(p).filtered |filename| { - *filename != ~"." && *filename != ~".." - } + do get_list(p).consume_iter().filter |filename| { + "." != *filename && ".." != *filename + }.collect() } } @@ -937,7 +937,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool { let mut done = false; let mut ok = true; while !done { - do vec::as_mut_buf(buf) |b, _sz| { + do buf.as_mut_buf |b, _sz| { let nread = libc::fread(b as *mut c_void, 1u as size_t, bufsize as size_t, istream); @@ -1683,7 +1683,7 @@ mod tests { let s = ~"hello"; let mut buf = s.as_bytes_with_null().to_owned(); let len = buf.len(); - do vec::as_mut_buf(buf) |b, _len| { + do buf.as_mut_buf |b, _len| { assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, (s.len() + 1u) as size_t, ostream), len as size_t) diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 9d50520996093..db534cca971a5 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -72,7 +72,7 @@ pub use tuple::{CloneableTuple10, CloneableTuple11, CloneableTuple12}; pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTuple5}; pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9}; pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; -pub use vec::{VectorVector, CopyableVector, ImmutableVector}; +pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector}; pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 473f56ddd7984..aee6f1bd204e3 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -406,7 +406,7 @@ pub mod ptr_tests { do str::as_c_str(s1) |p1| { do str::as_c_str(s2) |p2| { let v = ~[p0, p1, p2, null()]; - do vec::as_imm_buf(v) |vp, len| { + do v.as_imm_buf |vp, len| { assert_eq!(unsafe { buf_len(vp) }, 3u); assert_eq!(len, 4u); } diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 5782822bc2b77..5054763d742b0 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -830,7 +830,7 @@ pub fn seed() -> ~[u8] { unsafe { let n = rustrt::rand_seed_size() as uint; let mut s = vec::from_elem(n, 0_u8); - do vec::as_mut_buf(s) |p, sz| { + do s.as_mut_buf |p, sz| { rustrt::rand_gen_seed(p, sz as size_t) } s @@ -1087,7 +1087,7 @@ mod tests { for 10.times { unsafe { let seed = super::seed(); - let rt_rng = do vec::as_imm_buf(seed) |p, sz| { + let rt_rng = do seed.as_imm_buf |p, sz| { rustrt::rand_new_seeded(p, sz as size_t) }; let mut rng = IsaacRng::new_seeded(seed); diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs index f50efc079a7c7..092d736620268 100644 --- a/src/libstd/rt/uv/mod.rs +++ b/src/libstd/rt/uv/mod.rs @@ -40,6 +40,7 @@ use str::raw::from_c_str; use to_str::ToStr; use ptr::RawPtr; use vec; +use vec::ImmutableVector; use ptr; use str; use libc::{c_void, c_int, size_t, malloc, free}; @@ -300,7 +301,7 @@ pub fn vec_to_uv_buf(v: ~[u8]) -> Buf { unsafe { let data = malloc(v.len() as size_t) as *u8; assert!(data.is_not_null()); - do vec::as_imm_buf(v) |b, l| { + do v.as_imm_buf |b, l| { let data = data as *mut u8; ptr::copy_memory(data, b, l) } diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 9e5def253c7ed..df15111a91f42 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -24,7 +24,7 @@ use prelude::*; use ptr; use str; use task; -use vec; +use vec::ImmutableVector; /** * A value representing a child process. @@ -703,7 +703,7 @@ fn with_argv(prog: &str, args: &[~str], argptrs.push(str::as_c_str(*t, |b| b)); } argptrs.push(ptr::null()); - vec::as_imm_buf(argptrs, |buf, _len| cb(buf)) + argptrs.as_imm_buf(|buf, _len| cb(buf)) } #[cfg(unix)] @@ -722,7 +722,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T { } ptrs.push(ptr::null()); - vec::as_imm_buf(ptrs, |p, _len| + ptrs.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } @@ -743,7 +743,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T { blk.push_all(kv.as_bytes_with_null_consume()); } blk.push(0); - vec::as_imm_buf(blk, |p, _len| + blk.as_imm_buf(|p, _len| unsafe { cb(::cast::transmute(p)) } ) } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 28162cf5117ca..564c58f7097ee 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -826,6 +826,7 @@ pub mod raw { use str::raw; use str::{as_buf, is_utf8}; use vec; + use vec::MutableVector; /// Create a Rust string from a null-terminated *u8 buffer pub unsafe fn from_buf(buf: *u8) -> ~str { @@ -841,7 +842,7 @@ pub mod raw { /// Create a Rust string from a *u8 buffer of the given length pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str { let mut v: ~[u8] = vec::with_capacity(len + 1); - vec::as_mut_buf(v, |vbuf, _len| { + v.as_mut_buf(|vbuf, _len| { ptr::copy_memory(vbuf, buf as *u8, len) }); vec::raw::set_len(&mut v, len); @@ -863,7 +864,7 @@ pub mod raw { /// Converts a vector of bytes to a new owned string. pub unsafe fn from_bytes(v: &[u8]) -> ~str { - do vec::as_imm_buf(v) |buf, len| { + do v.as_imm_buf |buf, len| { from_buf_len(buf, len) } } @@ -917,7 +918,7 @@ pub mod raw { assert!((end <= n)); let mut v = vec::with_capacity(end - begin + 1u); - do vec::as_imm_buf(v) |vbuf, _vlen| { + do v.as_imm_buf |vbuf, _vlen| { let vbuf = ::cast::transmute_mut_unsafe(vbuf); let src = ptr::offset(sbuf, begin); ptr::copy_memory(vbuf, src, end - begin); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 28532bd54e36f..fb9c47b43733b 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -16,14 +16,13 @@ use cast::transmute; use cast; use container::{Container, Mutable}; use cmp; -use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; +use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; use kinds::Copy; use libc; use libc::c_void; use num::Zero; -use ops::Add; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; @@ -40,8 +39,6 @@ use unstable::intrinsics::{get_tydesc, contains_managed}; use vec; use util; -#[cfg(not(test))] use cmp::Equiv; - #[doc(hidden)] pub mod rustrt { use libc; @@ -74,7 +71,7 @@ pub fn same_length(xs: &[T], ys: &[U]) -> bool { pub fn from_fn(n_elts: uint, op: &fn(uint) -> T) -> ~[T] { unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i: uint = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i)); @@ -99,7 +96,7 @@ pub fn from_elem(n_elts: uint, t: T) -> ~[T] { // vec::with_capacity/ptr::set_memory for primitive types. unsafe { let mut v = with_capacity(n_elts); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let mut i = 0u; while i < n_elts { intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t); @@ -176,165 +173,69 @@ pub fn build_sized_opt(size: Option, build_sized(size.get_or_default(4), builder) } -// Accessors - -/// Copies +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function. +pub struct VecSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool +} -/// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } +impl<'self, T> Iterator<&'self [T]> for VecSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } - let mut start = 0u; - let mut result = ~[]; - while start < ln { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - start += i + 1u; - } + if self.n == 0 { + self.finished = true; + return Some(self.v); } - } - result.push(v.slice(start, ln).to_owned()); - result -} -/** - * Split the vector `v` by applying each element against the predicate `f` up - * to `n` times. - */ -pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } - - let mut start = 0u; - let mut count = n; - let mut result = ~[]; - while start < ln && count > 0u { - match v.slice(start, ln).iter().position_(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(start, start + i).to_owned()); - // Make sure to skip the separator. - start += i + 1u; - count -= 1u; + match self.v.iter().position_(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) + } + Some(idx) => { + let ret = Some(self.v.slice(0, idx)); + self.v = self.v.slice(idx + 1, self.v.len()); + self.n -= 1; + ret } } } - result.push(v.slice(start, ln).to_owned()); - result } -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f`. - */ -pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0) { return ~[] } - - let mut end = ln; - let mut result = ~[]; - while end > 0 { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1, end).to_owned()); - end = i; - } - } - } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result +/// An iterator over the slices of a vector separated by elements that +/// match a predicate function, from back to front. +pub struct VecRSplitIterator<'self, T> { + priv v: &'self [T], + priv n: uint, + priv pred: &'self fn(t: &T) -> bool, + priv finished: bool } -/** - * Reverse split the vector `v` by applying each element against the predicate - * `f` up to `n times. - */ -pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { - let ln = v.len(); - if (ln == 0u) { return ~[] } +impl<'self, T> Iterator<&'self [T]> for VecRSplitIterator<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.finished { return None; } - let mut end = ln; - let mut count = n; - let mut result = ~[]; - while end > 0u && count > 0u { - match v.slice(0, end).rposition(|t| f(t)) { - None => break, - Some(i) => { - result.push(v.slice(i + 1u, end).to_owned()); - // Make sure to skip the separator. - end = i; - count -= 1u; - } + if self.n == 0 { + self.finished = true; + return Some(self.v); } - } - result.push(v.slice(0u, end).to_owned()); - result.reverse(); - result -} -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vector is traversed from the start to the end. -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -/// -/// # Examples -/// -/// ~~~ {.rust} -/// let v = ~[~"a", ~"b"]; -/// do vec::consume(v) |i, s| { -/// // s has type ~str, not &~str -/// io::println(s + fmt!(" %d", i)); -/// } -/// ~~~ -pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - for uint::range(0, ln) |i| { - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); + match self.v.rposition(|x| (self.pred)(x)) { + None => { + self.finished = true; + Some(self.v) } - } - - raw::set_len(&mut v, 0); - } -} - -/// Consumes all elements, in a vector, moving them out into the / closure -/// provided. The vectors is traversed in reverse order (from end to start). -/// -/// This method does not impose any requirements on the type of the vector being -/// consumed, but it prevents any usage of the vector after this function is -/// called. -pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { - unsafe { - do as_mut_buf(v) |p, ln| { - let mut i = ln; - while i > 0 { - i -= 1; - - // NB: This unsafe operation counts on init writing 0s to the - // holes we create in the vector. That ensures that, if the - // iterator fails then we won't try to clean up the consumed - // elements during unwinding - let x = intrinsics::init(); - let p = ptr::mut_offset(p, i); - f(i, ptr::replace_ptr(p, x)); + Some(idx) => { + let ret = Some(self.v.slice(idx + 1, self.v.len())); + self.v = self.v.slice(0, idx); + self.n -= 1; + ret } } - - raw::set_len(&mut v, 0); } } @@ -360,20 +261,6 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { // Functional utilities -/// Consumes a vector, mapping it into a different vector. This function takes -/// ownership of the supplied vector `v`, moving each element into the closure -/// provided to generate a new element. The vector of new elements is then -/// returned. -/// -/// The original vector `v` cannot be used after this function call (it is moved -/// inside), but there are no restrictions on the type of the vector. -pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { - let mut result = ~[]; - do consume(v) |_i, x| { - result.push(f(x)); - } - result -} /** * Apply a function to each element of a vector and return a concatenation * of each result vector @@ -384,79 +271,6 @@ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { result } -pub fn filter_map( - v: ~[T], - f: &fn(t: T) -> Option) -> ~[U] -{ - /*! - * - * Apply a function to each element of a vector and return the results. - * Consumes the input vector. If function `f` returns `None` then that - * element is excluded from the resulting vector. - */ - - let mut result = ~[]; - do consume(v) |_, elem| { - match f(elem) { - None => {} - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -pub fn filter_mapped( - v: &[T], - f: &fn(t: &T) -> Option) -> ~[U] -{ - /*! - * - * Like `filter_map()`, but operates on a borrowed slice - * and does not consume the input. - */ - - let mut result = ~[]; - for v.iter().advance |elem| { - match f(elem) { - None => {/* no-op */ } - Some(result_elem) => { result.push(result_elem); } - } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - // FIXME (#4355 maybe): using v.consume here crashes - // do v.consume |_, elem| { - do consume(v) |_, elem| { - if f(&elem) { result.push(elem); } - } - result -} - -/** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector containing - * only those elements for which `f` returned true. - */ -pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { - let mut result = ~[]; - for v.iter().advance |elem| { - if f(elem) { result.push(copy *elem); } - } - result -} - /// Flattens a vector of vectors of T into a single vector of T. pub fn concat(v: &[~[T]]) -> ~[T] { v.concat_vec() } @@ -542,7 +356,7 @@ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[]; let mut us = ~[]; - do consume(v) |_i, p| { + for v.consume_iter().advance |p| { let (t, u) = p; ts.push(t); us.push(u); @@ -584,16 +398,6 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { w } -/// Returns a vector with the order of elements reversed -pub fn reversed(v: &[T]) -> ~[T] { - let mut rs: ~[T] = ~[]; - let mut i = v.len(); - if i == 0 { return (rs); } else { i -= 1; } - while i != 0 { rs.push(copy v[i]); i -= 1; } - rs.push(copy v[0]); - rs -} - /** * Iterate over all permutations of vector `v`. * @@ -648,251 +452,222 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> } } -/** - * Iterate over all contiguous windows of length `n` of the vector `v`. - * - * # Example - * - * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`) - * - * ~~~ {.rust} - * for windowed(2, &[1,2,3,4]) |v| { - * io::println(fmt!("%?", v)); - * } - * ~~~ - * - */ -pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { - assert!(1u <= n); - if n > v.len() { return true; } - for uint::range(0, v.len() - n + 1) |i| { - if !it(v.slice(i, i + n)) { return false; } - } - return true; +/// An iterator over the (overlapping) slices of length `size` within +/// a vector. +pub struct VecWindowIter<'self, T> { + priv v: &'self [T], + priv size: uint } -/** - * Work with the buffer of a vector. - * - * Allows for unsafe manipulation of vector contents, which is useful for - * foreign interop. - */ -#[inline] -pub fn as_imm_buf(s: &[T], - /* NB---this CANNOT be const, see below */ - f: &fn(*T, uint) -> U) -> U { - - // NB---Do not change the type of s to `&const [T]`. This is - // unsound. The reason is that we are going to create immutable pointers - // into `s` and pass them to `f()`, but in fact they are potentially - // pointing at *mutable memory*. Use `as_const_buf` or `as_mut_buf` - // instead! - - unsafe { - let v : *(*T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) +impl<'self, T> Iterator<&'self [T]> for VecWindowIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size > self.v.len() { + None + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(1, self.v.len()); + ret + } } } -/// Similar to `as_imm_buf` but passing a `*mut T` -#[inline] -pub fn as_mut_buf(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { - unsafe { - let v : *(*mut T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) +/// An iterator over a vector in (non-overlapping) chunks (`size` +/// elements at a time). +pub struct VecChunkIter<'self, T> { + priv v: &'self [T], + priv size: uint +} + +impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> { + fn next(&mut self) -> Option<&'self [T]> { + if self.size == 0 { + None + } else if self.size >= self.v.len() { + // finished + self.size = 0; + Some(self.v) + } else { + let ret = Some(self.v.slice(0, self.size)); + self.v = self.v.slice(self.size, self.v.len()); + ret + } } } // Equality -/// Tests whether two slices are equal to one another. This is only true if both -/// slices are of the same length, and each of the corresponding elements return -/// true when queried via the `eq` function. -fn eq(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } +#[cfg(not(test))] +pub mod traits { + use super::Vector; + use kinds::Copy; + use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv}; + use ops::Add; - let mut i = 0; - while i < a_len { - if a[i] != b[i] { return false; } - i += 1; + impl<'self,T:Eq> Eq for &'self [T] { + fn eq(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| *s == *o) + } + #[inline] + fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } } - true -} - -/// Similar to the `vec::eq` function, but this is defined for types which -/// implement `TotalEq` as opposed to types which implement `Eq`. Equality -/// comparisons are done via the `equals` function instead of `eq`. -fn equals(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - if a_len != b_len { return false; } - let mut i = 0; - while i < a_len { - if !a[i].equals(&b[i]) { return false; } - i += 1; + impl Eq for ~[T] { + #[inline] + fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } - true -} - -#[cfg(not(test))] -impl<'self,T:Eq> Eq for &'self [T] { - #[inline] - fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } -} -#[cfg(not(test))] -impl Eq for ~[T] { - #[inline] - fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl Eq for @[T] { - #[inline] - fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) } - #[inline] - fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } -} + impl Eq for @[T] { + #[inline] + fn eq(&self, other: &@[T]) -> bool { self.as_slice() == *other } + #[inline] + fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } + } -#[cfg(not(test))] -impl<'self,T:TotalEq> TotalEq for &'self [T] { - #[inline] - fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) } -} + impl<'self,T:TotalEq> TotalEq for &'self [T] { + fn equals(&self, other: & &'self [T]) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(s,o)| s.equals(o)) + } + } -#[cfg(not(test))] -impl TotalEq for ~[T] { - #[inline] - fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) } -} + impl TotalEq for ~[T] { + #[inline] + fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) } + } -#[cfg(not(test))] -impl TotalEq for @[T] { - #[inline] - fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) } -} + impl TotalEq for @[T] { + #[inline] + fn equals(&self, other: &@[T]) -> bool { self.as_slice().equals(&other.as_slice()) } + } -#[cfg(not(test))] -impl<'self,T:Eq> Equiv<~[T]> for &'self [T] { - #[inline] - fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } -} + impl<'self,T:Eq, V: Vector> Equiv for &'self [T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } -// Lexicographical comparison + impl<'self,T:Eq, V: Vector> Equiv for ~[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } -fn cmp(a: &[T], b: &[T]) -> Ordering { - let low = uint::min(a.len(), b.len()); + impl<'self,T:Eq, V: Vector> Equiv for @[T] { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } + } - for uint::range(0, low) |idx| { - match a[idx].cmp(&b[idx]) { - Greater => return Greater, - Less => return Less, - Equal => () + impl<'self,T:TotalOrd> TotalOrd for &'self [T] { + fn cmp(&self, other: & &'self [T]) -> Ordering { + for self.iter().zip(other.iter()).advance |(s,o)| { + match s.cmp(o) { + Equal => {}, + non_eq => { return non_eq; } + } + } + self.len().cmp(&other.len()) } } - a.len().cmp(&b.len()) -} - -#[cfg(not(test))] -impl<'self,T:TotalOrd> TotalOrd for &'self [T] { - #[inline] - fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } -} + impl TotalOrd for ~[T] { + #[inline] + fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } -#[cfg(not(test))] -impl TotalOrd for ~[T] { - #[inline] - fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } -} + impl TotalOrd for @[T] { + #[inline] + fn cmp(&self, other: &@[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + } -#[cfg(not(test))] -impl TotalOrd for @[T] { - #[inline] - fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } -} + impl<'self,T:Ord> Ord for &'self [T] { + fn lt(&self, other: & &'self [T]) -> bool { + for self.iter().zip(other.iter()).advance |(s,o)| { + if *s < *o { return true; } + if *s > *o { return false; } + } + self.len() < other.len() + } + #[inline] + fn le(&self, other: & &'self [T]) -> bool { !(*other < *self) } + #[inline] + fn ge(&self, other: & &'self [T]) -> bool { !(*self < *other) } + #[inline] + fn gt(&self, other: & &'self [T]) -> bool { *other < *self } + } -fn lt(a: &[T], b: &[T]) -> bool { - let (a_len, b_len) = (a.len(), b.len()); - let end = uint::min(a_len, b_len); + impl Ord for ~[T] { + #[inline] + fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() } + } - let mut i = 0; - while i < end { - let (c_a, c_b) = (&a[i], &b[i]); - if *c_a < *c_b { return true; } - if *c_a > *c_b { return false; } - i += 1; + impl Ord for @[T] { + #[inline] + fn lt(&self, other: &@[T]) -> bool { self.as_slice() < other.as_slice() } + #[inline] + fn le(&self, other: &@[T]) -> bool { self.as_slice() <= other.as_slice() } + #[inline] + fn ge(&self, other: &@[T]) -> bool { self.as_slice() >= other.as_slice() } + #[inline] + fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() } } - a_len < b_len + impl<'self,T:Copy, V: Vector> Add for &'self [T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } + impl> Add for ~[T] { + #[inline] + fn add(&self, rhs: &V) -> ~[T] { + let mut res = self.to_owned(); + res.push_all(rhs.as_slice()); + res + } + } } -fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } -fn ge(a: &[T], b: &[T]) -> bool { !lt(a, b) } -fn gt(a: &[T], b: &[T]) -> bool { lt(b, a) } +#[cfg(test)] +pub mod traits {} -#[cfg(not(test))] -impl<'self,T:Ord> Ord for &'self [T] { - #[inline] - fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } +/// Any vector that can be represented as a slice. +pub trait Vector { + /// Work with `self` as a slice. + fn as_slice<'a>(&'a self) -> &'a [T]; } - -#[cfg(not(test))] -impl Ord for ~[T] { - #[inline] - fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } +impl<'self,T> Vector for &'self [T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { *self } } - -#[cfg(not(test))] -impl Ord for @[T] { - #[inline] - fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } - #[inline] - fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) } - #[inline] - fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) } - #[inline] - fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } +impl Vector for ~[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } } - -#[cfg(not(test))] -impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] { - #[inline] - fn add(&self, rhs: & &'self [T]) -> ~[T] { - append(copy *self, (*rhs)) - } +impl Vector for @[T] { + #[inline(always)] + fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v } } impl<'self, T> Container for &'self [T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -900,13 +675,13 @@ impl Container for ~[T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_imm_buf(*self, |_p, len| len == 0u) + self.as_imm_buf(|_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_imm_buf(*self, |_p, len| len) + self.as_imm_buf(|_p, len| len) } } @@ -933,6 +708,14 @@ pub trait ImmutableVector<'self, T> { fn slice(&self, start: uint, end: uint) -> &'self [T]; fn iter(self) -> VecIterator<'self, T>; fn rev_iter(self) -> VecRevIterator<'self, T>; + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T>; + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>; + + fn window_iter(self, size: uint) -> VecWindowIter<'self, T>; + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T>; + fn head(&self) -> &'self T; fn head_opt(&self) -> Option<&'self T>; fn tail(&self) -> &'self [T]; @@ -943,12 +726,13 @@ pub trait ImmutableVector<'self, T> { fn last_opt(&self) -> Option<&'self T>; fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; unsafe fn unsafe_ref(&self, index: uint) -> *T; fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option; fn map(&self, &fn(t: &T) -> U) -> ~[U]; + + fn as_imm_buf(&self, f: &fn(*T, uint) -> U) -> U; } /// Extension methods for vectors @@ -958,7 +742,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn slice(&self, start: uint, end: uint) -> &'self [T] { assert!(start <= end); assert!(end <= self.len()); - do as_imm_buf(*self) |p, _len| { + do self.as_imm_buf |p, _len| { unsafe { transmute((ptr::offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -984,6 +768,101 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. + #[inline] + fn split_iter(self, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + self.splitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`, limited to splitting + /// at most `n` times. + #[inline] + fn splitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecSplitIterator<'self, T> { + VecSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred`. This starts at the + /// end of the vector and works backwards. + #[inline] + fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + self.rsplitn_iter(uint::max_value, pred) + } + /// Returns an iterator over the subslices of the vector which are + /// separated by elements that match `pred` limited to splitting + /// at most `n` times. This starts at the end of the vector and + /// works backwards. + #[inline] + fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T> { + VecRSplitIterator { + v: self, + n: n, + pred: pred, + finished: false + } + } + + /** + * Returns an iterator over all contiguous windows of length + * `size`. The windows overlap. If the vector is shorter than + * `size`, the iterator returns no values. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, + * `[3,4]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4]; + * for v.window_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn window_iter(self, size: uint) -> VecWindowIter<'self, T> { + assert!(size != 0); + VecWindowIter { v: self, size: size } + } + + /** + * + * Returns an iterator over `size` elements of the vector at a + * time. The chunks do not overlap. If `size` does not divide the + * length of the vector, then the last chunk will not have length + * `size`. + * + * # Failure + * + * Fails if `size` is 0. + * + * # Example + * + * Print the vector two elements at a time (i.e. `[1,2]`, + * `[3,4]`, `[5]`): + * + * ~~~ {.rust} + * let v = &[1,2,3,4,5]; + * for v.chunk_iter().advance |win| { + * io::println(fmt!("%?", win)); + * } + * ~~~ + * + */ + fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T> { + assert!(size != 0); + VecChunkIter { v: self, size: size } + } + /// Returns the first element of a vector, failing if the vector is empty. #[inline] fn head(&self) -> &'self T { @@ -1053,17 +932,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } - /** - * Apply a function to each element of a vector and return the results - * - * If function `f` returns `none` then that element is excluded from - * the resulting vector. - */ - #[inline] - fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { - filter_mapped(*self, f) - } - /// Returns a pointer to the element at the given index, without doing /// bounds checking. #[inline] @@ -1107,14 +975,36 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { self.iter().transform(f).collect() } -} -#[allow(missing_doc)] -pub trait ImmutableEqVector { - fn position_elem(&self, t: &T) -> Option; - fn rposition_elem(&self, t: &T) -> Option; - fn contains(&self, x: &T) -> bool; -} + /** + * Work with the buffer of a vector. + * + * Allows for unsafe manipulation of vector contents, which is useful for + * foreign interop. + */ + #[inline] + fn as_imm_buf(&self, + /* NB---this CANNOT be const, see below */ + f: &fn(*T, uint) -> U) -> U { + // NB---Do not change the type of s to `&const [T]`. This is + // unsound. The reason is that we are going to create immutable pointers + // into `s` and pass them to `f()`, but in fact they are potentially + // pointing at *mutable memory*. Use `as_mut_buf` instead! + + unsafe { + let v : *(*T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } +} + +#[allow(missing_doc)] +pub trait ImmutableEqVector { + fn position_elem(&self, t: &T) -> Option; + fn rposition_elem(&self, t: &T) -> Option; + fn contains(&self, x: &T) -> bool; +} impl<'self,T:Eq> ImmutableEqVector for &'self [T] { /// Find the first index containing a matching value @@ -1154,25 +1044,12 @@ impl<'self, T: TotalOrd> ImmutableTotalOrdVector for &'self [T] { #[allow(missing_doc)] pub trait ImmutableCopyableVector { - fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); unsafe fn unsafe_get(&self, elem: uint) -> T; } /// Extension methods for vectors impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { - /** - * Construct a new vector from the elements of a vector for which some - * predicate holds. - * - * Apply function `f` to each element of `v` and return a vector - * containing only those elements for which `f` returned true. - */ - #[inline] - fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { - filtered(*self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -1202,6 +1079,9 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { + fn consume_iter(self) -> VecConsumeIterator; + fn consume_rev_iter(self) -> VecConsumeRevIterator; + fn reserve(&mut self, n: uint); fn reserve_at_least(&mut self, n: uint); fn capacity(&self) -> uint; @@ -1218,14 +1098,37 @@ pub trait OwnedVector { fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); fn retain(&mut self, f: &fn(t: &T) -> bool); - fn consume(self, f: &fn(uint, v: T)); - fn consume_reverse(self, f: &fn(uint, v: T)); - fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T); } impl OwnedVector for ~[T] { + /// Creates a consuming iterator, that is, one that moves each + /// value out of the vector (from start to end). The vector cannot + /// be used after calling this. + /// + /// Note that this performs O(n) swaps, and so `consume_rev_iter` + /// (which just calls `pop` repeatedly) is more efficient. + /// + /// # Examples + /// + /// ~~~ {.rust} + /// let v = ~[~"a", ~"b"]; + /// for v.consume_iter().advance |s| { + /// // s has type ~str, not &~str + /// println(s); + /// } + /// ~~~ + fn consume_iter(self) -> VecConsumeIterator { + VecConsumeIterator { v: self, idx: 0 } + } + /// Creates a consuming iterator that moves out of the vector in + /// reverse order. Also see `consume_iter`, however note that this + /// is more efficient. + fn consume_rev_iter(self) -> VecConsumeRevIterator { + VecConsumeRevIterator { v: self } + } + /** * Reserves capacity for exactly `n` elements in the given vector. * @@ -1367,7 +1270,7 @@ impl OwnedVector for ~[T] { let new_len = self.len() + rhs.len(); self.reserve(new_len); unsafe { - do as_mut_buf(rhs) |p, len| { + do rhs.as_mut_buf |p, len| { for uint::range(0, len) |i| { let x = ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); @@ -1499,7 +1402,7 @@ impl OwnedVector for ~[T] { /// Shorten a vector, dropping excess elements. fn truncate(&mut self, newlen: uint) { - do as_mut_buf(*self) |p, oldlen| { + do self.as_mut_buf |p, oldlen| { assert!(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. @@ -1532,21 +1435,6 @@ impl OwnedVector for ~[T] { } } - #[inline] - fn consume(self, f: &fn(uint, v: T)) { - consume(self, f) - } - - #[inline] - fn consume_reverse(self, f: &fn(uint, v: T)) { - consume_reverse(self, f) - } - - #[inline] - fn filter(self, f: &fn(&T) -> bool) -> ~[T] { - filter(self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -1556,7 +1444,7 @@ impl OwnedVector for ~[T] { let mut lefts = ~[]; let mut rights = ~[]; - do self.consume |_, elt| { + for self.consume_iter().advance |elt| { if f(&elt) { lefts.push(elt); } else { @@ -1672,7 +1560,7 @@ impl OwnedEqVector for ~[T] { if self.len() == 0 { return; } let mut last_written = 0; let mut next_to_read = 1; - do as_mut_buf(*self) |p, ln| { + do self.as_mut_buf |p, ln| { // last_written < next_to_read <= ln while next_to_read < ln { // last_written < next_to_read < ln @@ -1726,6 +1614,8 @@ pub trait MutableVector<'self, T> { unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T; unsafe fn unsafe_set(&self, index: uint, val: T); + + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U; } impl<'self,T> MutableVector<'self, T> for &'self mut [T] { @@ -1734,7 +1624,7 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { assert!(start <= end); assert!(end <= self.len()); - do as_mut_buf(self) |p, _len| { + do self.as_mut_buf |p, _len| { unsafe { transmute((ptr::mut_offset(p, start), (end - start) * sys::nonzero_size_of::())) @@ -1807,6 +1697,17 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { unsafe fn unsafe_set(&self, index: uint, val: T) { *self.unsafe_mut_ref(index) = val; } + + /// Similar to `as_imm_buf` but passing a `*mut T` + #[inline] + fn as_mut_buf(&self, f: &fn(*mut T, uint) -> U) -> U { + unsafe { + let v : *(*mut T,uint) = transmute(self); + let (buf,len) = *v; + f(buf, len / sys::nonzero_size_of::()) + } + } + } /// Trait for ~[T] where T is Cloneable @@ -1856,7 +1757,7 @@ pub mod raw { use ptr; use sys; use unstable::intrinsics; - use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity}; + use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector}; use util; /// The internal representation of a (boxed) vector @@ -1944,7 +1845,7 @@ pub mod raw { */ #[inline] pub unsafe fn get(v: &[T], i: uint) -> T { - as_imm_buf(v, |p, _len| copy *ptr::offset(p, i)) + v.as_imm_buf(|p, _len| copy *ptr::offset(p, i)) } /** @@ -1955,7 +1856,7 @@ pub mod raw { #[inline] pub unsafe fn init_elem(v: &mut [T], i: uint, val: T) { let mut box = Some(val); - do as_mut_buf(v) |p, _len| { + do v.as_mut_buf |p, _len| { let box2 = util::replace(&mut box, None); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), box2.unwrap()); @@ -1975,7 +1876,7 @@ pub mod raw { pub unsafe fn from_buf_raw(ptr: *T, elts: uint) -> ~[T] { let mut dst = with_capacity(elts); set_len(&mut dst, elts); - as_mut_buf(dst, |p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); + dst.as_mut_buf(|p_dst, _len_dst| ptr::copy_memory(p_dst, ptr, elts)); dst } @@ -1991,8 +1892,8 @@ pub mod raw { assert!(dst.len() >= count); assert!(src.len() >= count); - do as_mut_buf(dst) |p_dst, _len_dst| { - do as_imm_buf(src) |p_src, _len_src| { + do dst.as_mut_buf |p_dst, _len_dst| { + do src.as_imm_buf |p_src, _len_src| { ptr::copy_memory(p_dst, p_src, count) } } @@ -2016,7 +1917,7 @@ pub mod bytes { impl<'self> MutableByteVector for &'self mut [u8] { #[inline] fn set_memory(self, value: u8) { - do vec::as_mut_buf(self) |p, len| { + do self.as_mut_buf |p, len| { unsafe { ptr::set_memory(p, value, len) }; } } @@ -2132,7 +2033,7 @@ macro_rules! iterator { } //iterator!{struct VecIterator -> *T, &'self T} -/// An iterator for iterating over a vector +/// An iterator for iterating over a vector. pub struct VecIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2141,7 +2042,7 @@ pub struct VecIterator<'self, T> { iterator!{impl VecIterator -> &'self T, 1} //iterator!{struct VecRevIterator -> *T, &'self T} -/// An iterator for iterating over a vector in reverse +/// An iterator for iterating over a vector in reverse. pub struct VecRevIterator<'self, T> { priv ptr: *T, priv end: *T, @@ -2150,7 +2051,7 @@ pub struct VecRevIterator<'self, T> { iterator!{impl VecRevIterator -> &'self T, -1} //iterator!{struct VecMutIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector +/// An iterator for mutating the elements of a vector. pub struct VecMutIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2159,7 +2060,7 @@ pub struct VecMutIterator<'self, T> { iterator!{impl VecMutIterator -> &'self mut T, 1} //iterator!{struct VecMutRevIterator -> *mut T, &'self mut T} -/// An iterator for mutating the elements of a vector in reverse +/// An iterator for mutating the elements of a vector in reverse. pub struct VecMutRevIterator<'self, T> { priv ptr: *mut T, priv end: *mut T, @@ -2167,6 +2068,49 @@ pub struct VecMutRevIterator<'self, T> { } iterator!{impl VecMutRevIterator -> &'self mut T, -1} +/// An iterator that moves out of a vector. +pub struct VecConsumeIterator { + priv v: ~[T], + priv idx: uint, +} + +impl Iterator for VecConsumeIterator { + fn next(&mut self) -> Option { + // this is peculiar, but is required for safety with respect + // to dtors. It traverses the first half of the vec, and + // removes them by swapping them with the last element (and + // popping), which results in the second half in reverse + // order, and so these can just be pop'd off. That is, + // + // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4, + // [5] -> 5, [] + + if self.v.is_empty() { + None + } else { + let l = self.v.len(); + if self.idx < l { + self.v.swap(self.idx, l - 1); + self.idx += 1; + } + + Some(self.v.pop()) + } + } +} + +/// An iterator that moves out of a vector in reverse order. +pub struct VecConsumeRevIterator { + priv v: ~[T] +} + +impl Iterator for VecConsumeRevIterator { + fn next(&mut self) -> Option { + if self.v.is_empty() { None } + else { Some(self.v.pop()) } + } +} + #[cfg(stage0)] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { @@ -2633,87 +2577,6 @@ mod tests { assert_eq!(w[4], 25u); } - #[test] - fn test_filter_mapped() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_mapped(v, square_if_odd_r); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: &int) -> Option { - if *i % 2 == 0 { - Some::(*i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_mapped(all_even, halve) == - all_even.map(halve_for_sure)); - assert_eq!(filter_mapped(all_odd1, halve), ~[]); - assert_eq!(filter_mapped(all_odd2, halve), ~[]); - assert_eq!(filter_mapped(mix, halve), mix_dest); - } - - #[test] - fn test_filter_map() { - // Test on-stack filter-map. - let mut v = ~[1u, 2u, 3u]; - let mut w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 2u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - - // Test on-heap filter-map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = filter_map(v, square_if_odd_v); - assert_eq!(w.len(), 3u); - assert_eq!(w[0], 1u); - assert_eq!(w[1], 9u); - assert_eq!(w[2], 25u); - - fn halve(i: int) -> Option { - if i % 2 == 0 { - Some::(i / 2) - } else { - None:: - } - } - fn halve_for_sure(i: &int) -> int { *i / 2 } - let all_even: ~[int] = ~[0, 2, 8, 6]; - let all_even0: ~[int] = copy all_even; - let all_odd1: ~[int] = ~[1, 7, 3]; - let all_odd2: ~[int] = ~[]; - let mix: ~[int] = ~[9, 2, 6, 7, 1, 0, 0, 3]; - let mix_dest: ~[int] = ~[1, 3, 0, 0]; - assert!(filter_map(all_even, halve) == - all_even0.map(halve_for_sure)); - assert_eq!(filter_map(all_odd1, halve), ~[]); - assert_eq!(filter_map(all_odd2, halve), ~[]); - assert_eq!(filter_map(mix, halve), mix_dest); - } - - #[test] - fn test_filter() { - assert_eq!(filter(~[1u, 2u, 3u], is_odd), ~[1u, 3u]); - assert_eq!(filter(~[1u, 2u, 4u, 8u, 16u], is_three), ~[]); - } - #[test] fn test_retain() { let mut v = ~[1, 2, 3, 4, 5]; @@ -2828,75 +2691,17 @@ mod tests { } #[test] - fn reverse_and_reversed() { + fn test_reverse() { let mut v: ~[int] = ~[10, 20]; assert_eq!(v[0], 10); assert_eq!(v[1], 20); v.reverse(); assert_eq!(v[0], 20); assert_eq!(v[1], 10); - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); - v[0] = 30; - assert_eq!(v2[0], 20); - // Make sure they work with 0-length vectors too. - - let v4 = reversed::([]); - assert_eq!(v4, ~[]); + let mut v3: ~[int] = ~[]; v3.reverse(); - } - - #[test] - fn reversed_mut() { - let v2 = reversed::([10, 20]); - assert_eq!(v2[0], 20); - assert_eq!(v2[1], 10); - } - - #[test] - fn test_split() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(split([], f), ~[]); - assert_eq!(split([1, 2], f), ~[~[1, 2]]); - assert_eq!(split([3, 1, 2], f), ~[~[], ~[1, 2]]); - assert_eq!(split([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert_eq!(split([1, 2, 3, 4, 3, 5], f), ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_splitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(splitn([], 1u, f), ~[]); - assert_eq!(splitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(splitn([3, 1, 2], 1u, f), ~[~[], ~[1, 2]]); - assert_eq!(splitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert!(splitn([1, 2, 3, 4, 3, 5], 1u, f) == - ~[~[1, 2], ~[4, 3, 5]]); - } - - #[test] - fn test_rsplit() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplit([], f), ~[]); - assert_eq!(rsplit([1, 2], f), ~[~[1, 2]]); - assert_eq!(rsplit([1, 2, 3], f), ~[~[1, 2], ~[]]); - assert!(rsplit([1, 2, 3, 4, 3, 5], f) == - ~[~[1, 2], ~[4], ~[5]]); - } - - #[test] - fn test_rsplitn() { - fn f(x: &int) -> bool { *x == 3 } - - assert_eq!(rsplitn([], 1u, f), ~[]); - assert_eq!(rsplitn([1, 2], 1u, f), ~[~[1, 2]]); - assert_eq!(rsplitn([1, 2, 3], 1u, f), ~[~[1, 2], ~[]]); - assert_eq!(rsplitn([1, 2, 3, 4, 3, 5], 1u, f), ~[~[1, 2, 3, 4], ~[5]]); + assert!(v3.is_empty()); } #[test] @@ -2939,31 +2744,6 @@ mod tests { assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]); } - #[test] - fn test_windowed () { - fn t(n: uint, expected: &[&[int]]) { - let mut i = 0; - for windowed(n, [1,2,3,4,5,6]) |v| { - assert_eq!(v, expected[i]); - i += 1; - } - - // check that we actually iterated the right number of times - assert_eq!(i, expected.len()); - } - t(3, &[&[1,2,3],&[2,3,4],&[3,4,5],&[4,5,6]]); - t(4, &[&[1,2,3,4],&[2,3,4,5],&[3,4,5,6]]); - t(7, &[]); - t(8, &[]); - } - - #[test] - #[should_fail] - #[ignore(cfg(windows))] - fn test_windowed_() { - for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {} - } - #[test] fn test_unshift() { let mut x = ~[1, 2, 3]; @@ -3064,156 +2844,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_split_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do splitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_splitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do split(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplit_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplit(v) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_true() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - true - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_rsplitn_fail_ret_false() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do rsplitn(v, 100) |_elt| { - if i == 2 { - fail!() - } - i += 1; - - false - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - fn test_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do consume(v) |_i, _elt| { - if i == 2 { - fail!() - } - i += 1; - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3243,21 +2873,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_map_consume_fail() { - let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do map_consume(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - ~[(~0, @0)] - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3273,38 +2888,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_mapped_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do filter_mapped(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - Some((~0, @0)) - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_filter_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do v.filtered |_elt| { - if i == 2 { - fail!() - } - i += 0; - true - }; - } - #[test] #[ignore(windows)] #[should_fail] @@ -3340,7 +2923,7 @@ mod tests { #[should_fail] fn test_as_imm_buf_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_imm_buf(v) |_buf, _i| { + do v.as_imm_buf |_buf, _i| { fail!() } } @@ -3350,7 +2933,7 @@ mod tests { #[should_fail] fn test_as_mut_buf_fail() { let mut v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_mut_buf(v) |_buf, _i| { + do v.as_mut_buf |_buf, _i| { fail!() } } @@ -3428,6 +3011,120 @@ mod tests { assert_eq!(xs, [5, 5, 5, 5, 5]) } + #[test] + fn test_consume_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345); + } + + #[test] + fn test_consume_rev_iterator() { + use iterator::*; + let xs = ~[1u,2,3,4,5]; + assert_eq!(xs.consume_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321); + } + + #[test] + fn test_split_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.split_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3], &[5]]); + assert_eq!(xs.split_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[], &[2,3,4,5]]); + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[1,2,3,4], &[]]); + assert_eq!(xs.split_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.split_iter(|_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[], &[], &[]]); + + let xs: &[int] = &[]; + assert_eq!(xs.split_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_splitn_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.splitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.splitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1], &[3,4,5]]); + assert_eq!(xs.splitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.splitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplit_iterator() { + let xs = &[1i,2,3,4,5]; + + assert_eq!(xs.rsplit_iter(|x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[3], &[1]]); + assert_eq!(xs.rsplit_iter(|x| *x == 1).collect::<~[&[int]]>(), + ~[&[2,3,4,5], &[]]); + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), + ~[&[], &[1,2,3,4]]); + assert_eq!(xs.rsplit_iter(|x| *x == 10).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplit_iter(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_rsplitn_iterator() { + let xs = &[1,2,3,4,5]; + + assert_eq!(xs.rsplitn_iter(0, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[1,2,3,4,5]]); + assert_eq!(xs.rsplitn_iter(1, |x| *x % 2 == 0).collect::<~[&[int]]>(), + ~[&[5], &[1,2,3]]); + assert_eq!(xs.rsplitn_iter(3, |_| true).collect::<~[&[int]]>(), + ~[&[], &[], &[], &[1,2]]); + + let xs: &[int] = &[]; + assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]); + } + + #[test] + fn test_window_iterator() { + let v = &[1i,2,3,4]; + + assert_eq!(v.window_iter(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]); + assert_eq!(v.window_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]); + assert!(v.window_iter(6).next().is_none()); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_window_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.window_iter(0); + } + + #[test] + fn test_chunk_iterator() { + let v = &[1i,2,3,4,5]; + + assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]); + assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]); + assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]); + } + + #[test] + #[should_fail] + #[ignore(cfg(windows))] + fn test_chunk_iterator_0() { + let v = &[1i,2,3,4]; + let _it = v.chunk_iter(0); + } + #[test] fn test_move_from() { let mut a = [1,2,3,4,5]; diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 529d5bfe70b49..ce8e24fd4445a 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -238,12 +238,12 @@ pub fn unguarded_pat(a: &arm) -> Option<~[@pat]> { } pub fn public_methods(ms: ~[@method]) -> ~[@method] { - do ms.filtered |m| { + do ms.consume_iter().filter |m| { match m.vis { public => true, _ => false } - } + }.collect() } // extract a ty_method from a trait_method. if the trait_method is diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a1a0c70062883..d04d96b2481d6 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -143,13 +143,13 @@ pub fn get_name_value_str_pair(item: @ast::meta_item) /// Search a list of attributes and return only those with a specific name pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> ~[ast::attribute] { - do vec::filter_mapped(attrs) |a| { + do attrs.iter().filter_map |a| { if name == get_attr_name(a) { Some(*a) } else { None } - } + }.collect() } /// Search a list of meta items and return only those with a specific name @@ -277,14 +277,7 @@ pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] { pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { - - return vec::filter_mapped(items, |item| { - if name != get_meta_item_name(*item) { - Some(*item) - } else { - None - } - }); + items.consume_iter().filter(|item| name != get_meta_item_name(*item)).collect() } /** diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 76073199f6457..333570b6c9d7e 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -22,7 +22,6 @@ use ext::build::AstBuilder; use std::option; use std::unstable::extfmt::ct::*; -use std::vec; use parse::token::{str_to_ident}; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) @@ -268,7 +267,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, corresponding function in std::unstable::extfmt. Each function takes a buffer to insert data into along with the data being formatted. */ let npieces = pieces.len(); - do vec::consume(pieces) |i, pc| { + for pieces.consume_iter().enumerate().advance |(i, pc)| { match pc { /* Raw strings get appended via str::push_str */ PieceString(s) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4e1451239962f..96d7685353b2d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -14,8 +14,6 @@ use codemap::{span, spanned}; use parse::token; use opt_vec::OptVec; -use std::vec; - pub trait ast_fold { fn fold_crate(@self, &crate) -> crate; fn fold_view_item(@self, @view_item) -> @view_item; @@ -700,7 +698,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { pub fn noop_fold_mod(m: &_mod, fld: @ast_fold) -> _mod { ast::_mod { view_items: m.view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), - items: vec::filter_mapped(m.items, |x| fld.fold_item(*x)), + items: m.items.iter().filter_map(|x| fld.fold_item(*x)).collect(), } } diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index bc5efc5fca1f0..d327b73c625ec 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -95,13 +95,13 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { } } - do vec::map_consume(graph) |mut v| { + do graph.consume_iter().transform |mut v| { let mut vec = ~[]; do v.consume |i| { vec.push(i); } vec - } + }.collect() } fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index e245ab894f5bc..abc44dfbc9bb7 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -96,7 +96,7 @@ fn recurse_or_fail(depth: int, st: Option) { fn_box: || @Cons((), fn_box()), tuple: (@Cons((), st.tuple.first()), ~Cons((), @*st.tuple.second())), - vec: st.vec + [@Cons((), *st.vec.last())], + vec: st.vec + &[@Cons((), *st.vec.last())], res: r(@Cons((), st.res._l)) } } diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index e1366a3a8694c..1cd90962c5b79 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -28,20 +28,21 @@ fn calc(children: uint, parent_wait_chan: &Chan>>) { wait_port }; - let child_start_chans: ~[Chan>] = vec::map_consume(wait_ports, |port| port.recv()); + let child_start_chans: ~[Chan>] = + wait_ports.consume_iter().transform(|port| port.recv()).collect(); let (start_port, start_chan) = stream::>(); parent_wait_chan.send(start_chan); let parent_result_chan: Chan = start_port.recv(); - let child_sum_ports: ~[Port] = do vec::map_consume(child_start_chans) |child_start_chan| { - let (child_sum_port, child_sum_chan) = stream::(); - child_start_chan.send(child_sum_chan); - child_sum_port - }; + let child_sum_ports: ~[Port] = + do child_start_chans.consume_iter().transform |child_start_chan| { + let (child_sum_port, child_sum_chan) = stream::(); + child_start_chan.send(child_sum_chan); + child_sum_port + }.collect(); - let mut sum = 0; - vec::consume(child_sum_ports, |_, sum_port| sum += sum_port.recv() ); + let sum = child_sum_ports.consume_iter().fold(0, |sum, sum_port| sum + sum_port.recv() ); parent_result_chan.send(sum + 1); } diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index e61de0ac11f4c..e7e01a4048721 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -30,7 +30,7 @@ use std::io::WriterUtil; // Make sure this import is warned about when at least one of its imported names // is unused -use std::vec::{filter, from_elem}; //~ ERROR unused import +use std::vec::{from_fn, from_elem}; //~ ERROR unused import mod foo { pub struct Point{x: int, y: int} diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs index bd7d86d729531..0fdaf31c59361 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs @@ -11,7 +11,6 @@ // error-pattern:index out of bounds use std::sys; -use std::vec; fn main() { @@ -22,7 +21,7 @@ fn main() { // huge). let x = ~[1u,2u,3u]; - do vec::as_imm_buf(x) |p, _len| { + do x.as_imm_buf |p, _len| { let base = p as uint; let idx = base / sys::size_of::(); error!("ov1 base = 0x%x", base); diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index b036a57e19cb0..d09ef3bc25c3a 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -17,5 +17,5 @@ use std::vec::*; pub fn main() { let mut v = from_elem(0u, 0); v = append(v, ~[4, 2]); - assert_eq!(reversed(v), ~[2, 4]); + assert_eq!(from_fn(2, |i| 2*(i+1)), ~[2, 4]); }