Permalink
Browse files

De-mode vec::each() and many of the str iteration routines

Note that the method foo.each() is not de-moded, nor the other
vec routines.
  • Loading branch information...
1 parent 62b7f4d commit 9cf271fe96b474d514b1052935db70c4056cf076 @nikomatsakis nikomatsakis committed Sep 19, 2012
Showing with 555 additions and 749 deletions.
  1. +37 −28 doc/tutorial.md
  2. +7 −6 src/cargo/cargo.rs
  3. +2 −2 src/compiletest/runtest.rs
  4. +2 −2 src/libcore/at_vec.rs
  5. +4 −3 src/libcore/cast.rs
  6. +3 −3 src/libcore/either.rs
  7. +6 −2 src/libcore/hash.rs
  8. +1 −1 src/libcore/io.rs
  9. +6 −1 src/libcore/iter-trait/dvec.rs
  10. +0 −143 src/libcore/iter.rs
  11. +5 −3 src/libcore/os.rs
  12. +3 −3 src/libcore/repr.rs
  13. +1 −1 src/libcore/result.rs
  14. +3 −3 src/libcore/run.rs
  15. +8 −24 src/libcore/send_map.rs
  16. +70 −60 src/libcore/str.rs
  17. +1 −1 src/libcore/task.rs
  18. +47 −172 src/libcore/vec.rs
  19. +6 −3 src/libstd/arc.rs
  20. +7 −7 src/libstd/getopts.rs
  21. +3 −3 src/libstd/json.rs
  22. +12 −9 src/libstd/map.rs
  23. +2 −2 src/libstd/net_ip.rs
  24. +1 −1 src/libstd/serialization.rs
  25. +5 −3 src/libstd/sha1.rs
  26. +4 −10 src/libstd/smallintmap.rs
  27. +1 −1 src/libstd/sort.rs
  28. +1 −1 src/libstd/term.rs
  29. +25 −21 src/libstd/test.rs
  30. +16 −8 src/libstd/time.rs
  31. +4 −2 src/libsyntax/ast_map.rs
  32. +35 −33 src/libsyntax/ast_util.rs
  33. +1 −1 src/libsyntax/ext/qquote.rs
  34. +1 −1 src/libsyntax/ext/simplext.rs
  35. +1 −1 src/libsyntax/print/pprust.rs
  36. +1 −1 src/libsyntax/visit.rs
  37. +1 −1 src/rustc/back/link.rs
  38. +2 −2 src/rustc/metadata/cstore.rs
  39. +4 −2 src/rustc/metadata/encoder.rs
  40. +1 −1 src/rustc/metadata/tyencode.rs
  41. +8 −8 src/rustc/middle/capture.rs
  42. +2 −2 src/rustc/middle/kind.rs
  43. +22 −20 src/rustc/middle/trans/alt.rs
  44. +29 −28 src/rustc/middle/trans/base.rs
  45. +1 −1 src/rustc/middle/trans/build.rs
  46. +3 −3 src/rustc/middle/trans/callee.rs
  47. +7 −5 src/rustc/middle/trans/closure.rs
  48. +9 −7 src/rustc/middle/trans/common.rs
  49. +2 −2 src/rustc/middle/trans/controlflow.rs
  50. +6 −2 src/rustc/middle/trans/expr.rs
  51. +9 −9 src/rustc/middle/trans/foreign.rs
  52. +1 −1 src/rustc/middle/trans/meth.rs
  53. +1 −1 src/rustc/middle/trans/monomorphize.rs
  54. +9 −3 src/rustc/middle/trans/reachable.rs
  55. +9 −9 src/rustc/middle/trans/shape.rs
  56. +2 −2 src/rustc/middle/trans/tvec.rs
  57. +1 −1 src/rustc/middle/trans/type_of.rs
  58. +11 −9 src/rustc/middle/trans/type_use.rs
  59. +5 −5 src/rustc/middle/ty.rs
  60. +0 −1 src/rustc/middle/typeck.rs
  61. +1 −1 src/rustc/middle/typeck/check/method.rs
  62. +5 −5 src/rustc/middle/typeck/check/vtable.rs
  63. +13 −13 src/rustc/middle/typeck/check/writeback.rs
  64. +1 −1 src/rustc/middle/typeck/collect.rs
  65. +8 −4 src/rustdoc/markdown_pass.rs
  66. +6 −3 src/test/bench/graph500-bfs.rs
  67. +4 −1 src/test/bench/msgsend-pipes-shared.rs
  68. +4 −1 src/test/bench/msgsend-pipes.rs
  69. +3 −1 src/test/bench/msgsend.rs
  70. +3 −3 src/test/bench/shootout-chameneos-redux.rs
  71. +3 −3 src/test/bench/task-perf-one-million.rs
  72. +1 −1 src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
  73. +1 −1 src/test/compile-fail/issue-2151.rs
  74. +2 −1 src/test/compile-fail/liveness-issue-2163.rs
  75. +2 −2 src/test/compile-fail/vec-concat-bug.rs
  76. +11 −9 src/test/run-pass/assignability-trait.rs
  77. +3 −1 src/test/run-pass/auto-loop.rs
  78. +2 −2 src/test/run-pass/block-arg.rs
  79. +1 −1 src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
  80. +3 −3 src/test/run-pass/break.rs
  81. +1 −1 src/test/run-pass/rcvr-borrowed-to-slice.rs
