Skip to content

Commit 96453eb

Browse files
committed
auto merge of #7736 : thestinger/rust/doc, r=thestinger
2b96408 r=sanxiyn documents conversion, size hints and double-ended iterators and adds more of the traits to the prelude
2 parents 5cc4e51 + 9b21bf4 commit 96453eb

File tree

23 files changed

+214
-76
lines changed

23 files changed

+214
-76
lines changed

doc/tutorial-container.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,104 @@ println(fmt!("last: %?", it.next()));
205205
// the iterator is now fully consumed
206206
assert!(it.next().is_none());
207207
~~~
208+
209+
## Conversion
210+
211+
Iterators offer generic conversion to containers with the `collect` adaptor:
212+
213+
~~~
214+
let xs = [0, 1, 1, 2, 3, 5, 8];
215+
let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~[int]>();
216+
assert_eq!(ys, ~[10, 6, 4, 2, 2, 0]);
217+
~~~
218+
219+
The method requires a type hint for the container type, if the surrounding code
220+
does not provide sufficient information.
221+
222+
Containers can provide conversion from iterators through `collect` by
223+
implementing the `FromIterator` trait. For example, the implementation for
224+
vectors is as follows:
225+
226+
~~~
227+
impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
228+
pub fn from_iterator(iterator: &mut T) -> ~[A] {
229+
let (lower, _) = iterator.size_hint();
230+
let mut xs = with_capacity(lower);
231+
for iterator.advance |x| {
232+
xs.push(x);
233+
}
234+
xs
235+
}
236+
}
237+
~~~
238+
239+
### Size hints
240+
241+
The `Iterator` trait provides a `size_hint` default method, returning a lower
242+
bound and optionally on upper bound on the length of the iterator:
243+
244+
~~~
245+
fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
246+
~~~
247+
248+
The vector implementation of `FromIterator` from above uses the lower bound
249+
to pre-allocate enough space to hold the minimum number of elements the
250+
iterator will yield.
251+
252+
The default implementation is always correct, but it should be overridden if
253+
the iterator can provide better information.
254+
255+
The `ZeroStream` from earlier can provide an exact lower and upper bound:
256+
257+
~~~
258+
/// A stream of N zeroes
259+
struct ZeroStream {
260+
priv remaining: uint
261+
}
262+
263+
impl ZeroStream {
264+
fn new(n: uint) -> ZeroStream {
265+
ZeroStream { remaining: n }
266+
}
267+
268+
fn size_hint(&self) -> (uint, Option<uint>) {
269+
(self.remaining, Some(self.remaining))
270+
}
271+
}
272+
273+
impl Iterator<int> for ZeroStream {
274+
fn next(&mut self) -> Option<int> {
275+
if self.remaining == 0 {
276+
None
277+
} else {
278+
self.remaining -= 1;
279+
Some(0)
280+
}
281+
}
282+
}
283+
~~~
284+
285+
## Double-ended iterators
286+
287+
The `DoubleEndedIterator` trait represents an iterator able to yield elements
288+
from either end of a range. It inherits from the `Iterator` trait and extends
289+
it with the `next_back` function.
290+
291+
A `DoubleEndedIterator` can be flipped with the `invert` adaptor, returning
292+
another `DoubleEndedIterator` with `next` and `next_back` exchanged.
293+
294+
~~~
295+
let xs = [1, 2, 3, 4, 5, 6];
296+
let mut it = xs.iter();
297+
println(fmt!("%?", it.next())); // prints `Some(&1)`
298+
println(fmt!("%?", it.next())); // prints `Some(&2)`
299+
println(fmt!("%?", it.next_back())); // prints `Some(&6)`
300+
301+
// prints `5`, `4` and `3`
302+
for it.invert().advance |&x| {
303+
println(fmt!("%?", x))
304+
}
305+
~~~
306+
307+
The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
308+
version of the standard immutable and mutable vector iterators.

src/libextra/bitv.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl SmallBitv {
104104
}
105105

106106
#[inline]
107-
pub fn invert(&mut self) { self.bits = !self.bits; }
107+
pub fn negate(&mut self) { self.bits = !self.bits; }
108108
}
109109

