Skip to content

Commit 9cf271f

Browse files
committed
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.
1 parent 62b7f4d commit 9cf271f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+555
-749
lines changed

doc/tutorial.md

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,14 +1235,14 @@ let crayons = ~[Almond, AntiqueBrass, Apricot];
12351235
assert crayons.len() == 3;
12361236
assert !crayons.is_empty();
12371237
1238-
// Iterate over a vector
1238+
// Iterate over a vector, obtaining a pointer to each element
12391239
for crayons.each |crayon| {
12401240
let delicious_crayon_wax = unwrap_crayon(crayon);
12411241
eat_crayon_wax(delicious_crayon_wax);
12421242
}
12431243
12441244
// Map vector elements
1245-
let crayon_names = crayons.map(crayon_to_str);
1245+
let crayon_names = crayons.map(|v| crayon_to_str(v));
12461246
let favorite_crayon_name = crayon_names[0];
12471247
12481248
// Remove whitespace from before and after the string
@@ -1384,40 +1384,44 @@ call_twice(bare_function);
13841384
Closures in Rust are frequently used in combination with higher-order
13851385
functions to simulate control structures like `if` and
13861386
`loop`. Consider this function that iterates over a vector of
1387-
integers, applying an operator to each:
1387+
integers, passing in a pointer to each integer in the vector:
13881388

