Skip to content

Commit 7820fb5

Browse files
committed
auto merge of #9062 : blake2-ppc/rust/vec-iterator, r=alexcrichton
Visit the free functions of std::vec and reimplement or remove some. Most prominently, remove `each_permutation` and replace with two iterators, ElementSwaps and Permutations. Replace unzip, unzip_slice with an updated `unzip` that works with an iterator argument. Replace each_permutation with a Permutation iterator. The new permutation iterator is more efficient since it uses an algorithm that produces permutations in an order where each is only one element swap apart, including swapping back to the original state with one swap at the end. Unify the seldomly used functions `build`, `build_sized`, `build_sized_opt` into just one function `build`. Remove `equal_sizes`
2 parents 8c7c0b4 + c11ee0f commit 7820fb5

File tree

10 files changed

+268
-274
lines changed

10 files changed

+268
-274
lines changed

src/libextra/base64.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,8 @@ mod test {
315315
use std::vec;
316316
317317
do 1000.times {
318-
let v: ~[u8] = do vec::build |push| {
319-
do task_rng().gen_uint_range(1, 100).times {
320-
push(random());
321-
}
322-
};
318+
let times = task_rng().gen_uint_range(1, 100);
319+
let v = vec::from_fn(times, |_| random::<u8>());
323320
assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
324321
}
325322
}

src/librustc/middle/typeck/infer/combine.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ use middle::typeck::infer::{TypeTrace};
6161
use util::common::indent;
6262