110110
struct BigBitv {
@@ -160,7 +160,7 @@ impl BigBitv {
160160
}
161161

162162
#[inline]
163-
pub fn invert(&mut self) { for self.each_storage |w| { *w = !*w } }
163+
pub fn negate(&mut self) { for self.each_storage |w| { *w = !*w } }
164164

165165
#[inline]
166166
pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
@@ -366,9 +366,9 @@ impl Bitv {
366366

367367
/// Invert all bits
368368
#[inline]
369-
pub fn invert(&mut self) {
369+
pub fn negate(&mut self) {
370370
match self.rep {
371-
Small(ref mut b) => b.invert(),
371+
Small(ref mut b) => b.negate(),
372372
Big(ref mut s) => for s.each_storage() |w| { *w = !*w } }
373373
}
374374

src/libextra/flatpipes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ pub mod flatteners {
446446
T: Decodable<D>>(
447447
buf: &[u8])
448448
-> T {
449-
let buf = vec::to_owned(buf);
449+
let buf = buf.to_owned();
450450
let buf_reader = @BufReader::new(buf);
451451
let reader = buf_reader as @Reader;
452452
let mut deser: D = FromReader::from_reader(reader);

src/libextra/getopts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
343343
}
344344
i += 1;
345345
}
346-
return Ok(Matches {opts: vec::to_owned(opts),
346+
return Ok(Matches {opts: opts.to_owned(),
347347
vals: vals,
348348
free: free});
349349
}

src/libextra/md4.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn md4(msg: &[u8]) -> Quad {
2828
let orig_len: u64 = (msg.len() * 8u) as u64;
2929

3030
// pad message
31-
let mut msg = vec::append(vec::to_owned(msg), [0x80u8]);
31+
let mut msg = vec::append(msg.to_owned(), [0x80u8]);
3232
let mut bitlen = orig_len + 8u64;
3333
while (bitlen + 64u64) % 512u64 > 0u64 {
3434
msg.push(0u8);

src/libextra/num/bigint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ impl BigUint {
567567
/// Creates and initializes an BigUint.
568568
569569
pub fn from_slice(slice: &[BigDigit]) -> BigUint {
570-
return BigUint::new(vec::to_owned(slice));
570+
return BigUint::new(slice.to_owned());
571571
}
572572

573573
/// Creates and initializes an BigUint.

src/libextra/stats.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use sort;
1212
use std::cmp;
1313
use std::io;
1414
use std::num;
15-
use std::vec;
1615

1716
// NB: this can probably be rewritten in terms of num::Num
1817
// to be less f64-specific.
@@ -200,13 +199,13 @@ impl<'self> Stats for &'self [f64] {
200199
}
201200

202201
fn percentile(self, pct: f64) -> f64 {
203-
let mut tmp = vec::to_owned(self);
202+
let mut tmp = self.to_owned();
204203
sort::tim_sort(tmp);
205204
percentile_of_sorted(tmp, pct)
206205
}
207206

208207
fn quartiles(self) -> (f64,f64,f64) {
209-
let mut tmp = vec::to_owned(self);
208+
let mut tmp = self.to_owned();
210209
sort::tim_sort(tmp);
211210
let a = percentile_of_sorted(tmp, 25.0);
212211
let b = percentile_of_sorted(tmp, 50.0);
@@ -251,7 +250,7 @@ priv fn percentile_of_sorted(sorted_samples: &[f64],
251250
///
252251
/// See: http://en.wikipedia.org/wiki/Winsorising
253252
pub fn winsorize(samples: &mut [f64], pct: f64) {
254-
let mut tmp = vec::to_owned(samples);
253+
let mut tmp = samples.to_owned();
255254
sort::tim_sort(tmp);
256255
let lo = percentile_of_sorted(tmp, pct);
257256
let hi = percentile_of_sorted(tmp, 100.0-pct);

src/librustc/metadata/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
714714
let item_doc = lookup_item(id, cdata.data);
715715
let path = {
716716
let item_path = item_path(item_doc);
717-
vec::to_owned(item_path.init())
717+
item_path.init().to_owned()
718718
};
719719
match decode_inlined_item(cdata, tcx, copy path, item_doc) {
720720
Some(ref ii) => csearch::found((/*bad*/copy *ii)),

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1659,7 +1659,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
16591659

16601660
let writer_bytes: &mut ~[u8] = wr.bytes;
16611661

1662-
vec::to_owned(metadata_encoding_version) +
1662+
metadata_encoding_version.to_owned() +
16631663
flate::deflate_bytes(*writer_bytes)
16641664
}
16651665

src/librustc/middle/check_match.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
484484
match cx.tcx.def_map.find(&pat_id) {
485485
Some(&def_variant(_, id)) => {
486486
if variant(id) == *ctor_id {
487-
Some(vec::to_owned(r.tail()))
487+
Some(r.tail().to_owned())
488488
} else {
489489
None
490490
}
@@ -522,7 +522,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
522522
_ => fail!("type error")
523523
};
524524
if match_ {
525-
Some(vec::to_owned(r.tail()))
525+
Some(r.tail().to_owned())
526526
} else {
527527
None
528528
}
@@ -569,7 +569,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
569569
_ => fail!("type error")
570570
};
571571
if match_ {
572-
Some(vec::to_owned(r.tail()))
572+
Some(r.tail().to_owned())
573573
} else {
574574
None
575575
}
@@ -579,7 +579,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
579579
Some(args) => args,
580580
None => vec::from_elem(arity, wild())
581581
};
582-
Some(vec::append(args, vec::to_owned(r.tail())))
582+
Some(vec::append(args, r.tail()))
583583
}
584584
def_variant(_, _) => None,
585585

@@ -591,7 +591,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
591591
Some(args) => new_args = args,
592592
None => new_args = vec::from_elem(arity, wild())
593593
}
594-
Some(vec::append(new_args, vec::to_owned(r.tail())))
594+
Some(vec::append(new_args, r.tail()))
595595
}
596596
_ => None
597597
}
@@ -609,7 +609,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
609609
_ => wild()
610610
}
611611
});
612-
Some(vec::append(args, vec::to_owned(r.tail())))
612+
Some(vec::append(args, r.tail()))
613613
} else {
614614
None
615615
}
@@ -640,7 +640,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
640640
_ => wild()
641641
}
642642
}).collect();
643-
Some(vec::append(args, vec::to_owned(r.tail())))
643+
Some(vec::append(args, r.tail()))
644644
}
645645
}
646646
}
@@ -676,14 +676,14 @@ pub fn specialize(cx: &MatchCheckCtxt,
676676
single => true,
677677
_ => fail!("type error")
678678
};
679-
if match_ { Some(vec::to_owned(r.tail())) } else { None }
679+
if match_ { Some(r.tail().to_owned()) } else { None }
680680
}
681681
pat_range(lo, hi) => {
682682
let (c_lo, c_hi) = match *ctor_id {
683683
val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
684684
range(ref lo, ref hi) =>
685685
((/*bad*/copy *lo), (/*bad*/copy *hi)),
686-
single => return Some(vec::to_owned(r.tail())),
686+
single => return Some(r.tail().to_owned()),
687687
_ => fail!("type error")
688688
};
689689
let v_lo = eval_const_expr(cx.tcx, lo);
@@ -693,7 +693,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
693693
let m2 = compare_const_vals(&c_hi, &v_hi);
694694
match (m1, m2) {
695695
(Some(val1), Some(val2)) if val1 >= 0 && val2 <= 0 => {
696-
Some(vec::to_owned(r.tail()))
696+
Some(r.tail().to_owned())
697697
},
698698
(Some(_), Some(_)) => None,
699699
_ => {
@@ -734,7 +734,7 @@ pub fn specialize(cx: &MatchCheckCtxt,
734734
}
735735

736736
pub fn default(cx: &MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> {
737-
if is_wild(cx, r[0]) { Some(vec::to_owned(r.tail())) }
737+
if is_wild(cx, r[0]) { Some(r.tail().to_owned()) }
738738
else { None }
739739
}
740740

src/librustc/middle/trans/adt.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
use std::container::Map;
4848
use std::libc::c_ulonglong;
4949
use std::option::{Option, Some, None};
50-
use std::vec;
5150

5251
use lib::llvm::{ValueRef, True, IntEQ, IntNE};
5352
use middle::trans::_match;
@@ -219,7 +218,7 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
219218
size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64,
220219
align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64,
221220
packed: packed,
222-
fields: vec::to_owned(tys)
221+
fields: tys.to_owned(),
223222
}
224223
}
225224

src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3783,7 +3783,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
37833783
}
37843784

37853785
ast_map::node_variant(ref variant, _, path) => {
3786-
vec::append_one(vec::to_owned(path.init()),
3786+
vec::append_one(path.init().to_owned(),
37873787
ast_map::path_name((*variant).node.name))
37883788
}
37893789

src/libstd/prelude.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Great
4747
pub use char::Char;
4848
pub use container::{Container, Mutable, Map, Set};
4949
pub use hash::Hash;
50-
pub use iter::{Times};
51-
pub use iterator::{Iterator, IteratorUtil, OrdIterator};
50+
pub use iter::Times;
51+
pub use iterator::{Iterator, IteratorUtil, DoubleEndedIterator, DoubleEndedIteratorUtil};
52+
pub use iterator::OrdIterator;
5253
pub use num::{Num, NumCast};
5354
pub use num::{Orderable, Signed, Unsigned, Round};
5455
pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};

src/libstd/rand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ impl<R: Rng> RngUtil for R {
591591

592592
/// Shuffle a vec
593593
fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] {
594-
let mut m = vec::to_owned(values);
594+
let mut m = values.to_owned();
595595
self.shuffle_mut(m);
596596
m
597597
}

0 commit comments

Comments
 (0)