13891389
~~~~
1390-
fn each(v: ~[int], op: fn(int)) {
1390+
fn each(v: ~[int], op: fn(v: &int)) {
13911391
let mut n = 0;
13921392
while n < v.len() {
1393-
op(v[n]);
1393+
op(&v[n]);
13941394
n += 1;
13951395
}
13961396
}
13971397
~~~~
13981398

1399-
As a caller, if we use a closure to provide the final operator
1400-
argument, we can write it in a way that has a pleasant, block-like
1401-
structure.
1399+
The reason we pass in a *pointer* to an integer rather than the
1400+
integer itself is that this is how the actual `each()` function for
1401+
vectors works. Using a pointer means that the function can be used
1402+
for vectors of any type, even large records that would be impractical
1403+
to copy out of the vector on each iteration. As a caller, if we use a
1404+
closure to provide the final operator argument, we can write it in a
1405+
way that has a pleasant, block-like structure.
14021406

14031407
~~~~
1404-
# fn each(v: ~[int], op: fn(int)) {}
1408+
# fn each(v: ~[int], op: fn(v: &int)) { }
14051409
# fn do_some_work(i: int) { }
14061410
each(~[1, 2, 3], |n| {
1407-
debug!("%i", n);
1408-
do_some_work(n);
1411+
debug!("%i", *n);
1412+
do_some_work(*n);
14091413
});
14101414
~~~~
14111415

14121416
This is such a useful pattern that Rust has a special form of function
14131417
call that can be written more like a built-in control structure:
14141418

14151419
~~~~
1416-
# fn each(v: ~[int], op: fn(int)) {}
1420+
# fn each(v: ~[int], op: fn(v: &int)) { }
14171421
# fn do_some_work(i: int) { }
14181422
do each(~[1, 2, 3]) |n| {
1419-
debug!("%i", n);
1420-
do_some_work(n);
1423+
debug!("%i", *n);
1424+
do_some_work(*n);
14211425
}
14221426
~~~~
14231427

@@ -1461,10 +1465,10 @@ Consider again our `each` function, this time improved to
14611465
break early when the iteratee returns `false`:
14621466

14631467
~~~~
1464-
fn each(v: ~[int], op: fn(int) -> bool) {
1468+
fn each(v: ~[int], op: fn(v: &int) -> bool) {
14651469
let mut n = 0;
14661470
while n < v.len() {
1467-
if !op(v[n]) {
1471+
if !op(&v[n]) {
14681472
break;
14691473
}
14701474
n += 1;
@@ -1478,7 +1482,7 @@ And using this function to iterate over a vector:
14781482
# use each = vec::each;
14791483
# use println = io::println;
14801484
each(~[2, 4, 8, 5, 16], |n| {
1481-
if n % 2 != 0 {
1485+
if *n % 2 != 0 {
14821486
println(~"found odd number!");
14831487
false
14841488
} else { true }
@@ -1495,7 +1499,7 @@ to the next iteration, write `again`.
14951499
# use each = vec::each;
14961500
# use println = io::println;
14971501
for each(~[2, 4, 8, 5, 16]) |n| {
1498-
if n % 2 != 0 {
1502+
if *n % 2 != 0 {
14991503
println(~"found odd number!");
15001504
break;
15011505
}
@@ -1511,7 +1515,7 @@ function, not just the loop body.
15111515
# use each = vec::each;
15121516
fn contains(v: ~[int], elt: int) -> bool {
15131517
for each(v) |x| {
1514-
if (x == elt) { return true; }
1518+
if (*x == elt) { return true; }
15151519
}
15161520
false
15171521
}
@@ -1529,9 +1533,9 @@ every type they apply to. Thus, Rust allows functions and datatypes to have
15291533
type parameters.
15301534

15311535
~~~~
1532-
fn map<T, U>(vector: &[T], function: fn(T) -> U) -> ~[U] {
1536+
fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
15331537
let mut accumulator = ~[];
1534-
for vector.each |element| {
1538+
for vec::each(vector) |element| {
15351539
vec::push(accumulator, function(element));
15361540
}
15371541
return accumulator;
@@ -1544,7 +1548,12 @@ type of the vector's content agree with each other.
15441548

15451549
Inside a generic function, the names of the type parameters
15461550
(capitalized by convention) stand for opaque types. You can't look
1547-
inside them, but you can pass them around.
1551+
inside them, but you can pass them around. Note that instances of
1552+
generic types are almost always passed by pointer. For example, the
1553+
parameter `function()` is supplied with a pointer to a value of type
1554+
`T` and not a value of type `T` itself. This ensures that the
1555+
function works with the broadest set of types possible, since some
1556+
types are expensive or illegal to copy and pass by value.
15481557

15491558
## Generic datatypes
15501559

@@ -1686,12 +1695,12 @@ generalized sequence types is:
16861695
~~~~
16871696
trait Seq<T> {
16881697
fn len() -> uint;
1689-
fn iter(fn(T));
1698+
fn iter(b: fn(v: &T));
16901699
}
16911700
impl<T> ~[T]: Seq<T> {
16921701
fn len() -> uint { vec::len(self) }
1693-
fn iter(b: fn(T)) {
1694-
for self.each |elt| { b(elt); }
1702+
fn iter(b: fn(v: &T)) {
1703+
for vec::each(self) |elt| { b(elt); }
16951704
}
16961705
}
16971706
~~~~
@@ -2186,7 +2195,7 @@ Here is the function that implements the child task:
21862195
~~~~
21872196
# use std::comm::DuplexStream;
21882197
# use pipes::{Port, Chan};
2189-
fn stringifier(channel: DuplexStream<~str, uint>) {
2198+
fn stringifier(channel: &DuplexStream<~str, uint>) {
21902199
let mut value: uint;
21912200
loop {
21922201
value = channel.recv();
@@ -2210,7 +2219,7 @@ Here is the code for the parent task:
22102219
# use std::comm::DuplexStream;
22112220
# use pipes::{Port, Chan};
22122221
# use task::spawn;
2213-
# fn stringifier(channel: DuplexStream<~str, uint>) {
2222+
# fn stringifier(channel: &DuplexStream<~str, uint>) {
22142223
# let mut value: uint;
22152224
# loop {
22162225
# value = channel.recv();
@@ -2223,7 +2232,7 @@ Here is the code for the parent task:
22232232
let (from_child, to_child) = DuplexStream();
22242233
22252234
do spawn || {
2226-
stringifier(to_child);
2235+
stringifier(&to_child);
22272236
};
22282237
22292238
from_child.send(22u);

src/cargo/cargo.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,7 +1502,7 @@ fn print_source(s: source) {
15021502
print(io::with_str_writer(|writer| {
15031503
let mut list = ~" >> ";
15041504
1505-
do vec::iteri(pks) |i, pk| {
1505+
for vec::eachi(pks) |i, pk| {
15061506
if str::len(list) > 78u {
15071507
writer.write_line(list);
15081508
list = ~" >> ";
@@ -1518,16 +1518,17 @@ fn cmd_list(c: &cargo) {
15181518
sync(c);
15191519
15201520
if vec::len(c.opts.free) >= 3u {
1521-
do vec::iter_between(c.opts.free, 2u, vec::len(c.opts.free)) |name| {
1522-
if !valid_pkg_name(name) {
1523-
error(fmt!("'%s' is an invalid source name", name));
1521+
let v = vec::view(c.opts.free, 2u, vec::len(c.opts.free));
1522+
for vec::each(v) |name| {
1523+
if !valid_pkg_name(*name) {
1524+
error(fmt!("'%s' is an invalid source name", *name));
15241525
} else {
1525-
match c.sources.find(name) {
1526+
match c.sources.find(*name) {
15261527
Some(source) => {
15271528
print_source(source);
15281529
}
15291530
None => {
1530-
error(fmt!("no such source: %s", name));
1531+
error(fmt!("no such source: %s", *name));
15311532
}
15321533
}
15331534
}

src/compiletest/runtest.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,8 @@ fn compose_and_run_compiler(
425425
let extra_link_args = ~[~"-L",
426426
aux_output_dir_name(config, testfile).to_str()];
427427

428-
do vec::iter(props.aux_builds) |rel_ab| {
429-
let abs_ab = config.aux_base.push_rel(&Path(rel_ab));
428+
for vec::each(props.aux_builds) |rel_ab| {
429+
let abs_ab = config.aux_base.push_rel(&Path(*rel_ab));
430430
let aux_args =
431431
make_compile_args(config, props, ~[~"--lib"] + extra_link_args,
432432
|a,b| make_lib_name(a, b, testfile), &abs_ab);

src/libcore/at_vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pure fn build_sized_opt<A>(size: Option<uint>,
9191
#[inline(always)]
9292
pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
9393
do build_sized(lhs.len() + rhs.len()) |push| {
94-
for vec::each(lhs) |x| { push(x); }
94+
for vec::each(lhs) |x| { push(*x); }
9595
for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
9696
}
9797
}
@@ -101,7 +101,7 @@ pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
101101
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
102102
do build_sized(v.len()) |push| {
103103
for vec::each(v) |elem| {
104-
push(f(elem));
104+
push(f(*elem));
105105
}
106106
}
107107
}

src/libcore/cast.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export reinterpret_cast, forget, bump_box_refcount, transmute;
44
export transmute_mut, transmute_immut, transmute_region, transmute_mut_region;
55
export transmute_mut_unsafe, transmute_immut_unsafe;
66

7-
export copy_lifetime;
7+
export copy_lifetime, copy_lifetime_vec;
88

99
#[abi = "rust-intrinsic"]
1010
extern mod rusti {
@@ -85,8 +85,9 @@ unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
8585
}
8686

8787
/// Transforms lifetime of the second pointer to match the first.
88-
unsafe fn copy_lifetime_to_unsafe<S,T>(_ptr: &a/S, +ptr: *T) -> &a/T {
89-
transmute(ptr)
88+
#[inline(always)]
89+
unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
90+
transmute_region(ptr)
9091
}
9192

9293

src/libcore/either.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
3434
3535
let mut result: ~[T] = ~[];
3636
for vec::each(eithers) |elt| {
37-
match elt {
37+
match *elt {
3838
Left(l) => vec::push(result, l),
3939
_ => { /* fallthrough */ }
4040
}
@@ -47,7 +47,7 @@ fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
4747
4848
let mut result: ~[U] = ~[];
4949
for vec::each(eithers) |elt| {
50-
match elt {
50+
match *elt {
5151
Right(r) => vec::push(result, r),
5252
_ => { /* fallthrough */ }
5353
}
@@ -67,7 +67,7 @@ fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
6767
let mut lefts: ~[T] = ~[];
6868
let mut rights: ~[U] = ~[];
6969
for vec::each(eithers) |elt| {
70-
match elt {
70+
match *elt {
7171
Left(l) => vec::push(lefts, l),
7272
Right(r) => vec::push(rights, r)
7373
}

src/libcore/hash.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,9 @@ impl &SipState : Streaming {
390390
fn result_str() -> ~str {
391391
let r = self.result_bytes();
392392
let mut s = ~"";
393-
for vec::each(r) |b| { s += uint::to_str(b as uint, 16u); }
393+
for vec::each(r) |b| {
394+
s += uint::to_str(*b as uint, 16u);
395+
}
394396
move s
395397
}
396398

@@ -483,7 +485,9 @@ fn test_siphash() {
483485

484486
fn to_hex_str(r: &[u8]/8) -> ~str {
485487
let mut s = ~"";
486-
for vec::each(*r) |b| { s += uint::to_str(b as uint, 16u); }
488+
for vec::each(*r) |b| {
489+
s += uint::to_str(*b as uint, 16u);
490+
}
487491
return s;
488492
}
489493

src/libcore/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ fn mk_file_writer(path: &Path, flags: ~[FileFlag])
451451

452452
let mut fflags: c_int = wb();
453453
for vec::each(flags) |f| {
454-
match f {
454+
match *f {
455455
Append => fflags |= O_APPEND as c_int,
456456
Create => fflags |= O_CREAT as c_int,
457457
Truncate => fflags |= O_TRUNC as c_int,

src/libcore/iter-trait/dvec.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ type IMPL_T<A> = dvec::DVec<A>;
77
* Attempts to access this dvec during iteration will fail.
88
*/
99
pure fn EACH<A>(self: IMPL_T<A>, f: fn(A) -> bool) {
10-
unsafe { self.swap(|v| { vec::each(v, f); move v }) }
10+
unsafe {
11+
do self.swap |v| {
12+
v.each(f);
13+
move v
14+
}
15+
}
1116
}
1217

1318
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> Option<uint> {

0 commit comments

Comments
 (0)