6363
use std::result;
64-
use std::vec;
6564
use syntax::ast::{Onceness, purity};
6665
use syntax::ast;
6766
use syntax::opt_vec;
@@ -88,7 +87,7 @@ pub trait Combine {
8887
// future we could allow type parameters to declare a
8988
// variance.
9089

91-
if vec::same_length(as_, bs) {
90+
if as_.len() == bs.len() {
9291
result::fold_(as_.iter().zip(bs.iter())
9392
.map(|(a, b)| eq_tys(self, *a, *b)))
9493
.then(|| Ok(as_.to_owned()))
@@ -419,7 +418,7 @@ pub fn super_fn_sigs<C:Combine>(
419418
this: &C, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
420419

421420
fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<~[ty::t]> {
422-
if vec::same_length(a_args, b_args) {
421+
if a_args.len() == b_args.len() {
423422
result::collect(a_args.iter().zip(b_args.iter())
424423
.map(|(a, b)| this.args(*a, *b)))
425424
} else {

src/librustc/middle/typeck/infer/region_inference/mod.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,12 @@ impl RegionVarBindings {
373373

374374
pub fn vars_created_since_snapshot(&mut self, snapshot: uint)
375375
-> ~[RegionVid] {
376-
do vec::build |push| {
377-
for &elt in self.undo_log.slice_from(snapshot).iter() {
378-
match elt {
379-
AddVar(vid) => push(vid),
380-
_ => ()
381-
}
382-
}
383-
}
376+
self.undo_log.slice_from(snapshot).iter()
377+
.filter_map(|&elt| match elt {
378+
AddVar(vid) => Some(vid),
379+
_ => None
380+
})
381+
.collect()
384382
}
385383

386384
pub fn tainted(&mut self, snapshot: uint, r0: Region) -> ~[Region] {

src/librustdoc/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub fn parse_config_(
112112
process_output: Process
113113
) -> Result<Config, ~str> {
114114
let args = args.tail();
115-
let opts = vec::unzip(opts()).first();
115+
let opts = vec::unzip(opts().move_iter()).first();
116116
match getopts::getopts(args, opts) {
117117
Ok(matches) => {
118118
if matches.free.len() == 1 {

src/libstd/at_vec.rs

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -33,62 +33,30 @@ pub fn capacity<T>(v: @[T]) -> uint {
3333
/**
3434
* Builds a vector by calling a provided function with an argument
3535
* function that pushes an element to the back of a vector.
36-
* This version takes an initial size for the vector.
36+
* The initial size for the vector may optionally be specified
3737
*
3838
* # Arguments
3939
*
40-
* * size - An initial size of the vector to reserve
40+
* * size - An option, maybe containing initial size of the vector to reserve
4141
* * builder - A function that will construct the vector. It receives
4242
* as an argument a function that will push an element
4343
* onto the vector being constructed.
4444
*/
4545
#[inline]
46-
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
46+
pub fn build<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
4747
let mut vec = @[];
48-
unsafe { raw::reserve(&mut vec, size); }
48+
unsafe { raw::reserve(&mut vec, size.unwrap_or_default(4)); }
4949
builder(|x| unsafe { raw::push(&mut vec, x) });
5050
vec
5151
}
5252

53-
/**
54-
* Builds a vector by calling a provided function with an argument
55-
* function that pushes an element to the back of a vector.
56-
*
57-
* # Arguments
58-
*
59-
* * builder - A function that will construct the vector. It receives
60-
* as an argument a function that will push an element
61-
* onto the vector being constructed.
62-
*/
63-
#[inline]
64-
pub fn build<A>(builder: &fn(push: &fn(v: A))) -> @[A] {
65-
build_sized(4, builder)
66-
}
67-
68-
/**
69-
* Builds a vector by calling a provided function with an argument
70-
* function that pushes an element to the back of a vector.
71-
* This version takes an initial size for the vector.
72-
*
73-
* # Arguments
74-
*
75-
* * size - An option, maybe containing initial size of the vector to reserve
76-
* * builder - A function that will construct the vector. It receives
77-
* as an argument a function that will push an element
78-
* onto the vector being constructed.
79-
*/
80-
#[inline]
81-
pub fn build_sized_opt<A>(size: Option<uint>, builder: &fn(push: &fn(v: A))) -> @[A] {
82-
build_sized(size.unwrap_or_default(4), builder)
83-
}
84-
8553
// Appending
8654

8755
/// Iterates over the `rhs` vector, copying each element and appending it to the
8856
/// `lhs`. Afterwards, the `lhs` is then returned for use again.
8957
#[inline]
9058
pub fn append<T:Clone>(lhs: @[T], rhs: &[T]) -> @[T] {
91-
do build_sized(lhs.len() + rhs.len()) |push| {
59+
do build(Some(lhs.len() + rhs.len())) |push| {
9260
for x in lhs.iter() {
9361
push((*x).clone());
9462
}
@@ -101,7 +69,7 @@ pub fn append<T:Clone>(lhs: @[T], rhs: &[T]) -> @[T] {
10169

10270
/// Apply a function to each element of a vector and return the results
10371
pub fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] {
104-
do build_sized(v.len()) |push| {
72+
do build(Some(v.len())) |push| {
10573
for elem in v.iter() {
10674
push(f(elem));
10775
}
@@ -115,7 +83,7 @@ pub fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] {
11583
* to the value returned by the function `op`.
11684
*/
11785
pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> @[T] {
118-
do build_sized(n_elts) |push| {
86+
do build(Some(n_elts)) |push| {
11987
let mut i: uint = 0u;
12088
while i < n_elts { push(op(i)); i += 1u; }
12189
}
@@ -128,7 +96,7 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> @[T] {
12896
* to the value `t`.
12997
*/
13098
pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> @[T] {
131-
do build_sized(n_elts) |push| {
99+
do build(Some(n_elts)) |push| {
132100
let mut i: uint = 0u;
133101
while i < n_elts {
134102
push(t.clone());
@@ -312,7 +280,7 @@ mod test {
312280
fn test() {
313281
// Some code that could use that, then:
314282
fn seq_range(lo: uint, hi: uint) -> @[uint] {
315-
do build |push| {
283+
do build(None) |push| {
316284
for i in range(lo, hi) {
317285
push(i);
318286
}
@@ -359,15 +327,15 @@ mod test {
359327
fn bench_build_sized(b: &mut bh) {
360328
let len = 64;
361329
do b.iter {
362-
build_sized(len, |push| for i in range(0, 1024) { push(i) });
330+
build(Some(len), |push| for i in range(0, 1024) { push(i) });
363331
}
364332
}
365333

366334
#[bench]
367335
fn bench_build(b: &mut bh) {
368336
do b.iter {
369337
for i in range(0, 95) {
370-
build(|push| push(i));
338+
build(None, |push| push(i));
371339
}
372340
}
373341
}

src/libstd/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ impl<T:Reader> ReaderUtil for T {
777777
}
778778

779779
fn read_lines(&self) -> ~[~str] {
780-
do vec::build |push| {
780+
do vec::build(None) |push| {
781781
do self.each_line |line| {
782782
push(line.to_owned());
783783
true

src/libstd/select.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ mod test {
148148
// Unfortunately this does not actually test the block_on early-break
149149
// codepath in select -- racing between the sender and the receiver in
150150
// separate tasks is necessary to get around the optimistic check.
151-
let (ports, chans) = unzip(from_fn(num_ports, |_| oneshot::<()>()));
151+
let (ports, chans) = unzip(range(0, num_ports).map(|_| oneshot::<()>()));
152152
let mut dead_chans = ~[];
153153
let mut ports = ports;
154154
for (i, chan) in chans.move_iter().enumerate() {
@@ -165,7 +165,7 @@ mod test {
165165

166166
// Same thing with streams instead.
167167
// FIXME(#7971): This should be in a macro but borrowck isn't smart enough.
168-
let (ports, chans) = unzip(from_fn(num_ports, |_| stream::<()>()));
168+
let (ports, chans) = unzip(range(0, num_ports).map(|_| stream::<()>()));
169169
let mut dead_chans = ~[];
170170
let mut ports = ports;
171171
for (i, chan) in chans.move_iter().enumerate() {
@@ -209,7 +209,7 @@ mod test {
209209
// Sends 10 buffered packets, and uses select to retrieve them all.
210210
// Puts the port in a different spot in the vector each time.
211211
do run_in_newsched_task {
212-
let (ports, _) = unzip(from_fn(10, |_| stream()));
212+
let (ports, _) = unzip(range(0u, 10).map(|_| stream::<int>()));
213213
let (port, chan) = stream();
214214
do 10.times { chan.send(31337); }
215215
let mut ports = ports;
@@ -327,7 +327,7 @@ mod test {
327327
let (p,c) = oneshot();
328328
let c = Cell::new(c);
329329
do task::spawn {
330-
let (dead_ps, dead_cs) = unzip(from_fn(5, |_| oneshot::<()>()));
330+
let (dead_ps, dead_cs) = unzip(range(0u, 5).map(|_| oneshot::<()>()));
331331
let mut ports = dead_ps;
332332
select(ports); // should get killed; nothing should leak
333333
c.take().send(()); // must not happen

0 commit comments

Comments
 (0)