View
@@ -1235,14 +1235,14 @@ let crayons = ~[Almond, AntiqueBrass, Apricot];
assert crayons.len() == 3;
assert !crayons.is_empty();
-// Iterate over a vector
+// Iterate over a vector, obtaining a pointer to each element
for crayons.each |crayon| {
let delicious_crayon_wax = unwrap_crayon(crayon);
eat_crayon_wax(delicious_crayon_wax);
}
// Map vector elements
-let crayon_names = crayons.map(crayon_to_str);
+let crayon_names = crayons.map(|v| crayon_to_str(v));
let favorite_crayon_name = crayon_names[0];
// Remove whitespace from before and after the string
@@ -1384,40 +1384,44 @@ call_twice(bare_function);
Closures in Rust are frequently used in combination with higher-order
functions to simulate control structures like `if` and
`loop`. Consider this function that iterates over a vector of
-integers, applying an operator to each:
+integers, passing in a pointer to each integer in the vector:
~~~~
-fn each(v: ~[int], op: fn(int)) {
+fn each(v: ~[int], op: fn(v: &int)) {
let mut n = 0;
while n < v.len() {
- op(v[n]);
+ op(&v[n]);
n += 1;
}
}
~~~~
-As a caller, if we use a closure to provide the final operator
-argument, we can write it in a way that has a pleasant, block-like
-structure.
+The reason we pass in a *pointer* to an integer rather than the
+integer itself is that this is how the actual `each()` function for
+vectors works. Using a pointer means that the function can be used
+for vectors of any type, even large records that would be impractical
+to copy out of the vector on each iteration. As a caller, if we use a
+closure to provide the final operator argument, we can write it in a
+way that has a pleasant, block-like structure.
~~~~
-# fn each(v: ~[int], op: fn(int)) {}
+# fn each(v: ~[int], op: fn(v: &int)) { }
# fn do_some_work(i: int) { }
each(~[1, 2, 3], |n| {
- debug!("%i", n);
- do_some_work(n);
+ debug!("%i", *n);
+ do_some_work(*n);
});
~~~~
This is such a useful pattern that Rust has a special form of function
call that can be written more like a built-in control structure:
~~~~
-# fn each(v: ~[int], op: fn(int)) {}
+# fn each(v: ~[int], op: fn(v: &int)) { }
# fn do_some_work(i: int) { }
do each(~[1, 2, 3]) |n| {
- debug!("%i", n);
- do_some_work(n);
+ debug!("%i", *n);
+ do_some_work(*n);
}
~~~~
@@ -1461,10 +1465,10 @@ Consider again our `each` function, this time improved to
break early when the iteratee returns `false`:
~~~~
-fn each(v: ~[int], op: fn(int) -> bool) {
+fn each(v: ~[int], op: fn(v: &int) -> bool) {
let mut n = 0;
while n < v.len() {
- if !op(v[n]) {
+ if !op(&v[n]) {
break;
}
n += 1;
@@ -1478,7 +1482,7 @@ And using this function to iterate over a vector:
# use each = vec::each;
# use println = io::println;
each(~[2, 4, 8, 5, 16], |n| {
- if n % 2 != 0 {
+ if *n % 2 != 0 {
println(~"found odd number!");
false
} else { true }
@@ -1495,7 +1499,7 @@ to the next iteration, write `again`.
# use each = vec::each;
# use println = io::println;
for each(~[2, 4, 8, 5, 16]) |n| {
- if n % 2 != 0 {
+ if *n % 2 != 0 {
println(~"found odd number!");
break;
}
@@ -1511,7 +1515,7 @@ function, not just the loop body.
# use each = vec::each;
fn contains(v: ~[int], elt: int) -> bool {
for each(v) |x| {
- if (x == elt) { return true; }
+ if (*x == elt) { return true; }
}
false
}
@@ -1529,9 +1533,9 @@ every type they apply to. Thus, Rust allows functions and datatypes to have
type parameters.
~~~~
-fn map<T, U>(vector: &[T], function: fn(T) -> U) -> ~[U] {
+fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
let mut accumulator = ~[];
- for vector.each |element| {
+ for vec::each(vector) |element| {
vec::push(accumulator, function(element));
}
return accumulator;
@@ -1544,7 +1548,12 @@ type of the vector's content agree with each other.
Inside a generic function, the names of the type parameters
(capitalized by convention) stand for opaque types. You can't look
-inside them, but you can pass them around.
+inside them, but you can pass them around. Note that instances of
+generic types are almost always passed by pointer. For example, the
+parameter `function()` is supplied with a pointer to a value of type
+`T` and not a value of type `T` itself. This ensures that the
+function works with the broadest set of types possible, since some
+types are expensive or illegal to copy and pass by value.
## Generic datatypes
@@ -1686,12 +1695,12 @@ generalized sequence types is:
~~~~
trait Seq<T> {
fn len() -> uint;
- fn iter(fn(T));
+ fn iter(b: fn(v: &T));
}
impl<T> ~[T]: Seq<T> {
fn len() -> uint { vec::len(self) }
- fn iter(b: fn(T)) {
- for self.each |elt| { b(elt); }
+ fn iter(b: fn(v: &T)) {
+ for vec::each(self) |elt| { b(elt); }
}
}
~~~~
@@ -2186,7 +2195,7 @@ Here is the function that implements the child task:
~~~~
# use std::comm::DuplexStream;
# use pipes::{Port, Chan};
-fn stringifier(channel: DuplexStream<~str, uint>) {
+fn stringifier(channel: &DuplexStream<~str, uint>) {
let mut value: uint;
loop {
value = channel.recv();
@@ -2210,7 +2219,7 @@ Here is the code for the parent task:
# use std::comm::DuplexStream;
# use pipes::{Port, Chan};
# use task::spawn;
-# fn stringifier(channel: DuplexStream<~str, uint>) {
+# fn stringifier(channel: &DuplexStream<~str, uint>) {
# let mut value: uint;
# loop {
# value = channel.recv();
@@ -2223,7 +2232,7 @@ Here is the code for the parent task:
let (from_child, to_child) = DuplexStream();
do spawn || {
- stringifier(to_child);
+ stringifier(&to_child);
};
from_child.send(22u);
View
@@ -1502,7 +1502,7 @@ fn print_source(s: source) {
print(io::with_str_writer(|writer| {
let mut list = ~" >> ";
- do vec::iteri(pks) |i, pk| {
+ for vec::eachi(pks) |i, pk| {
if str::len(list) > 78u {
writer.write_line(list);
list = ~" >> ";
@@ -1518,16 +1518,17 @@ fn cmd_list(c: &cargo) {
sync(c);
if vec::len(c.opts.free) >= 3u {
- do vec::iter_between(c.opts.free, 2u, vec::len(c.opts.free)) |name| {
- if !valid_pkg_name(name) {
- error(fmt!("'%s' is an invalid source name", name));
+ let v = vec::view(c.opts.free, 2u, vec::len(c.opts.free));
+ for vec::each(v) |name| {
+ if !valid_pkg_name(*name) {
+ error(fmt!("'%s' is an invalid source name", *name));
} else {
- match c.sources.find(name) {
+ match c.sources.find(*name) {
Some(source) => {
print_source(source);
}
None => {
- error(fmt!("no such source: %s", name));
+ error(fmt!("no such source: %s", *name));
}
}
}
@@ -425,8 +425,8 @@ fn compose_and_run_compiler(
let extra_link_args = ~[~"-L",
aux_output_dir_name(config, testfile).to_str()];
- do vec::iter(props.aux_builds) |rel_ab| {
- let abs_ab = config.aux_base.push_rel(&Path(rel_ab));
+ for vec::each(props.aux_builds) |rel_ab| {
+ let abs_ab = config.aux_base.push_rel(&Path(*rel_ab));
let aux_args =
make_compile_args(config, props, ~[~"--lib"] + extra_link_args,
|a,b| make_lib_name(a, b, testfile), &abs_ab);
View
@@ -91,7 +91,7 @@ pure fn build_sized_opt<A>(size: Option<uint>,
#[inline(always)]
pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
do build_sized(lhs.len() + rhs.len()) |push| {
- for vec::each(lhs) |x| { push(x); }
+ for vec::each(lhs) |x| { push(*x); }
for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
}
}
@@ -101,7 +101,7 @@ pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
do build_sized(v.len()) |push| {
for vec::each(v) |elem| {
- push(f(elem));
+ push(f(*elem));
}
}
}
View
@@ -4,7 +4,7 @@ export reinterpret_cast, forget, bump_box_refcount, transmute;
export transmute_mut, transmute_immut, transmute_region, transmute_mut_region;
export transmute_mut_unsafe, transmute_immut_unsafe;
-export copy_lifetime;
+export copy_lifetime, copy_lifetime_vec;
#[abi = "rust-intrinsic"]
extern mod rusti {
@@ -85,8 +85,9 @@ unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
}
/// Transforms lifetime of the second pointer to match the first.
-unsafe fn copy_lifetime_to_unsafe<S,T>(_ptr: &a/S, +ptr: *T) -> &a/T {
- transmute(ptr)
+#[inline(always)]
+unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
+ transmute_region(ptr)
}
View
@@ -34,7 +34,7 @@ fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
let mut result: ~[T] = ~[];
for vec::each(eithers) |elt| {
- match elt {
+ match *elt {
Left(l) => vec::push(result, l),
_ => { /* fallthrough */ }
}
@@ -47,7 +47,7 @@ fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
let mut result: ~[U] = ~[];
for vec::each(eithers) |elt| {
- match elt {
+ match *elt {
Right(r) => vec::push(result, r),
_ => { /* fallthrough */ }
}
@@ -67,7 +67,7 @@ fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
let mut lefts: ~[T] = ~[];
let mut rights: ~[U] = ~[];
for vec::each(eithers) |elt| {
- match elt {
+ match *elt {
Left(l) => vec::push(lefts, l),
Right(r) => vec::push(rights, r)
}
View
@@ -390,7 +390,9 @@ impl &SipState : Streaming {
fn result_str() -> ~str {
let r = self.result_bytes();
let mut s = ~"";
- for vec::each(r) |b| { s += uint::to_str(b as uint, 16u); }
+ for vec::each(r) |b| {
+ s += uint::to_str(*b as uint, 16u);
+ }
move s
}
@@ -483,7 +485,9 @@ fn test_siphash() {
fn to_hex_str(r: &[u8]/8) -> ~str {
let mut s = ~"";
- for vec::each(*r) |b| { s += uint::to_str(b as uint, 16u); }
+ for vec::each(*r) |b| {
+ s += uint::to_str(*b as uint, 16u);
+ }
return s;
}
View
@@ -451,7 +451,7 @@ fn mk_file_writer(path: &Path, flags: ~[FileFlag])
let mut fflags: c_int = wb();
for vec::each(flags) |f| {
- match f {
+ match *f {
Append => fflags |= O_APPEND as c_int,
Create => fflags |= O_CREAT as c_int,
Truncate => fflags |= O_TRUNC as c_int,
@@ -7,7 +7,12 @@ type IMPL_T<A> = dvec::DVec<A>;
* Attempts to access this dvec during iteration will fail.
*/
pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
- unsafe { self.swap(|v| { vec::each(v, f); move v }) }
+ unsafe {
+ do self.swap |v| {
+ v.each(f);
+ move v
+ }
+ }
}
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> Option<uint> {
Oops, something went wrong.

0 comments on commit 9cf271f

Please sign in to comment.