Skip to content

Commit

Permalink
auto merge of #7982 : thestinger/rust/iterator, r=thestinger
Browse files Browse the repository at this point in the history
f0f4dcc r=huonw
25e9c4c r=graydon
a87c2d1 r=brson
16f369d r=cmr
9f05cc8 r=bstrie
e858055 r=huonw
5d80938 r=thestinger
05d03e7 r=cmr
8f86fa3 r=thestinger
  • Loading branch information
bors committed Jul 24, 2013
2 parents 5102853 + 8f86fa3 commit f132401
Show file tree
Hide file tree
Showing 104 changed files with 589 additions and 372 deletions.
56 changes: 50 additions & 6 deletions doc/tutorial-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,15 @@ let mut it = xs.iter().zip(ys.iter());
// print out the pairs of elements up to (&3, &"baz")
for it.advance |(x, y)| {
println(fmt!("%d %s", *x, *y));
printfln!("%d %s", *x, *y);
if *x == 3 {
break;
}
}
// yield and print the last pair from the iterator
println(fmt!("last: %?", it.next()));
printfln!("last: %?", it.next());
// the iterator is now fully consumed
assert!(it.next().is_none());
Expand Down Expand Up @@ -294,15 +294,59 @@ another `DoubleEndedIterator` with `next` and `next_back` exchanged.
~~~
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter();
println(fmt!("%?", it.next())); // prints `Some(&1)`
println(fmt!("%?", it.next())); // prints `Some(&2)`
println(fmt!("%?", it.next_back())); // prints `Some(&6)`
printfln!("%?", it.next()); // prints `Some(&1)`
printfln!("%?", it.next()); // prints `Some(&2)`
printfln!("%?", it.next_back()); // prints `Some(&6)`
// prints `5`, `4` and `3`
for it.invert().advance |&x| {
println(fmt!("%?", x))
printfln!("%?", x)
}
~~~

The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
version of the standard immutable and mutable vector iterators.

The `chain_`, `transform`, `filter`, `filter_map` and `peek` adaptors are
`DoubleEndedIterator` implementations if the underlying iterators are.

~~~
let xs = [1, 2, 3, 4];
let ys = [5, 6, 7, 8];
let mut it = xs.iter().chain_(ys.iter()).transform(|&x| x * 2);
printfln!("%?", it.next()); // prints `Some(2)`
// prints `16`, `14`, `12`, `10`, `8`, `6`, `4`
for it.invert().advance |x| {
printfln!("%?", x);
}
~~~

## Random-access iterators

The `RandomAccessIterator` trait represents an iterator offering random access
to the whole range. The `indexable` method retrieves the number of elements
accessible with the `idx` method.

The `chain_` adaptor is an implementation of `RandomAccessIterator` if the
underlying iterators are.

