From c3b98cabe1d7bee4878a967507ae745e9bfe13ac Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 27 Jun 2012 15:21:50 -0700 Subject: [PATCH] Removed pretty much all the vector+ from core (issue #2719) --- src/libcore/dvec.rs | 3 +- src/libcore/either.rs | 9 ++++-- src/libcore/extfmt.rs | 6 ++-- src/libcore/iter.rs | 2 +- src/libcore/rand.rs | 2 +- src/libcore/result.rs | 4 +-- src/libcore/run.rs | 10 +++--- src/libcore/str.rs | 31 ++++++++++--------- src/libcore/vec.rs | 71 +++++++++++++++++++++++++++++-------------- 9 files changed, 84 insertions(+), 54 deletions(-) diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 84a4981fb3c..85bde3b7c59 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -150,7 +150,8 @@ impl extensions for dvec { let data_ptr: *() = unsafe::reinterpret_cast(data); if data_ptr.is_null() { fail "Recursive use of dvec"; } log(error, "a"); - self.data <- [mut t]/~ + data; + self.data <- [mut t]/~; + vec::push_all_move(self.data, data); log(error, "b"); } } diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 564966c1493..0a1c9ce9e6b 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -26,7 +26,7 @@ fn lefts(eithers: [either]/~) -> [T]/~ { let mut result: [T]/~ = []/~; for vec::each(eithers) {|elt| - alt elt { left(l) { result += [l]/~; } _ {/* fallthrough */ } } + alt elt { left(l) { vec::push(result, l); } _ {/* fallthrough */ } } } ret result; } @@ -36,7 +36,7 @@ fn rights(eithers: [either]/~) -> [U]/~ { let mut result: [U]/~ = []/~; for vec::each(eithers) {|elt| - alt elt { right(r) { result += [r]/~; } _ {/* fallthrough */ } } + alt elt { right(r) { vec::push(result, r); } _ {/* fallthrough */ } } } ret result; } @@ -53,7 +53,10 @@ fn partition(eithers: [either]/~) let mut lefts: [T]/~ = []/~; let mut rights: [U]/~ = []/~; for vec::each(eithers) {|elt| - alt elt { left(l) { lefts += [l]/~; } right(r) { rights += [r]/~; } } + alt elt { + left(l) { vec::push(lefts, l); } + right(r) { vec::push(rights, r); } + } } ret {lefts: lefts, rights: rights}; } diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index b1bb6d80a7a..d738b4f6615 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -88,7 +88,7 @@ mod ct { fn flush_buf(buf: str, &pieces: [piece]/~) -> str { if str::len(buf) > 0u { let piece = piece_string(buf); - pieces += [piece]/~; + vec::push(pieces, piece); } ret ""; } @@ -108,7 +108,7 @@ mod ct { } else { buf = flush_buf(buf, pieces); let rs = parse_conversion(s, i, lim, error); - pieces += [rs.piece]/~; + vec::push(pieces, rs.piece); i = rs.next; } } else { buf += curr; i += size; } @@ -172,7 +172,7 @@ mod ct { let rest = next.flags; let j = next.next; let curr: [flag]/~ = [f]/~; - ret {flags: curr + rest, next: j}; + ret {flags: vec::append(curr, rest), next: j}; } let more = {|x|more_(x, s, i, lim)}; let f = s[i]; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index d6380a2968a..8fdc1a28df5 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -65,7 +65,7 @@ fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B { } fn to_vec>(self: IA) -> [A]/~ { - foldl::(self, []/~, {|r, a| r + [a]/~}) + foldl::(self, []/~, {|r, a| vec::append(r, [a]/~) }) } fn contains>(self: IA, x: A) -> bool { diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index e4cbd475c9a..059529a79f7 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -204,7 +204,7 @@ impl extensions for rng { let mut r = []/~; for v.each {|item| for uint::range(0u, item.weight) {|_i| - r += [item.item]/~; + vec::push(r, item.item); } } r diff --git a/src/libcore/result.rs b/src/libcore/result.rs index f9b8388f465..e9d3847ab93 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -256,7 +256,7 @@ fn map_vec( vec::reserve(vs, vec::len(ts)); for vec::each(ts) {|t| alt op(t) { - ok(v) { vs += [v]/~; } + ok(v) { vec::push(vs, v); } err(u) { ret err(u); } } } @@ -294,7 +294,7 @@ fn map_vec2(ss: [S]/~, ts: [T]/~, let mut i = 0u; while i < n { alt op(ss[i],ts[i]) { - ok(v) { vs += [v]/~; } + ok(v) { vec::push(vs, v); } err(u) { ret err(u); } } i += 1u; diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 6c724db52b5..f51e5993bbc 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -83,10 +83,10 @@ fn with_argv(prog: str, args: [str]/~, let mut tmps = []/~; for vec::each(args) {|arg| let t = @arg; - tmps += [t]/~; - argptrs += str::as_c_str(*t) {|b| [b]/~ }; + vec::push(tmps, t); + vec::push_all(argptrs, str::as_c_str(*t) {|b| [b]/~ }); } - argptrs += [ptr::null()]/~; + vec::push(argptrs, ptr::null()); vec::as_buf(argptrs, cb) } @@ -104,9 +104,9 @@ fn with_envp(env: option<[(str,str)]/~>, let (k,v) = e; let t = @(#fmt("%s=%s", k, v)); vec::push(tmps, t); - ptrs += str::as_c_str(*t) {|b| [b]/~}; + vec::push_all(ptrs, str::as_c_str(*t) {|b| [b]/~}); } - ptrs += [ptr::null()]/~; + vec::push(ptrs, ptr::null()); vec::as_buf(ptrs) { |p| unsafe { cb(::unsafe::reinterpret_cast(p)) } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 0367398c5d0..35d2edd608a 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -347,7 +347,7 @@ pure fn chars(s: str/&) -> [char]/~ { let len = len(s); while i < len { let {ch, next} = char_range_at(s, i); - buf += [ch]/~; + unchecked { vec::push(buf, ch); } i = next; } ret buf; @@ -407,8 +407,9 @@ pure fn split_char_inner(s: str/&, sep: char, count: uint, allow_empty: bool) let mut i = 0u, start = 0u; while i < l && done < count { if s[i] == b { - if allow_empty || start < i { - result += [unsafe { unsafe::slice_bytes(s, start, i) }]/~; + if allow_empty || start < i unchecked { + vec::push(result, + unsafe { unsafe::slice_bytes(s, start, i) }); } start = i + 1u; done += 1u; @@ -416,7 +417,7 @@ pure fn split_char_inner(s: str/&, sep: char, count: uint, allow_empty: bool) i += 1u; } if allow_empty || start < l { - result += [unsafe { unsafe::slice_bytes(s, start, l) }]/~; + unsafe { vec::push(result, unsafe::slice_bytes(s, start, l) ) }; } result } else { @@ -450,16 +451,16 @@ pure fn split_inner(s: str/&, sepfn: fn(cc: char) -> bool, count: uint, while i < l && done < count { let {ch, next} = char_range_at(s, i); if sepfn(ch) { - if allow_empty || start < i { - result += [unsafe { unsafe::slice_bytes(s, start, i) }]/~; + if allow_empty || start < i unchecked { + vec::push(result, unsafe { unsafe::slice_bytes(s, start, i)}); } start = next; done += 1u; } i = next; } - if allow_empty || start < l { - result += [unsafe { unsafe::slice_bytes(s, start, l) }]/~; + if allow_empty || start < l unchecked { + vec::push(result, unsafe { unsafe::slice_bytes(s, start, l) }); } result } @@ -513,7 +514,7 @@ assert [\"\", \"XXX\", \"YYY\", \"\"] == split_str(\".XXX.YYY.\", \".\") pure fn split_str(s: str/&a, sep: str/&b) -> [str]/~ { let mut result = []/~; iter_between_matches(s, sep) {|from, to| - unsafe { result += [unsafe::slice_bytes(s, from, to)]/~; } + unsafe { vec::push(result, unsafe::slice_bytes(s, from, to)); } } result } @@ -522,7 +523,7 @@ pure fn split_str_nonempty(s: str/&a, sep: str/&b) -> [str]/~ { let mut result = []/~; iter_between_matches(s, sep) {|from, to| if to > from { - unsafe { result += [unsafe::slice_bytes(s, from, to)]/~; } + unsafe { vec::push(result, unsafe::slice_bytes(s, from, to)); } } } result @@ -1270,17 +1271,17 @@ pure fn to_utf16(s: str/&) -> [u16]/~ { // Arithmetic with u32 literals is easier on the eyes than chars. let mut ch = cch as u32; - if (ch & 0xFFFF_u32) == ch { + if (ch & 0xFFFF_u32) == ch unchecked { // The BMP falls through (assuming non-surrogate, as it should) assert ch <= 0xD7FF_u32 || ch >= 0xE000_u32; - u += [ch as u16]/~ - } else { + vec::push(u, ch as u16) + } else unchecked { // Supplementary planes break into surrogates. assert ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32; ch -= 0x1_0000_u32; let w1 = 0xD800_u16 | ((ch >> 10) as u16); let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16); - u += [w1, w2]/~ + vec::push_all(u, [w1, w2]/~) } } ret u; @@ -1788,7 +1789,7 @@ mod unsafe { ptr::memcpy(vbuf, src, end - begin); } vec::unsafe::set_len(v, end - begin); - v += [0u8]/~; + vec::push(v, 0u8); ::unsafe::transmute(v) } } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 8f1ff7d1a01..97a1bca4dda 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -31,7 +31,7 @@ export rsplit; export rsplitn; export shift; export pop; -export push, push_all; +export push, push_all, push_all_move; export grow; export grow_fn; export grow_set; @@ -468,6 +468,20 @@ fn push_all(&v: [const T]/~, rhs: [const T]/&) { } } +#[inline(always)] +fn push_all_move(&v: [const T]/~, -rhs: [const T]/~) { + reserve(v, v.len() + rhs.len()); + unsafe { + unpack_slice(rhs) {|p, len| + for uint::range(0, len) {|i| + let x <- *ptr::offset(p, i); + push(v, x); + } + } + unsafe::set_len(rhs, 0); + } +} + // Appending #[inline(always)] pure fn append(lhs: [T]/&, rhs: [const T]/&) -> [T]/~ { @@ -577,7 +591,7 @@ of each result vector "] pure fn flat_map(v: [T]/&, f: fn(T) -> [U]/~) -> [U]/~ { let mut result = []/~; - for each(v) {|elem| result += f(elem); } + for each(v) {|elem| unchecked{ push_all_move(result, f(elem)); } } ret result; } @@ -649,7 +663,7 @@ pure fn connect(v: [[T]/~]/&, sep: T) -> [T]/~ { let mut first = true; for each(v) {|inner| if first { first = false; } else { unsafe { push(r, sep); } } - r += inner; + unchecked { push_all(r, inner) }; } ret r; } @@ -873,7 +887,13 @@ of the i-th tuple of the input vector. "] pure fn unzip(v: [(T, U)]/&) -> ([T]/~, [U]/~) { let mut as = []/~, bs = []/~; - for each(v) {|p| let (a, b) = p; as += [a]/~; bs += [b]/~; } + for each(v) {|p| + let (a, b) = p; + unchecked { + vec::push(as, a); + vec::push(bs, b); + } + } ret (as, bs); } @@ -888,7 +908,7 @@ pure fn zip(v: [const T]/&, u: [const U]/&) -> [(T, U)]/~ { let sz = len(v); let mut i = 0u; assert sz == len(u); - while i < sz { zipped += [(v[i], u[i])]/~; i += 1u; } + while i < sz unchecked { vec::push(zipped, (v[i], u[i])); i += 1u; } ret zipped; } @@ -914,12 +934,14 @@ fn reverse(v: [mut T]/~) { #[doc = "Returns a vector with the order of elements reversed"] -fn reversed(v: [const T]/&) -> [T]/~ { +pure fn reversed(v: [const T]/&) -> [T]/~ { let mut rs: [T]/~ = []/~; let mut i = len::(v); if i == 0u { ret rs; } else { i -= 1u; } - while i != 0u { rs += [v[i]]/~; i -= 1u; } - rs += [v[0]]/~; + unchecked { + while i != 0u { vec::push(rs, v[i]); i -= 1u; } + vec::push(rs, v[0]); + } ret rs; } @@ -1063,18 +1085,21 @@ The total number of permutations produced is `len(v)!`. If `v` contains repeated elements, then some permutations are repeated. "] pure fn permute(v: [T]/&, put: fn([T]/~)) { - let ln = len(v); - if ln == 0u { - put([]/~); - } else { - let mut i = 0u; - while i < ln { - let elt = v[i]; - let rest = slice(v, 0u, i) + slice(v, i+1u, ln); - permute(rest) {|permutation| put([elt]/~ + permutation)} - i += 1u; + let ln = len(v); + if ln == 0u { + put([]/~); + } else { + let mut i = 0u; + while i < ln { + let elt = v[i]; + let mut rest = slice(v, 0u, i); + unchecked { + push_all(rest, view(v, i+1u, ln)); + } + permute(rest) {|permutation| put([elt]/~ + permutation)} + i += 1u; + } } - } } pure fn windowed(nn: uint, xx: [TT]/&) -> [[TT]/~]/~ { @@ -1082,8 +1107,8 @@ pure fn windowed(nn: uint, xx: [TT]/&) -> [[TT]/~]/~ { assert 1u <= nn; vec::iteri (xx, {|ii, _x| let len = vec::len(xx); - if ii+nn <= len { - ww += [vec::slice(xx, ii, ii+nn)]/~; + if ii+nn <= len unchecked { + vec::push(ww, vec::slice(xx, ii, ii+nn)); } }); ret ww; @@ -2195,10 +2220,10 @@ mod tests { #[test] fn test_windowed () { assert [[1u,2u,3u]/~,[2u,3u,4u]/~,[3u,4u,5u]/~,[4u,5u,6u]/~]/~ - == windowed (3u, [1u,2u,3u,4u,5u,6u]/~); + == windowed (3u, [1u,2u,3u,4u,5u,6u]/~); assert [[1u,2u,3u,4u]/~,[2u,3u,4u,5u]/~,[3u,4u,5u,6u]/~]/~ - == windowed (4u, [1u,2u,3u,4u,5u,6u]/~); + == windowed (4u, [1u,2u,3u,4u,5u,6u]/~); assert []/~ == windowed (7u, [1u,2u,3u,4u,5u,6u]/~); }