~~~
let xs = [1, 2, 3, 4, 5];
let ys = ~[7, 9, 11];
let mut it = xs.iter().chain_(ys.iter());
printfln!("%?", it.idx(0)); // prints `Some(&1)`
printfln!("%?", it.idx(5)); // prints `Some(&7)`
printfln!("%?", it.idx(7)); // prints `Some(&11)`
printfln!("%?", it.idx(8)); // prints `None`
// yield two elements from the beginning, and one from the end
it.next();
it.next();
it.next_back();
printfln!("%?", it.idx(0)); // prints `Some(&3)`
printfln!("%?", it.idx(4)); // prints `Some(&9)`
printfln!("%?", it.idx(6)); // prints `None`
~~~
2 changes: 1 addition & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
}
}
if i != num_check_lines {
fatal_ProcRes(fmt!("line not found in debugger output: %s"
fatal_ProcRes(fmt!("line not found in debugger output: %s",
check_lines[i]), &ProcRes);
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/libextra/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'self> ToBase64 for &'self [u8] {
*
* fn main () {
* let str = [52,32].to_base64(standard);
* println(fmt!("%s", str));
* printfln!("%s", str);
* }
* ~~~
*/
Expand Down Expand Up @@ -164,7 +164,7 @@ impl<'self> ToBase64 for &'self str {
*
* fn main () {
* let str = "Hello, World".to_base64(standard);
* println(fmt!("%s",str));
* printfln!("%s", str);
* }
* ~~~
*
Expand Down Expand Up @@ -194,9 +194,9 @@ impl<'self> FromBase64 for &'self [u8] {
*
* fn main () {
* let str = [52,32].to_base64(standard);
* println(fmt!("%s", str));
* printfln!("%s", str);
* let bytes = str.from_base64();
* println(fmt!("%?",bytes));
* printfln!("%?", bytes);
* }
* ~~~
*/
Expand Down Expand Up @@ -271,11 +271,11 @@ impl<'self> FromBase64 for &'self str {
*
* fn main () {
* let hello_str = "Hello, World".to_base64(standard);
* println(fmt!("%s",hello_str));
* printfln!("%s", hello_str);
* let bytes = hello_str.from_base64();
* println(fmt!("%?",bytes));
* printfln!("%?", bytes);
* let result_str = str::from_bytes(bytes);
* println(fmt!("%s",result_str));
* printfln!("%s", result_str);
* }
* ~~~
*/
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* # fn make_a_sandwich() {};
* let mut delayed_fib = extra::future::spawn (|| fib(5000) );
* make_a_sandwich();
* println(fmt!("fib(5000) = %?", delayed_fib.get()))
* printfln!("fib(5000) = %?", delayed_fib.get())
* ~~~
*/

Expand Down
2 changes: 1 addition & 1 deletion src/libextra/getopts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* }
*
* fn print_usage(program: &str, _opts: &[Opt]) {
* println(fmt!("Usage: %s [options]", program));
* printfln!("Usage: %s [options]", program);
* println("-o\t\tOutput");
* println("-h --help\tUsage");
* }
Expand Down
90 changes: 43 additions & 47 deletions src/libextra/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@ cycle cannot be created with `Rc<T>` because there is no way to modify it after


use std::cast;
use std::libc::{c_void, size_t, malloc, free};
use std::ptr;
use std::sys;
use std::unstable::intrinsics;

// Convert ~T into *mut T without dropping it
#[inline]
unsafe fn owned_to_raw<T>(mut box: ~T) -> *mut T {
let ptr = ptr::to_mut_unsafe_ptr(box);
intrinsics::forget(box);
ptr
}

struct RcBox<T> {
value: T,
count: uint
Expand All @@ -42,21 +48,20 @@ pub struct Rc<T> {

impl<T> Rc<T> {
unsafe fn new(value: T) -> Rc<T> {
let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
assert!(!ptr::is_null(ptr));
intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
Rc{ptr: ptr}
Rc{ptr: owned_to_raw(~RcBox{value: value, count: 1})}
}
}

// FIXME: #6516: should be a static method
pub fn rc_from_owned<T: Send>(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
impl<T: Send> Rc<T> {
pub fn from_owned(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
}
}

// FIXME: #6516: should be a static method
pub fn rc_from_const<T: Freeze>(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
impl<T: Freeze> Rc<T> {
pub fn from_const(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
}
}

impl<T> Rc<T> {
Expand All @@ -73,8 +78,7 @@ impl<T> Drop for Rc<T> {
if self.ptr.is_not_null() {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::read_ptr(self.ptr);
free(self.ptr as *c_void)
let _: ~T = cast::transmute(self.ptr);
}
}
}
Expand Down Expand Up @@ -107,7 +111,7 @@ mod test_rc {

#[test]
fn test_clone() {
let x = rc_from_owned(Cell::new(5));
let x = Rc::from_owned(Cell::new(5));
let y = x.clone();
do x.borrow().with_mut_ref |inner| {
*inner = 20;
Expand All @@ -117,7 +121,7 @@ mod test_rc {

#[test]
fn test_deep_clone() {
let x = rc_from_owned(Cell::new(5));
let x = Rc::from_owned(Cell::new(5));
let y = x.deep_clone();
do x.borrow().with_mut_ref |inner| {
*inner = 20;
Expand All @@ -127,31 +131,25 @@ mod test_rc {

#[test]
fn test_simple() {
let x = rc_from_const(5);
let x = Rc::from_const(5);
assert_eq!(*x.borrow(), 5);
}

#[test]
fn test_simple_clone() {
let x = rc_from_const(5);
let x = Rc::from_const(5);
let y = x.clone();
assert_eq!(*x.borrow(), 5);
assert_eq!(*y.borrow(), 5);
}

#[test]
fn test_destructor() {
let x = rc_from_owned(~5);
let x = Rc::from_owned(~5);
assert_eq!(**x.borrow(), 5);
}
}

#[abi = "rust-intrinsic"]
extern "rust-intrinsic" {
fn init<T>() -> T;
fn uninit<T>() -> T;
}

#[deriving(Eq)]
enum Borrow {
Mutable,
Expand All @@ -175,21 +173,20 @@ pub struct RcMut<T> {

impl<T> RcMut<T> {
unsafe fn new(value: T) -> RcMut<T> {
let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
assert!(!ptr::is_null(ptr));
intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
RcMut{ptr: ptr}
RcMut{ptr: owned_to_raw(~RcMutBox{value: value, count: 1, borrow: Nothing})}
}
}

// FIXME: #6516: should be a static method
pub fn rc_mut_from_owned<T: Send>(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
impl<T: Send> RcMut<T> {
pub fn from_owned(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
}
}

// FIXME: #6516: should be a static method
pub fn rc_mut_from_const<T: Freeze>(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
impl<T: Freeze> RcMut<T> {
pub fn from_const(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
}
}

impl<T> RcMut<T> {
Expand Down Expand Up @@ -226,8 +223,7 @@ impl<T> Drop for RcMut<T> {
if self.ptr.is_not_null() {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::replace_ptr(self.ptr, uninit());
free(self.ptr as *c_void)
let _: ~T = cast::transmute(self.ptr);
}
}
}
Expand Down Expand Up @@ -262,7 +258,7 @@ mod test_rc_mut {

#[test]
fn test_clone() {
let x = rc_mut_from_owned(5);
let x = RcMut::from_owned(5);
let y = x.clone();
do x.with_mut_borrow |value| {
*value = 20;
Expand All @@ -274,7 +270,7 @@ mod test_rc_mut {

#[test]
fn test_deep_clone() {
let x = rc_mut_from_const(5);
let x = RcMut::from_const(5);
let y = x.deep_clone();
do x.with_mut_borrow |value| {
*value = 20;
Expand All @@ -286,7 +282,7 @@ mod test_rc_mut {

#[test]
fn borrow_many() {
let x = rc_mut_from_owned(5);
let x = RcMut::from_owned(5);
let y = x.clone();

do x.with_borrow |a| {
Expand All @@ -302,7 +298,7 @@ mod test_rc_mut {

#[test]
fn modify() {
let x = rc_mut_from_const(5);
let x = RcMut::from_const(5);
let y = x.clone();

do y.with_mut_borrow |a| {
Expand All @@ -317,22 +313,22 @@ mod test_rc_mut {

#[test]
fn release_immutable() {
let x = rc_mut_from_owned(5);
let x = RcMut::from_owned(5);
do x.with_borrow |_| {}
do x.with_mut_borrow |_| {}
}

#[test]
fn release_mutable() {
let x = rc_mut_from_const(5);
let x = RcMut::from_const(5);
do x.with_mut_borrow |_| {}
do x.with_borrow |_| {}
}

#[test]
#[should_fail]
fn frozen() {
let x = rc_mut_from_owned(5);
let x = RcMut::from_owned(5);
let y = x.clone();

do x.with_borrow |_| {
Expand All @@ -344,7 +340,7 @@ mod test_rc_mut {
#[test]
#[should_fail]
fn mutable_dupe() {
let x = rc_mut_from_const(5);
let x = RcMut::from_const(5);
let y = x.clone();

do x.with_mut_borrow |_| {
Expand All @@ -356,7 +352,7 @@ mod test_rc_mut {
#[test]
#[should_fail]
fn mutable_freeze() {
let x = rc_mut_from_owned(5);
let x = RcMut::from_owned(5);
let y = x.clone();

do x.with_mut_borrow |_| {
Expand All @@ -368,7 +364,7 @@ mod test_rc_mut {
#[test]
#[should_fail]
fn restore_freeze() {
let x = rc_mut_from_const(5);
let x = RcMut::from_const(5);
let y = x.clone();

do x.with_borrow |_| {
Expand Down
Loading

0 comments on commit f132401

Please sign in to comment.