diff options
| author | bors <bors@rust-lang.org> | 2013-05-10 17:56:02 -0700 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-05-10 17:56:02 -0700 | 
| commit | 3e0400fb86170baff30282edcdccff73e243fd6e (patch) | |
| tree | ec7cc5de5ce7c80845c77fdcbb670cd54c120783 /src/libcore | |
| parent | d546493096f35e68cbcd9b5d3d7654e7a9345744 (diff) | |
| parent | 606bd75586419948f109de313ab37e31397ca7a3 (diff) | |
| download | rust-3e0400fb86170baff30282edcdccff73e243fd6e.tar.gz rust-3e0400fb86170baff30282edcdccff73e243fd6e.zip  | |
auto merge of #6223 : alexcrichton/rust/issue-6183, r=pcwalton
Closes #6183. The first commit changes the compiler's method of treating a `for` loop, and all the remaining commits are just dealing with the fallout. The biggest fallout was the `IterBytes` trait, although it's really a whole lot nicer now because all of the `iter_bytes_XX` methods are just and-ed together. Sadly there was a huge amount of stuff that's `cfg(stage0)` gated, but whoever lands the next snapshot is going to have a lot of fun deleting all this code!
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cleanup.rs | 32 | ||||
| -rw-r--r-- | src/libcore/container.rs | 53 | ||||
| -rwxr-xr-x | src/libcore/core | bin | 0 -> 9455580 bytes | |||
| -rw-r--r-- | src/libcore/gc.rs | 31 | ||||
| -rw-r--r-- | src/libcore/hashmap.rs | 108 | ||||
| -rw-r--r-- | src/libcore/io.rs | 47 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 57 | ||||
| -rw-r--r-- | src/libcore/iterator.rs | 22 | ||||
| -rw-r--r-- | src/libcore/num/int-template.rs | 35 | ||||
| -rw-r--r-- | src/libcore/num/uint-template.rs | 42 | ||||
| -rw-r--r-- | src/libcore/num/uint-template/uint.rs | 24 | ||||
| -rw-r--r-- | src/libcore/old_iter.rs | 49 | ||||
| -rw-r--r-- | src/libcore/option.rs | 18 | ||||
| -rw-r--r-- | src/libcore/os.rs | 9 | ||||
| -rw-r--r-- | src/libcore/stackwalk.rs | 30 | ||||
| -rw-r--r-- | src/libcore/str.rs | 437 | ||||
| -rw-r--r-- | src/libcore/task/spawn.rs | 13 | ||||
| -rw-r--r-- | src/libcore/to_bytes.rs | 394 | ||||
| -rw-r--r-- | src/libcore/trie.rs | 62 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 241 | 
20 files changed, 1537 insertions, 167 deletions
diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 912f965db7c..a5df97e3d57 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -127,6 +127,7 @@ struct AnnihilateStats { n_bytes_freed: uint } +#[cfg(stage0)] unsafe fn each_live_alloc(read_next_before: bool, f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) { //! Walks the internal list of allocations @@ -141,8 +142,8 @@ unsafe fn each_live_alloc(read_next_before: bool, let uniq = (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE; - if ! f(box, uniq) { - break + if !f(box, uniq) { + return; } if read_next_before { @@ -152,6 +153,33 @@ unsafe fn each_live_alloc(read_next_before: bool, } } } +#[cfg(not(stage0))] +unsafe fn each_live_alloc(read_next_before: bool, + f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool { + //! Walks the internal list of allocations + + use managed; + + let task: *Task = transmute(rustrt::rust_get_task()); + let box = (*task).boxed_region.live_allocs; + let mut box: *mut BoxRepr = transmute(copy box); + while box != mut_null() { + let next_before = transmute(copy (*box).header.next); + let uniq = + (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE; + + if !f(box, uniq) { + return false; + } + + if read_next_before { + box = next_before; + } else { + box = transmute(copy (*box).header.next); + } + } + return true; +} #[cfg(unix)] fn debug_mem() -> bool { diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 37b904bbe63..1d5d7764954 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -30,16 +30,32 @@ pub trait Map<K, V>: Mutable { fn contains_key(&self, key: &K) -> bool; // Visits all keys and values + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool); + // Visits all keys and values + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool; /// Visit all keys + #[cfg(stage0)] fn each_key(&self, f: &fn(&K) -> bool); + /// Visit all keys + #[cfg(not(stage0))] + fn each_key(&self, f: &fn(&K) -> bool) -> bool; /// Visit all values + #[cfg(stage0)] fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool); + /// Visit all values + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool; /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool); + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool; /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V>; @@ -65,6 +81,7 @@ pub trait Map<K, V>: Mutable { fn pop(&mut self, k: &K) -> Option<V>; } +#[cfg(stage0)] pub trait Set<T>: Mutable { /// Return true if the set contains a value fn contains(&self, value: &T) -> bool; @@ -99,3 +116,39 @@ pub trait Set<T>: Mutable { /// Visit the values representing the union fn union(&self, other: &Self, f: &fn(&T) -> bool); } + +#[cfg(not(stage0))] +pub trait Set<T>: Mutable { + /// Return true if the set contains a value + fn contains(&self, value: &T) -> bool; + + /// Add a value to the set. Return true if the value was not already + /// present in the set. + fn insert(&mut self, value: T) -> bool; + + /// Remove a value from the set. Return true if the value was + /// present in the set. + fn remove(&mut self, value: &T) -> bool; + + /// Return true if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + fn is_disjoint(&self, other: &Self) -> bool; + + /// Return true if the set is a subset of another + fn is_subset(&self, other: &Self) -> bool; + + /// Return true if the set is a superset of another + fn is_superset(&self, other: &Self) -> bool; + + /// Visit the values representing the difference + fn difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool; + + /// Visit the values representing the symmetric difference + fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool) -> bool; + + /// Visit the values representing the intersection + fn intersection(&self, other: &Self, f: &fn(&T) -> bool) -> bool; + + /// Visit the values representing the union + fn union(&self, other: &Self, f: &fn(&T) -> bool) -> bool; +} diff --git a/src/libcore/core b/src/libcore/core new file mode 100755 index 00000000000..790c07db685 --- /dev/null +++ b/src/libcore/core Binary files differdiff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 9a7d0056b82..6a427297cc2 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -129,7 +129,7 @@ type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool; // Walks the list of roots for the given safe point, and calls visitor // on each root. -unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { +unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { let fp_bytes: *u8 = cast::transmute(fp); let sp_meta: *u32 = cast::transmute(sp.sp_meta); @@ -155,7 +155,7 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { } else { ptr::null() }; - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } sri += 1; } @@ -168,6 +168,16 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { } rri += 1; } + return true; +} + +#[cfg(stage0)] +unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { + _walk_safe_point(fp, sp, visitor); +} +#[cfg(not(stage0))] +unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { + _walk_safe_point(fp, sp, visitor) } // Is fp contained in segment? @@ -222,7 +232,7 @@ static need_cleanup: Memory = exchange_heap | stack; // Walks stack, searching for roots of the requested type, and passes // each root to the visitor. -unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { +unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { let mut segment = rustrt::rust_get_stack_segment(); let mut last_ret: *Word = ptr::null(); // To avoid collecting memory used by the GC itself, skip stack @@ -274,14 +284,14 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { // Root is a generic box. let refcount = **root; if mem | task_local_heap != 0 && refcount != -1 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } else if mem | exchange_heap != 0 && refcount == -1 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } } else { // Root is a non-immediate. if mem | stack != 0 { - if !visitor(root, tydesc) { return; } + if !visitor(root, tydesc) { return false; } } } } @@ -290,8 +300,17 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { } reached_sentinel = delay_reached_sentinel; } + return true; } +#[cfg(stage0)] +unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { + _walk_gc_roots(mem, sentinel, visitor); +} +#[cfg(not(stage0))] +unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool { + _walk_gc_roots(mem, sentinel, visitor) +} pub fn gc() { unsafe { // Abort when GC is disabled. diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 8e0a185248e..b5ae07208fc 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -88,18 +88,32 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> { } #[inline(always)] + #[cfg(stage0)] fn bucket_sequence(&self, hash: uint, - op: &fn(uint) -> bool) -> uint { + op: &fn(uint) -> bool) { let start_idx = self.to_bucket(hash); let len_buckets = self.buckets.len(); let mut idx = start_idx; loop { - if !op(idx) { - return idx; + if !op(idx) { return; } + idx = self.next_bucket(idx, len_buckets); + if idx == start_idx { + return; } + } + } + #[inline(always)] + #[cfg(not(stage0))] + fn bucket_sequence(&self, hash: uint, + op: &fn(uint) -> bool) -> bool { + let start_idx = self.to_bucket(hash); + let len_buckets = self.buckets.len(); + let mut idx = start_idx; + loop { + if !op(idx) { return false; } idx = self.next_bucket(idx, len_buckets); if idx == start_idx { - return start_idx; + return true; } } } @@ -122,14 +136,14 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> { hash: uint, k: &K) -> SearchResult { - let _ = for self.bucket_sequence(hash) |i| { + for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => if bkt.hash == hash && *k == bkt.key { return FoundEntry(i); }, None => return FoundHole(i) } - }; + } TableFull } @@ -138,7 +152,7 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> { hash: uint, k: &Q) -> SearchResult { - let _ = for self.bucket_sequence(hash) |i| { + for self.bucket_sequence(hash) |i| { match self.buckets[i] { Some(ref bkt) => { if bkt.hash == hash && k.equiv(&bkt.key) { @@ -147,7 +161,7 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> { }, None => return FoundHole(i) } - }; + } TableFull } @@ -311,7 +325,8 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> { } /// Visit all key-value pairs - fn each<'a>(&'a self, blk: &fn(&'a K, &'a V) -> bool) { + #[cfg(stage0)] + fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) { for uint::range(0, self.buckets.len()) |i| { for self.buckets[i].each |bucket| { if !blk(&bucket.key, &bucket.value) { @@ -321,17 +336,45 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> { } } + /// Visit all key-value pairs + #[cfg(not(stage0))] + fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + for self.buckets[i].each |bucket| { + if !blk(&bucket.key, &bucket.value) { + return false; + } + } + } + return true; + } + /// Visit all keys + #[cfg(stage0)] fn each_key(&self, blk: &fn(k: &K) -> bool) { self.each(|k, _| blk(k)) } + /// Visit all keys + #[cfg(not(stage0))] + fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { + self.each(|k, _| blk(k)) + } + /// Visit all values + #[cfg(stage0)] fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) { self.each(|_, v| blk(v)) } + /// Visit all values + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { + self.each(|_, v| blk(v)) + } + /// Iterate over the map and mutate the contained values + #[cfg(stage0)] fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) { for uint::range(0, self.buckets.len()) |i| { match self.buckets[i] { @@ -343,6 +386,20 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> { } } + /// Iterate over the map and mutate the contained values + #[cfg(not(stage0))] + fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + match self.buckets[i] { + Some(Bucket{key: ref key, value: ref mut value, _}) => { + if !blk(key, value) { return false; } + } + None => () + } + } + return true; + } + /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, k: &K) -> Option<&'a V> { match self.bucket_for_key(k) { @@ -632,7 +689,10 @@ pub struct HashSet<T> { impl<T:Hash + Eq> BaseIter<T> for HashSet<T> { /// Visit all values in order + #[cfg(stage0)] fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } + #[cfg(not(stage0))] + fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } fn size_hint(&self) -> Option<uint> { Some(self.len()) } } @@ -683,6 +743,7 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { } /// Visit the values representing the difference + #[cfg(stage0)] fn difference(&self, other: &HashSet<T>, f: &fn(&T) -> bool) { for self.each |v| { if !other.contains(v) { @@ -691,7 +752,14 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { } } + /// Visit the values representing the difference + #[cfg(not(stage0))] + fn difference(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool { + self.each(|v| other.contains(v) || f(v)) + } + /// Visit the values representing the symmetric difference + #[cfg(stage0)] fn symmetric_difference(&self, other: &HashSet<T>, f: &fn(&T) -> bool) { @@ -699,7 +767,16 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { other.difference(self, f); } + /// Visit the values representing the symmetric difference + #[cfg(not(stage0))] + fn symmetric_difference(&self, + other: &HashSet<T>, + f: &fn(&T) -> bool) -> bool { + self.difference(other, f) && other.difference(self, f) + } + /// Visit the values representing the intersection + #[cfg(stage0)] fn intersection(&self, other: &HashSet<T>, f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { @@ -708,7 +785,14 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { } } + /// Visit the values representing the intersection + #[cfg(not(stage0))] + fn intersection(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool { + self.each(|v| !other.contains(v) || f(v)) + } + /// Visit the values representing the union + #[cfg(stage0)] fn union(&self, other: &HashSet<T>, f: &fn(&T) -> bool) { for self.each |v| { if !f(v) { return } @@ -720,6 +804,12 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { } } } + + /// Visit the values representing the union + #[cfg(not(stage0))] + fn union(&self, other: &HashSet<T>, f: &fn(&T) -> bool) -> bool { + self.each(f) && other.each(|v| self.contains(v) || f(v)) + } } pub impl <T:Hash + Eq> HashSet<T> { diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 7fc2c2559c2..67fc71a941e 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -247,7 +247,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_byte(&self, it: &fn(int) -> bool); + #[cfg(not(stage0))] + fn each_byte(&self, it: &fn(int) -> bool) -> bool; /** * Iterate over every char until EOF or the iterator breaks. @@ -256,7 +259,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool; /** * Iterate over every line until EOF or the iterator breaks. @@ -265,7 +271,10 @@ pub trait ReaderUtil { * * None right now. */ + #[cfg(stage0)] fn each_line(&self, it: &fn(&str) -> bool); + #[cfg(not(stage0))] + fn each_line(&self, it: &fn(&str) -> bool) -> bool; /** * Reads all of the lines in the stream. @@ -676,18 +685,35 @@ impl<T:Reader> ReaderUtil for T { bytes } + #[cfg(stage0)] fn each_byte(&self, it: &fn(int) -> bool) { while !self.eof() { if !it(self.read_byte()) { break; } } } + #[cfg(not(stage0))] + fn each_byte(&self, it: &fn(int) -> bool) -> bool { + while !self.eof() { + if !it(self.read_byte()) { return false; } + } + return true; + } + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool) { while !self.eof() { if !it(self.read_char()) { break; } } } + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool { + while !self.eof() { + if !it(self.read_char()) { return false; } + } + return true; + } + #[cfg(stage0)] fn each_line(&self, it: &fn(s: &str) -> bool) { while !self.eof() { // include the \n, so that we can distinguish an entirely empty @@ -707,6 +733,27 @@ impl<T:Reader> ReaderUtil for T { if !it(line) { break; } } } + #[cfg(not(stage0))] + fn each_line(&self, it: &fn(s: &str) -> bool) -> bool { + while !self.eof() { + // include the \n, so that we can distinguish an entirely empty + // line read after "...\n", and the trailing empty line in + // "...\n\n". + let mut line = self.read_until('\n' as u8, true); + + // blank line at the end of the reader is ignored + if self.eof() && line.is_empty() { break; } + + // trim the \n, so that each_line is consistent with read_line + let n = str::len(line); + if line[n-1] == '\n' as u8 { + unsafe { str::raw::set_len(&mut line, n-1); } + } + + if !it(line) { return false; } + } + return true; + } fn read_lines(&self) -> ~[~str] { do vec::build |push| { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index b68d1158334..d5649d3dfd2 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -40,12 +40,17 @@ much easier to implement. */ -use cmp::Ord; -use option::{Option, Some, None}; +#[cfg(not(stage0))] use cmp::Ord; +#[cfg(not(stage0))] use option::{Option, Some, None}; +#[cfg(stage0)] pub trait Times { fn times(&self, it: &fn() -> bool); } +#[cfg(not(stage0))] +pub trait Times { + fn times(&self, it: &fn() -> bool) -> bool; +} /** * Transform an internal iterator into an owned vector. @@ -59,7 +64,8 @@ pub trait Times { * ~~~ */ #[inline(always)] -pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { +#[cfg(not(stage0))] +pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] { let mut v = ~[]; for iter |x| { v.push(x) } v @@ -77,13 +83,15 @@ pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { * ~~~~ */ #[inline(always)] -pub fn any<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { +#[cfg(not(stage0))] +pub fn any<T>(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { for iter |x| { if predicate(x) { - return true + return true; } } - false + return false; } /** @@ -97,13 +105,34 @@ pub fn any<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { * ~~~~ */ #[inline(always)] -pub fn all<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { +#[cfg(stage0)] +pub fn all<T>(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool)) -> bool { for iter |x| { if !predicate(x) { - return false + return false; } } - true + return true; +} + +/** + * Return true if `predicate` is true for all values yielded by an internal iterator. + * + * # Example: + * + * ~~~~ + * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); + * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); + * ~~~~ + */ +#[inline(always)] +#[cfg(not(stage0))] +pub fn all<T>(predicate: &fn(T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> bool { + // If we ever break, iter will return false, so this will only return true + // if predicate returns true for everything. + iter(|x| predicate(x)) } /** @@ -117,7 +146,9 @@ pub fn all<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { * ~~~~ */ #[inline(always)] -pub fn find<T>(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Option<T> { +#[cfg(not(stage0))] +pub fn find<T>(predicate: &fn(&T) -> bool, + iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> { for iter |x| { if predicate(&x) { return Some(x); @@ -137,7 +168,8 @@ pub fn find<T>(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Opti * ~~~~ */ #[inline] -pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> { +#[cfg(not(stage0))] +pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> { let mut result = None; for iter |x| { match result { @@ -163,7 +195,8 @@ pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> { * ~~~~ */ #[inline] -pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> { +#[cfg(not(stage0))] +pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> { let mut result = None; for iter |x| { match result { diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 29dd4538aa2..40c9637f692 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -41,7 +41,10 @@ pub trait IteratorUtil<A> { fn take(self, n: uint) -> TakeIterator<Self>; fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>) -> ScanIterator<'r, A, B, Self, St>; + #[cfg(stage0)] fn advance(&mut self, f: &fn(A) -> bool); + #[cfg(not(stage0))] + fn advance(&mut self, f: &fn(A) -> bool) -> bool; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -103,13 +106,28 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T { /// A shim implementing the `for` loop iteration protocol for iterator objects #[inline] + #[cfg(stage0)] fn advance(&mut self, f: &fn(A) -> bool) { loop { match self.next() { Some(x) => { - if !f(x) { return } + if !f(x) { return; } } - None => return + None => { return; } + } + } + } + + /// A shim implementing the `for` loop iteration protocol for iterator objects + #[inline] + #[cfg(not(stage0))] + fn advance(&mut self, f: &fn(A) -> bool) -> bool { + loop { + match self.next() { + Some(x) => { + if !f(x) { return false; } + } + None => { return true; } } } } diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 9ee5ba4753d..f2bba6a4639 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -86,38 +86,63 @@ pub fn gt(x: T, y: T) -> bool { x > y } /// #[inline(always)] /// Iterate over the range [`start`,`start`+`step`..`stop`) -pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { +pub fn _range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); } else if step > 0 { // ascending while i < stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding overflow. break if i + step > max_value - if i > max_value - step { break; } + if i > max_value - step { return true; } i += step; } } else { // descending while i > stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding underflow. break if i + step < min_value - if i < min_value - step { break; } + if i < min_value - step { return true; } i += step; } } + return true; +} + +#[cfg(stage0)] +pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { + _range_step(start, stop, step, it); +} +#[cfg(not(stage0))] +pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) -> bool { + _range_step(start, stop, step, it) } #[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T, it); } #[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`lo`..`hi`) +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) -> bool { + range_step(lo, hi, 1 as T, it) +} + +#[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T, it); } +#[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`hi`..`lo`) +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) -> bool { + range_step(hi, lo, -1 as T, it) +} /// Computes the bitwise complement #[inline(always)] diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index dcb0865cb9b..1c115ee5072 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -51,43 +51,69 @@ pub fn gt(x: T, y: T) -> bool { x > y } /// /// Iterate over the range [`start`,`start`+`step`..`stop`) /// -pub fn range_step(start: T, - stop: T, - step: T_SIGNED, - it: &fn(T) -> bool) { +pub fn _range_step(start: T, + stop: T, + step: T_SIGNED, + it: &fn(T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); } if step >= 0 { while i < stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding overflow. break if i + step > max_value - if i > max_value - (step as T) { break; } + if i > max_value - (step as T) { return true; } i += step as T; } } else { while i > stop { - if !it(i) { break } + if !it(i) { return false; } // avoiding underflow. break if i + step < min_value - if i < min_value + ((-step) as T) { break; } + if i < min_value + ((-step) as T) { return true; } i -= -step as T; } } + return true; +} + +#[cfg(stage0)] +pub fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) { + _range_step(start, stop, step, it); +} +#[cfg(not(stage0))] +pub fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) -> bool { + _range_step(start, stop, step, it) } #[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T_SIGNED, it); } #[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`lo`..`hi`) +pub fn range(lo: T, hi: T, it: &fn(T) -> bool) -> bool { + range_step(lo, hi, 1 as T_SIGNED, it) +} + +#[inline(always)] +#[cfg(stage0)] /// Iterate over the range [`hi`..`lo`) pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T_SIGNED, it); } +#[inline(always)] +#[cfg(not(stage0))] +/// Iterate over the range [`hi`..`lo`) +pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) -> bool { + range_step(hi, lo, -1 as T_SIGNED, it) +} + /// Computes the bitwise complement #[inline(always)] pub fn compl(i: T) -> T { diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index de882f1ee7a..d8a4ec19304 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -154,6 +154,7 @@ pub mod inst { return true; } + #[cfg(stage0)] impl iter::Times for uint { #[inline(always)] /// @@ -175,6 +176,29 @@ pub mod inst { } } + #[cfg(not(stage0))] + impl iter::Times for uint { + #[inline(always)] + /// + /// A convenience form for basic iteration. Given a uint `x`, + /// `for x.times { ... }` executes the given block x times. + /// + /// Equivalent to `for uint::range(0, x) |_| { ... }`. + /// + /// Not defined on all integer types to permit unambiguous + /// use with integer literals of inferred integer-type as + /// the self-value (eg. `for 100.times { ... }`). + /// + fn times(&self, it: &fn() -> bool) -> bool { + let mut i = *self; + while i > 0 { + if !it() { return false; } + i -= 1; + } + return true; + } + } + /// Returns the smallest power of 2 greater than or equal to `n` #[inline(always)] pub fn next_power_of_two(n: uint) -> uint { diff --git a/src/libcore/old_iter.rs b/src/libcore/old_iter.rs index 98b847c75b4..8e31bbfd878 100644 --- a/src/libcore/old_iter.rs +++ b/src/libcore/old_iter.rs @@ -22,21 +22,40 @@ use vec; /// A function used to initialize the elements of a sequence pub type InitOp<'self,T> = &'self fn(uint) -> T; +#[cfg(stage0)] pub trait BaseIter<A> { fn each(&self, blk: &fn(v: &A) -> bool); fn size_hint(&self) -> Option<uint>; } +#[cfg(not(stage0))] +pub trait BaseIter<A> { + fn each(&self, blk: &fn(v: &A) -> bool) -> bool; + fn size_hint(&self) -> Option<uint>; +} +#[cfg(stage0)] pub trait ReverseIter<A>: BaseIter<A> { fn each_reverse(&self, blk: &fn(&A) -> bool); } +#[cfg(not(stage0))] +pub trait ReverseIter<A>: BaseIter<A> { + fn each_reverse(&self, blk: &fn(&A) -> bool) -> bool; +} +#[cfg(stage0)] pub trait MutableIter<A>: BaseIter<A> { fn each_mut(&mut self, blk: &fn(&mut A) -> bool); } +#[cfg(not(stage0))] +pub trait MutableIter<A>: BaseIter<A> { + fn each_mut(&mut self, blk: &fn(&mut A) -> bool) -> bool; +} pub trait ExtendedIter<A> { + #[cfg(stage0)] fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + #[cfg(not(stage0))] + fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool; fn all(&self, blk: &fn(&A) -> bool) -> bool; fn any(&self, blk: &fn(&A) -> bool) -> bool; fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; @@ -45,9 +64,14 @@ pub trait ExtendedIter<A> { fn flat_map_to_vec<B,IB: BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B]; } +#[cfg(stage0)] pub trait ExtendedMutableIter<A> { fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool); } +#[cfg(not(stage0))] +pub trait ExtendedMutableIter<A> { + fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool) -> bool; +} pub trait EqIter<A:Eq> { fn contains(&self, x: &A) -> bool; @@ -92,12 +116,22 @@ pub trait Buildable<A> { } #[inline(always)] -pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) { +pub fn _eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool { let mut i = 0; for self.each |a| { - if !blk(i, a) { break; } + if !blk(i, a) { return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) { + _eachi(self, blk); +} +#[cfg(not(stage0))] +pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) -> bool { + _eachi(self, blk) } #[inline(always)] @@ -199,6 +233,7 @@ pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool) // it would have to be implemented with foldr, which is too inefficient. #[inline(always)] +#[cfg(stage0)] pub fn repeat(times: uint, blk: &fn() -> bool) { let mut i = 0; while i < times { @@ -206,6 +241,16 @@ pub fn repeat(times: uint, blk: &fn() -> bool) { i += 1; } } +#[inline(always)] +#[cfg(not(stage0))] +pub fn repeat(times: uint, blk: &fn() -> bool) -> bool { + let mut i = 0; + while i < times { + if !blk() { return false; } + i += 1; + } + return true; +} #[inline(always)] pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A { diff --git a/src/libcore/option.rs b/src/libcore/option.rs index b7c51147fba..7cb40876705 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -101,9 +101,16 @@ impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> { impl<T> BaseIter<T> for Option<T> { /// Performs an operation on the contained value by reference #[inline(always)] + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) { match *self { None => (), Some(ref t) => { f(t); } } } + /// Performs an operation on the contained value by reference + #[inline(always)] + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) -> bool { + match *self { None => true, Some(ref t) => { f(t) } } + } #[inline(always)] fn size_hint(&self) -> Option<uint> { @@ -112,16 +119,27 @@ impl<T> BaseIter<T> for Option<T> { } impl<T> MutableIter<T> for Option<T> { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) { match *self { None => (), Some(ref mut t) => { f(t); } } } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) -> bool { + match *self { None => true, Some(ref mut t) => { f(t) } } + } } impl<A> ExtendedIter<A> for Option<A> { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 26d4790705a..299b9429ac3 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -550,6 +550,7 @@ pub fn tmpdir() -> Path { } } /// Recursively walk a directory structure +#[cfg(stage0)] pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { walk_dir_(p, f); @@ -577,6 +578,14 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { return keepgoing; } } +/// Recursively walk a directory structure +#[cfg(not(stage0))] +pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool { + list_dir(p).each(|q| { + let path = &p.push(*q); + f(path) && (!path_is_dir(path) || walk_dir(path, f)) + }) +} /// Indicates whether a path represents a directory pub fn path_is_dir(p: &Path) -> bool { diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 1958b5b9d80..e86416f2499 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -24,6 +24,7 @@ pub fn Frame(fp: *Word) -> Frame { } } +#[cfg(stage0)] pub fn walk_stack(visit: &fn(Frame) -> bool) { debug!("beginning stack walk"); @@ -51,6 +52,35 @@ pub fn walk_stack(visit: &fn(Frame) -> bool) { } } } +#[cfg(not(stage0))] +pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool { + + debug!("beginning stack walk"); + + do frame_address |frame_pointer| { + let mut frame_address: *Word = unsafe { + transmute(frame_pointer) + }; + loop { + let fr = Frame(frame_address); + + debug!("frame: %x", unsafe { transmute(fr.fp) }); + visit(fr); + + unsafe { + let next_fp: **Word = transmute(frame_address); + frame_address = *next_fp; + if *frame_address == 0u { + debug!("encountered task_start_wrapper. ending walk"); + // This is the task_start_wrapper_frame. There is + // no stack beneath it and it is a foreign frame. + break; + } + } + } + } + return true; +} #[test] fn test_simple() { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 5ec6471ac4a..d7b27f53e7a 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -566,14 +566,30 @@ pub fn slice<'a>(s: &'a str, begin: uint, end: uint) -> &'a str { } /// Splits a string into substrings at each occurrence of a given character +#[cfg(stage0)] pub fn each_split_char<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), true, true, it); +} + +/// Splits a string into substrings at each occurrence of a given character +#[cfg(not(stage0))] +pub fn each_split_char<'a>(s: &'a str, sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), true, true, it) } /// Like `each_split_char`, but a trailing empty string is omitted +#[cfg(stage0)] pub fn each_split_char_no_trailing<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), true, false, it); +} +/// Like `each_split_char`, but a trailing empty string is omitted +#[cfg(not(stage0))] +pub fn each_split_char_no_trailing<'a>(s: &'a str, + sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), true, false, it) } @@ -583,17 +599,39 @@ pub fn each_split_char_no_trailing<'a>(s: &'a str, * * The character must be a valid UTF-8/ASCII character */ +#[cfg(stage0)] pub fn each_splitn_char<'a>(s: &'a str, sep: char, count: uint, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, count, true, true, it); +} +/** + * Splits a string into substrings at each occurrence of a given + * character up to 'count' times. + * + * The character must be a valid UTF-8/ASCII character + */ +#[cfg(not(stage0))] +pub fn each_splitn_char<'a>(s: &'a str, + sep: char, + count: uint, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, count, true, true, it) } /// Like `each_split_char`, but omits empty strings +#[cfg(stage0)] pub fn each_split_char_nonempty<'a>(s: &'a str, sep: char, it: &fn(&'a str) -> bool) { + each_split_char_inner(s, sep, len(s), false, false, it); +} +/// Like `each_split_char`, but omits empty strings +#[cfg(not(stage0))] +pub fn each_split_char_nonempty<'a>(s: &'a str, + sep: char, + it: &fn(&'a str) -> bool) -> bool { each_split_char_inner(s, sep, len(s), false, false, it) } @@ -602,7 +640,7 @@ fn each_split_char_inner<'a>(s: &'a str, count: uint, allow_empty: bool, allow_trailing_empty: bool, - it: &fn(&'a str) -> bool) { + it: &fn(&'a str) -> bool) -> bool { if sep < 128u as char { let b = sep as u8, l = len(s); let mut done = 0u; @@ -610,7 +648,9 @@ fn each_split_char_inner<'a>(s: &'a str, while i < l && done < count { if s[i] == b { if allow_empty || start < i { - if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { + return false; + } } start = i + 1u; done += 1u; @@ -619,24 +659,41 @@ fn each_split_char_inner<'a>(s: &'a str, } // only slice a non-empty trailing substring if allow_trailing_empty || start < l { - if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; } } - } else { - each_split_inner(s, |cur| cur == sep, count, allow_empty, allow_trailing_empty, it) + return true; } + return each_split_inner(s, |cur| cur == sep, count, + allow_empty, allow_trailing_empty, it) } /// Splits a string into substrings using a character function +#[cfg(stage0)] pub fn each_split<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), true, true, it); +} +/// Splits a string into substrings using a character function +#[cfg(not(stage0))] +pub fn each_split<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), true, true, it) } /// Like `each_split`, but a trailing empty string is omitted +#[cfg(stage0)] pub fn each_split_no_trailing<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), true, false, it); +} +/// Like `each_split`, but a trailing empty string is omitted +#[cfg(not(stage0))] +pub fn each_split_no_trailing<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), true, false, it) } @@ -644,17 +701,37 @@ pub fn each_split_no_trailing<'a>(s: &'a str, * Splits a string into substrings using a character function, cutting at * most `count` times. */ +#[cfg(stage0)] pub fn each_splitn<'a>(s: &'a str, sepfn: &fn(char) -> bool, count: uint, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, count, true, true, it); +} +/** + * Splits a string into substrings using a character function, cutting at + * most `count` times. + */ +#[cfg(not(stage0))] +pub fn each_splitn<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + count: uint, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, count, true, true, it) } /// Like `each_split`, but omits empty strings +#[cfg(stage0)] pub fn each_split_nonempty<'a>(s: &'a str, sepfn: &fn(char) -> bool, it: &fn(&'a str) -> bool) { + each_split_inner(s, sepfn, len(s), false, false, it); +} +/// Like `each_split`, but omits empty strings +#[cfg(not(stage0))] +pub fn each_split_nonempty<'a>(s: &'a str, + sepfn: &fn(char) -> bool, + it: &fn(&'a str) -> bool) -> bool { each_split_inner(s, sepfn, len(s), false, false, it) } @@ -663,14 +740,16 @@ fn each_split_inner<'a>(s: &'a str, count: uint, allow_empty: bool, allow_trailing_empty: bool, - it: &fn(&'a str) -> bool) { + it: &fn(&'a str) -> bool) -> bool { let l = len(s); let mut i = 0u, start = 0u, done = 0u; while i < l && done < count { let CharRange {ch, next} = char_range_at(s, i); if sepfn(ch) { if allow_empty || start < i { - if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, i) } ) { + return false; + } } start = next; done += 1u; @@ -678,12 +757,15 @@ fn each_split_inner<'a>(s: &'a str, i = next; } if allow_trailing_empty || start < l { - if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return; } + if !it( unsafe{ raw::slice_bytes(s, start, l) } ) { return false; } } + return true; } // See Issue #1932 for why this is a naive search -fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { +#[cfg(stage0)] +fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, + f: &fn(uint, uint) -> bool) { let sep_len = len(sep), l = len(s); assert!(sep_len > 0u); let mut i = 0u, match_start = 0u, match_i = 0u; @@ -709,7 +791,38 @@ fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { } } } +// See Issue #1932 for why this is a naive search +#[cfg(not(stage0))] +fn iter_matches<'a,'b>(s: &'a str, sep: &'b str, + f: &fn(uint, uint) -> bool) -> bool { + let sep_len = len(sep), l = len(s); + assert!(sep_len > 0u); + let mut i = 0u, match_start = 0u, match_i = 0u; + + while i < l { + if s[i] == sep[match_i] { + if match_i == 0u { match_start = i; } + match_i += 1u; + // Found a match + if match_i == sep_len { + if !f(match_start, i + 1u) { return false; } + match_i = 0u; + } + i += 1u; + } else { + // Failed match, backtrack + if match_i > 0u { + match_i = 0u; + i = match_start + 1u; + } else { + i += 1u; + } + } + } + return true; +} +#[cfg(stage0)] fn iter_between_matches<'a,'b>(s: &'a str, sep: &'b str, f: &fn(uint, uint) -> bool) { @@ -720,6 +833,17 @@ fn iter_between_matches<'a,'b>(s: &'a str, } f(last_end, len(s)); } +#[cfg(not(stage0))] +fn iter_between_matches<'a,'b>(s: &'a str, + sep: &'b str, + f: &fn(uint, uint) -> bool) -> bool { + let mut last_end = 0u; + for iter_matches(s, sep) |from, to| { + if !f(last_end, from) { return false; } + last_end = to; + } + return f(last_end, len(s)); +} /** * Splits a string into a vector of the substrings separated by a given string @@ -732,6 +856,7 @@ fn iter_between_matches<'a,'b>(s: &'a str, * assert!(v == ["", "XXX", "YYY", ""]); * ~~~ */ +#[cfg(stage0)] pub fn each_split_str<'a,'b>(s: &'a str, sep: &'b str, it: &fn(&'a str) -> bool) { @@ -739,7 +864,28 @@ pub fn each_split_str<'a,'b>(s: &'a str, if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return; } } } +/** + * Splits a string into a vector of the substrings separated by a given string + * + * # Example + * + * ~~~ + * let mut v = ~[]; + * for each_split_str(".XXX.YYY.", ".") |subs| { v.push(subs); } + * assert!(v == ["", "XXX", "YYY", ""]); + * ~~~ + */ +#[cfg(not(stage0))] +pub fn each_split_str<'a,'b>(s: &'a str, + sep: &'b str, + it: &fn(&'a str) -> bool) -> bool { + for iter_between_matches(s, sep) |from, to| { + if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; } + } + return true; +} +#[cfg(stage0)] pub fn each_split_str_nonempty<'a,'b>(s: &'a str, sep: &'b str, it: &fn(&'a str) -> bool) { @@ -750,6 +896,18 @@ pub fn each_split_str_nonempty<'a,'b>(s: &'a str, } } +#[cfg(not(stage0))] +pub fn each_split_str_nonempty<'a,'b>(s: &'a str, + sep: &'b str, + it: &fn(&'a str) -> bool) -> bool { + for iter_between_matches(s, sep) |from, to| { + if to > from { + if !it( unsafe { raw::slice_bytes(s, from, to) } ) { return false; } + } + } + return true; +} + /// Levenshtein Distance between two strings pub fn levdistance(s: &str, t: &str) -> uint { @@ -787,7 +945,15 @@ pub fn levdistance(s: &str, t: &str) -> uint { /** * Splits a string into substrings separated by LF ('\n'). */ +#[cfg(stage0)] pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) { + each_split_char_no_trailing(s, '\n', it); +} +/** + * Splits a string into substrings separated by LF ('\n'). + */ +#[cfg(not(stage0))] +pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { each_split_char_no_trailing(s, '\n', it) } @@ -795,6 +961,7 @@ pub fn each_line<'a>(s: &'a str, it: &fn(&'a str) -> bool) { * Splits a string into substrings separated by LF ('\n') * and/or CR LF ("\r\n") */ +#[cfg(stage0)] pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) { for each_line(s) |s| { let l = s.len(); @@ -805,9 +972,31 @@ pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) { } } } +/** + * Splits a string into substrings separated by LF ('\n') + * and/or CR LF ("\r\n") + */ +#[cfg(not(stage0))] +pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { + for each_line(s) |s| { + let l = s.len(); + if l > 0u && s[l - 1u] == '\r' as u8 { + if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; } + } else { + if !it( s ) { return false; } + } + } + return true; +} /// Splits a string into substrings separated by whitespace +#[cfg(stage0)] pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) { + each_split_nonempty(s, char::is_whitespace, it); +} +/// Splits a string into substrings separated by whitespace +#[cfg(not(stage0))] +pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool { each_split_nonempty(s, char::is_whitespace, it) } @@ -820,9 +1009,9 @@ pub fn each_word<'a>(s: &'a str, it: &fn(&'a str) -> bool) { * Fails during iteration if the string contains a non-whitespace * sequence longer than the limit. */ -pub fn each_split_within<'a>(ss: &'a str, - lim: uint, - it: &fn(&'a str) -> bool) { +pub fn _each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) -> bool { // Just for fun, let's write this as an state machine: enum SplitWithinState { @@ -880,6 +1069,20 @@ pub fn each_split_within<'a>(ss: &'a str, machine(fake_i, ' '); fake_i += 1; } + return cont; +} + +#[cfg(stage0)] +pub fn each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) { + _each_split_within(ss, lim, it); +} +#[cfg(not(stage0))] +pub fn each_split_within<'a>(ss: &'a str, + lim: uint, + it: &fn(&'a str) -> bool) -> bool { + _each_split_within(ss, lim, it) } /** @@ -1158,12 +1361,20 @@ pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { /// Iterate over the bytes in a string #[inline(always)] +#[cfg(stage0)] pub fn each(s: &str, it: &fn(u8) -> bool) { eachi(s, |_i, b| it(b)) } +/// Iterate over the bytes in a string +#[inline(always)] +#[cfg(not(stage0))] +pub fn each(s: &str, it: &fn(u8) -> bool) -> bool { + eachi(s, |_i, b| it(b)) +} /// Iterate over the bytes in a string, with indices #[inline(always)] +#[cfg(stage0)] pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) { let mut pos = 0; let len = s.len(); @@ -1174,14 +1385,36 @@ pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) { } } +/// Iterate over the bytes in a string, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn eachi(s: &str, it: &fn(uint, u8) -> bool) -> bool { + let mut pos = 0; + let len = s.len(); + + while pos < len { + if !it(pos, s[pos]) { return false; } + pos += 1; + } + return true; +} + /// Iterate over the bytes in a string in reverse #[inline(always)] +#[cfg(stage0)] pub fn each_reverse(s: &str, it: &fn(u8) -> bool) { eachi_reverse(s, |_i, b| it(b) ) } +/// Iterate over the bytes in a string in reverse +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_reverse(s: &str, it: &fn(u8) -> bool) -> bool { + eachi_reverse(s, |_i, b| it(b) ) +} /// Iterate over the bytes in a string in reverse, with indices #[inline(always)] +#[cfg(stage0)] pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) { let mut pos = s.len(); while pos > 0 { @@ -1189,9 +1422,21 @@ pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) { if !it(pos, s[pos]) { break; } } } +/// Iterate over the bytes in a string in reverse, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn eachi_reverse(s: &str, it: &fn(uint, u8) -> bool) -> bool { + let mut pos = s.len(); + while pos > 0 { + pos -= 1; + if !it(pos, s[pos]) { return false; } + } + return true; +} /// Iterate over each char of a string, without allocating #[inline(always)] +#[cfg(stage0)] pub fn each_char(s: &str, it: &fn(char) -> bool) { let mut i = 0; let len = len(s); @@ -1201,9 +1446,23 @@ pub fn each_char(s: &str, it: &fn(char) -> bool) { i = next; } } +/// Iterate over each char of a string, without allocating +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_char(s: &str, it: &fn(char) -> bool) -> bool { + let mut i = 0; + let len = len(s); + while i < len { + let CharRange {ch, next} = char_range_at(s, i); + if !it(ch) { return false; } + i = next; + } + return true; +} /// Iterates over the chars in a string, with indices #[inline(always)] +#[cfg(stage0)] pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) { let mut pos = 0; let mut ch_pos = 0u; @@ -1215,15 +1474,38 @@ pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) { ch_pos += 1u; } } +/// Iterates over the chars in a string, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_chari(s: &str, it: &fn(uint, char) -> bool) -> bool { + let mut pos = 0; + let mut ch_pos = 0u; + let len = s.len(); + while pos < len { + let CharRange {ch, next} = char_range_at(s, pos); + pos = next; + if !it(ch_pos, ch) { return false; } + ch_pos += 1u; + } + return true; +} /// Iterates over the chars in a string in reverse #[inline(always)] +#[cfg(stage0)] pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) { each_chari_reverse(s, |_, c| it(c)) } +/// Iterates over the chars in a string in reverse +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_char_reverse(s: &str, it: &fn(char) -> bool) -> bool { + each_chari_reverse(s, |_, c| it(c)) +} // Iterates over the chars in a string in reverse, with indices #[inline(always)] +#[cfg(stage0)] pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) { let mut pos = s.len(); let mut ch_pos = s.char_len(); @@ -1236,6 +1518,21 @@ pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) { } } +// Iterates over the chars in a string in reverse, with indices +#[inline(always)] +#[cfg(not(stage0))] +pub fn each_chari_reverse(s: &str, it: &fn(uint, char) -> bool) -> bool { + let mut pos = s.len(); + let mut ch_pos = s.char_len(); + while pos > 0 { + let CharRange {ch, next} = char_range_at_reverse(s, pos); + pos = next; + ch_pos -= 1; + + if !it(ch_pos, ch) { return false; } + } + return true; +} /* Section: Searching @@ -2473,14 +2770,22 @@ pub trait StrSlice<'self> { fn contains<'a>(&self, needle: &'a str) -> bool; fn contains_char(&self, needle: char) -> bool; fn char_iter(&self) -> StrCharIterator<'self>; - fn each(&self, it: &fn(u8) -> bool); - fn eachi(&self, it: &fn(uint, u8) -> bool); - fn each_reverse(&self, it: &fn(u8) -> bool); - fn eachi_reverse(&self, it: &fn(uint, u8) -> bool); - fn each_char(&self, it: &fn(char) -> bool); - fn each_chari(&self, it: &fn(uint, char) -> bool); - fn each_char_reverse(&self, it: &fn(char) -> bool); - fn each_chari_reverse(&self, it: &fn(uint, char) -> bool); + #[cfg(stage0)] fn each(&self, it: &fn(u8) -> bool); + #[cfg(not(stage0))] fn each(&self, it: &fn(u8) -> bool) -> bool; + #[cfg(stage0)] fn eachi(&self, it: &fn(uint, u8) -> bool); + #[cfg(not(stage0))] fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool; + #[cfg(stage0)] fn each_reverse(&self, it: &fn(u8) -> bool); + #[cfg(not(stage0))] fn each_reverse(&self, it: &fn(u8) -> bool) -> bool; + #[cfg(stage0)] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool); + #[cfg(not(stage0))] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool; + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] fn each_char(&self, it: &fn(char) -> bool) -> bool; + #[cfg(stage0)] fn each_chari(&self, it: &fn(uint, char) -> bool); + #[cfg(not(stage0))] fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool; + #[cfg(stage0)] fn each_char_reverse(&self, it: &fn(char) -> bool); + #[cfg(not(stage0))] fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool; + #[cfg(stage0)] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool); + #[cfg(not(stage0))] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool; fn ends_with(&self, needle: &str) -> bool; fn is_empty(&self) -> bool; fn is_whitespace(&self) -> bool; @@ -2488,9 +2793,18 @@ pub trait StrSlice<'self> { fn len(&self) -> uint; fn char_len(&self) -> uint; fn slice(&self, begin: uint, end: uint) -> &'self str; + #[cfg(stage0)] fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool; + #[cfg(stage0)] fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool; + #[cfg(stage0)] fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool); + #[cfg(not(stage0))] + fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool; fn starts_with<'a>(&self, needle: &'a str) -> bool; fn substr(&self, begin: uint, n: uint) -> &'self str; fn escape_default(&self) -> ~str; @@ -2543,39 +2857,86 @@ impl<'self> StrSlice<'self> for &'self str { /// Iterate over the bytes in a string #[inline] + #[cfg(stage0)] fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } + /// Iterate over the bytes in a string + #[inline] + #[cfg(not(stage0))] + fn each(&self, it: &fn(u8) -> bool) -> bool { each(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] + #[cfg(stage0)] fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } + /// Iterate over the bytes in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn eachi(&self, it: &fn(uint, u8) -> bool) -> bool { eachi(*self, it) } /// Iterate over the bytes in a string #[inline] - fn each_reverse(&self, it: &fn(u8) -> bool) { - each_reverse(*self, it) - } + #[cfg(stage0)] + fn each_reverse(&self, it: &fn(u8) -> bool) { each_reverse(*self, it) } + /// Iterate over the bytes in a string + #[inline] + #[cfg(not(stage0))] + fn each_reverse(&self, it: &fn(u8) -> bool) -> bool { each_reverse(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] + #[cfg(stage0)] fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) { eachi_reverse(*self, it) } + /// Iterate over the bytes in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn eachi_reverse(&self, it: &fn(uint, u8) -> bool) -> bool { + eachi_reverse(*self, it) + } /// Iterate over the chars in a string #[inline] + #[cfg(stage0)] fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } + /// Iterate over the chars in a string + #[inline] + #[cfg(not(stage0))] + fn each_char(&self, it: &fn(char) -> bool) -> bool { each_char(*self, it) } /// Iterate over the chars in a string, with indices #[inline] + #[cfg(stage0)] fn each_chari(&self, it: &fn(uint, char) -> bool) { each_chari(*self, it) } + /// Iterate over the chars in a string, with indices + #[inline] + #[cfg(not(stage0))] + fn each_chari(&self, it: &fn(uint, char) -> bool) -> bool { + each_chari(*self, it) + } /// Iterate over the chars in a string in reverse #[inline] + #[cfg(stage0)] fn each_char_reverse(&self, it: &fn(char) -> bool) { each_char_reverse(*self, it) } + /// Iterate over the chars in a string in reverse + #[inline] + #[cfg(not(stage0))] + fn each_char_reverse(&self, it: &fn(char) -> bool) -> bool { + each_char_reverse(*self, it) + } /// Iterate over the chars in a string in reverse, with indices from the /// end #[inline] + #[cfg(stage0)] fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) { each_chari_reverse(*self, it) } + /// Iterate over the chars in a string in reverse, with indices from the + /// end + #[inline] + #[cfg(not(stage0))] + fn each_chari_reverse(&self, it: &fn(uint, char) -> bool) -> bool { + each_chari_reverse(*self, it) + } /// Returns true if one string ends with another #[inline] fn ends_with(&self, needle: &str) -> bool { @@ -2617,24 +2978,50 @@ impl<'self> StrSlice<'self> for &'self str { } /// Splits a string into substrings using a character function #[inline] + #[cfg(stage0)] fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) { each_split(*self, sepfn, it) } + /// Splits a string into substrings using a character function + #[inline] + #[cfg(not(stage0))] + fn each_split(&self, sepfn: &fn(char) -> bool, it: &fn(&'self str) -> bool) -> bool { + each_split(*self, sepfn, it) + } /** * Splits a string into substrings at each occurrence of a given character */ #[inline] + #[cfg(stage0)] fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) { each_split_char(*self, sep, it) } /** + * Splits a string into substrings at each occurrence of a given character + */ + #[inline] + #[cfg(not(stage0))] + fn each_split_char(&self, sep: char, it: &fn(&'self str) -> bool) -> bool { + each_split_char(*self, sep, it) + } + /** * Splits a string into a vector of the substrings separated by a given * string */ #[inline] + #[cfg(stage0)] fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) { each_split_str(*self, sep, it) } + /** + * Splits a string into a vector of the substrings separated by a given + * string + */ + #[inline] + #[cfg(not(stage0))] + fn each_split_str<'a>(&self, sep: &'a str, it: &fn(&'self str) -> bool) -> bool { + each_split_str(*self, sep, it) + } /// Returns true if one string starts with another #[inline] fn starts_with<'a>(&self, needle: &'a str) -> bool { @@ -3017,7 +3404,7 @@ mod tests { let lf = ~"\nMary had a little lamb\nLittle lamb\n"; let crlf = ~"\r\nMary had a little lamb\r\nLittle lamb\r\n"; - fn t(s: &str, f: &fn(&str, &fn(&str) -> bool), u: &[~str]) { + fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) { let mut v = ~[]; for f(s) |s| { v.push(s.to_owned()) } assert!(vec::all2(v, u, |a,b| a == b)); @@ -3037,7 +3424,7 @@ mod tests { #[test] fn test_words () { - fn t(s: &str, f: &fn(&str, &fn(&str) -> bool), u: &[~str]) { + fn t(s: &str, f: &fn(&str, &fn(&str) -> bool) -> bool, u: &[~str]) { let mut v = ~[]; for f(s) |s| { v.push(s.to_owned()) } assert!(vec::all2(v, u, |a,b| a == b)); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 19c417dfdfc..846d4a34950 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -110,9 +110,14 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); assert!(was_present); } +#[cfg(stage0)] pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { tasks.each(|k| blk(*k)) } +#[cfg(not(stage0))] +pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) -> bool { + tasks.each(|k| blk(*k)) +} // One of these per group of linked-failure tasks. struct TaskGroupData { @@ -685,13 +690,11 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { }; // Attempt to join every ancestor group. result = - for each_ancestor(ancestors, Some(bail)) |ancestor_tg| { + each_ancestor(ancestors, Some(bail), |ancestor_tg| { // Enlist as a descendant, not as an actual member. // Descendants don't kill ancestor groups on failure. - if !enlist_in_taskgroup(ancestor_tg, child, false) { - break; - } - }; + enlist_in_taskgroup(ancestor_tg, child, false) + }); // If any ancestor group fails, need to exit this group too. if !result { do access_group(child_arc) |child_tg| { diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index 9e4da7ab488..182a03da4b1 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -21,6 +21,11 @@ use str; pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool; +#[cfg(stage0)] +pub trait IterBytes { + fn iter_bytes(&self, lsb0: bool, f: Cb); +} + /** * A trait to implement in order to make a type hashable; * This works in combination with the trait `Hash::Hash`, and @@ -28,6 +33,7 @@ pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool; * modified when default methods and trait inheritence are * completed. */ +#[cfg(not(stage0))] pub trait IterBytes { /** * Call the provided callback `f` one or more times with @@ -43,9 +49,10 @@ pub trait IterBytes { * left-to-right in declaration order, regardless of * underlying memory endianness. */ - fn iter_bytes(&self, lsb0: bool, f: Cb); + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool; } +#[cfg(stage0)] impl IterBytes for bool { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -54,7 +61,17 @@ impl IterBytes for bool { ]); } } +#[cfg(not(stage0))] +impl IterBytes for bool { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + f([ + *self as u8 + ]) + } +} +#[cfg(stage0)] impl IterBytes for u8 { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -63,7 +80,17 @@ impl IterBytes for u8 { ]); } } +#[cfg(not(stage0))] +impl IterBytes for u8 { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + f([ + *self + ]) + } +} +#[cfg(stage0)] impl IterBytes for u16 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -80,7 +107,25 @@ impl IterBytes for u16 { } } } +#[cfg(not(stage0))] +impl IterBytes for u16 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8 + ]) + } else { + f([ + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for u32 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -101,7 +146,29 @@ impl IterBytes for u32 { } } } +#[cfg(not(stage0))] +impl IterBytes for u32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + ]) + } else { + f([ + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for u64 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -130,73 +197,157 @@ impl IterBytes for u64 { } } } +#[cfg(not(stage0))] +impl IterBytes for u64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + (*self >> 32) as u8, + (*self >> 40) as u8, + (*self >> 48) as u8, + (*self >> 56) as u8 + ]) + } else { + f([ + (*self >> 56) as u8, + (*self >> 48) as u8, + (*self >> 40) as u8, + (*self >> 32) as u8, + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]) + } + } +} +#[cfg(stage0)] impl IterBytes for i8 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u8).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i8 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u8).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i16 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u16).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i16 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u16).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i32 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for i64 { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u64).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for i64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u64).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IterBytes for char { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as u32).iter_bytes(lsb0, f) } } - -#[cfg(target_word_size = "32")] -pub mod x32 { - use to_bytes::{Cb, IterBytes}; - - impl IterBytes for uint { - #[inline(always)] - fn iter_bytes(&self, lsb0: bool, f: Cb) { - (*self as u32).iter_bytes(lsb0, f) - } +#[cfg(not(stage0))] +impl IterBytes for char { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) } } -#[cfg(target_word_size = "64")] -pub mod x64 { - use to_bytes::{Cb, IterBytes}; +#[cfg(target_word_size = "32", stage0)] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u32).iter_bytes(lsb0, f) + } +} +#[cfg(target_word_size = "32", not(stage0))] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u32).iter_bytes(lsb0, f) + } +} - impl IterBytes for uint { - #[inline(always)] - fn iter_bytes(&self, lsb0: bool, f: Cb) { - (*self as u64).iter_bytes(lsb0, f) - } +#[cfg(target_word_size = "64", stage0)] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u64).iter_bytes(lsb0, f) + } +} +#[cfg(target_word_size = "64", not(stage0))] +impl IterBytes for uint { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as u64).iter_bytes(lsb0, f) } } +#[cfg(stage0)] impl IterBytes for int { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl IterBytes for int { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl<'self,A:IterBytes> IterBytes for &'self [A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -207,7 +358,15 @@ impl<'self,A:IterBytes> IterBytes for &'self [A] { } } } +#[cfg(not(stage0))] +impl<'self,A:IterBytes> IterBytes for &'self [A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + self.each(|elt| elt.iter_bytes(lsb0, |b| f(b))) + } +} +#[cfg(stage0)] impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -218,7 +377,17 @@ impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) { } } } +#[cfg(not(stage0))] +impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) } + } + } +} +#[cfg(stage0)] impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -229,26 +398,57 @@ impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) { } } } +#[cfg(not(stage0))] +impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + (ref a, ref b, ref c) => { + a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) && c.iter_bytes(lsb0, f) + } + } + } +} // Move this to vec, probably. fn borrow<'x,A>(a: &'x [A]) -> &'x [A] { a } +#[cfg(stage0)] impl<A:IterBytes> IterBytes for ~[A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl<A:IterBytes> IterBytes for ~[A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + borrow(*self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl<A:IterBytes> IterBytes for @[A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { borrow(*self).iter_bytes(lsb0, f) } } +#[cfg(not(stage0))] +impl<A:IterBytes> IterBytes for @[A] { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + borrow(*self).iter_bytes(lsb0, f) + } +} + +// NOTE: remove all of these after a snapshot, the new for-loop iteration +// protocol makes these unnecessary. +#[cfg(stage0)] pub fn iter_bytes_2<A:IterBytes,B:IterBytes>(a: &A, b: &B, lsb0: bool, z: Cb) { let mut flag = true; @@ -256,11 +456,17 @@ pub fn iter_bytes_2<A:IterBytes,B:IterBytes>(a: &A, b: &B, if !flag { return; } b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } +#[cfg(not(stage0))] +pub fn iter_bytes_2<A:IterBytes,B:IterBytes>(a: &A, b: &B, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) +} +#[cfg(stage0)] pub fn iter_bytes_3<A: IterBytes, - B: IterBytes, - C: IterBytes>(a: &A, b: &B, c: &C, - lsb0: bool, z: Cb) { + B: IterBytes, + C: IterBytes>(a: &A, b: &B, c: &C, + lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } @@ -268,7 +474,14 @@ pub fn iter_bytes_3<A: IterBytes, if !flag { return; } c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } +#[cfg(not(stage0))] +pub fn iter_bytes_3<A: IterBytes, + B: IterBytes, + C: IterBytes>(a: &A, b: &B, c: &C, lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) +} +#[cfg(stage0)] pub fn iter_bytes_4<A: IterBytes, B: IterBytes, C: IterBytes, @@ -284,33 +497,24 @@ pub fn iter_bytes_4<A: IterBytes, if !flag { return; } d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } - -pub fn iter_bytes_5<A: IterBytes, +#[cfg(not(stage0))] +pub fn iter_bytes_4<A: IterBytes, B: IterBytes, C: IterBytes, - D: IterBytes, - E: IterBytes>(a: &A, b: &B, c: &C, - d: &D, e: &E, - lsb0: bool, z: Cb) { - let mut flag = true; - a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + D: IterBytes>(a: &A, b: &B, c: &C, + d: &D, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) && + d.iter_bytes(lsb0, z) } -pub fn iter_bytes_6<A: IterBytes, +#[cfg(stage0)] +pub fn iter_bytes_5<A: IterBytes, B: IterBytes, C: IterBytes, D: IterBytes, - E: IterBytes, - F: IterBytes>(a: &A, b: &B, c: &C, - d: &D, e: &E, f: &F, + E: IterBytes>(a: &A, b: &B, c: &C, + d: &D, e: &E, lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); @@ -322,36 +526,20 @@ pub fn iter_bytes_6<A: IterBytes, d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); if !flag { return; } e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } - -pub fn iter_bytes_7<A: IterBytes, +#[cfg(not(stage0))] +pub fn iter_bytes_5<A: IterBytes, B: IterBytes, C: IterBytes, D: IterBytes, - E: IterBytes, - F: IterBytes, - G: IterBytes>(a: &A, b: &B, c: &C, - d: &D, e: &E, f: &F, - g: &G, - lsb0: bool, z: Cb) { - let mut flag = true; - a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); - if !flag { return; } - g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); + E: IterBytes>(a: &A, b: &B, c: &C, + d: &D, e: &E, + lsb0: bool, z: Cb) -> bool { + a.iter_bytes(lsb0, z) && b.iter_bytes(lsb0, z) && c.iter_bytes(lsb0, z) && + d.iter_bytes(lsb0, z) && e.iter_bytes(lsb0, z) } +#[cfg(stage0)] impl<'self> IterBytes for &'self str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -360,7 +548,17 @@ impl<'self> IterBytes for &'self str { } } } +#[cfg(not(stage0))] +impl<'self> IterBytes for &'self str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl IterBytes for ~str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -369,7 +567,17 @@ impl IterBytes for ~str { } } } +#[cfg(not(stage0))] +impl IterBytes for ~str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl IterBytes for @str { #[inline(always)] fn iter_bytes(&self, _lsb0: bool, f: Cb) { @@ -378,7 +586,17 @@ impl IterBytes for @str { } } } +#[cfg(not(stage0))] +impl IterBytes for @str { + #[inline(always)] + fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { + do str::byte_slice(*self) |bytes| { + f(bytes) + } + } +} +#[cfg(stage0)] impl<A:IterBytes> IterBytes for Option<A> { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { @@ -388,36 +606,80 @@ impl<A:IterBytes> IterBytes for Option<A> { } } } +#[cfg(not(stage0))] +impl<A:IterBytes> IterBytes for Option<A> { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f), + None => 1u8.iter_bytes(lsb0, f) + } + } +} +#[cfg(stage0)] impl<'self,A:IterBytes> IterBytes for &'self A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl<'self,A:IterBytes> IterBytes for &'self A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl<A:IterBytes> IterBytes for @A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl<A:IterBytes> IterBytes for @A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl<A:IterBytes> IterBytes for ~A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (**self).iter_bytes(lsb0, f); } } +#[cfg(not(stage0))] +impl<A:IterBytes> IterBytes for ~A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (**self).iter_bytes(lsb0, f) + } +} // NB: raw-pointer IterBytes does _not_ dereference // to the target; it just gives you the pointer-bytes. +#[cfg(stage0)] impl<A> IterBytes for *const A { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) { (*self as uint).iter_bytes(lsb0, f); } } +// NB: raw-pointer IterBytes does _not_ dereference +// to the target; it just gives you the pointer-bytes. +#[cfg(not(stage0))] +impl<A> IterBytes for *const A { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as uint).iter_bytes(lsb0, f) + } +} pub trait ToBytes { fn to_bytes(&self, lsb0: bool) -> ~[u8]; diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index af1c1aa83c3..05ef1cf433f 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -57,28 +57,60 @@ impl<T> Map<uint, T> for TrieMap<T> { /// Visit all key-value pairs in order #[inline(always)] + #[cfg(stage0)] fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) { self.root.each(f); } + /// Visit all key-value pairs in order + #[inline(always)] + #[cfg(not(stage0))] + fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each(f) + } + /// Visit all keys in order #[inline(always)] + #[cfg(stage0)] fn each_key(&self, f: &fn(&uint) -> bool) { self.each(|k, _| f(k)) } + /// Visit all keys in order + #[inline(always)] + #[cfg(not(stage0))] + fn each_key(&self, f: &fn(&uint) -> bool) -> bool { + self.each(|k, _| f(k)) + } + /// Visit all values in order #[inline(always)] + #[cfg(stage0)] fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) { self.each(|_, v| f(v)) } + /// Visit all values in order + #[inline(always)] + #[cfg(not(stage0))] + fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { + self.each(|_, v| f(v)) + } + /// Iterate over the map and mutate the contained values #[inline(always)] + #[cfg(stage0)] fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) { self.root.mutate_values(f); } + /// Iterate over the map and mutate the contained values + #[inline(always)] + #[cfg(not(stage0))] + fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { + self.root.mutate_values(f) + } + /// Return a reference to the value corresponding to the key #[inline(hint)] fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { @@ -151,21 +183,43 @@ pub impl<T> TrieMap<T> { /// Visit all key-value pairs in reverse order #[inline(always)] + #[cfg(stage0)] fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) { self.root.each_reverse(f); } + /// Visit all key-value pairs in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each_reverse(f) + } + /// Visit all keys in reverse order #[inline(always)] + #[cfg(stage0)] fn each_key_reverse(&self, f: &fn(&uint) -> bool) { self.each_reverse(|k, _| f(k)) } + /// Visit all keys in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool { + self.each_reverse(|k, _| f(k)) + } /// Visit all values in reverse order #[inline(always)] + #[cfg(stage0)] fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|_, v| f(v)) } + /// Visit all values in reverse order + #[inline(always)] + #[cfg(not(stage0))] + fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool { + self.each_reverse(|_, v| f(v)) + } } pub struct TrieSet { @@ -175,7 +229,10 @@ pub struct TrieSet { impl BaseIter<uint> for TrieSet { /// Visit all values in order #[inline(always)] + #[cfg(stage0)] fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } + #[cfg(not(stage0))] + fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } #[inline(always)] fn size_hint(&self) -> Option<uint> { Some(self.len()) } } @@ -183,9 +240,14 @@ impl BaseIter<uint> for TrieSet { impl ReverseIter<uint> for TrieSet { /// Visit all values in reverse order #[inline(always)] + #[cfg(stage0)] fn each_reverse(&self, f: &fn(&uint) -> bool) { self.map.each_key_reverse(f) } + #[cfg(not(stage0))] + fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool { + self.map.each_key_reverse(f) + } } impl Container for TrieSet { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 3f3691670ef..7eba2cbf0cc 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1489,13 +1489,14 @@ pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] { * ~~~ */ #[inline(always)] -pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { +pub fn _each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { // ^^^^ // NB---this CANNOT be &const [T]! The reason // is that you are passing it to `f()` using // an immutable. - do vec::as_imm_buf(v) |p, n| { + let mut broke = false; + do as_imm_buf(v) |p, n| { let mut n = n; let mut p = p; while n > 0u { @@ -1506,42 +1507,69 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { } n -= 1u; } + broke = n > 0; } + return true; } +#[cfg(stage0)] +pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) { _each(v, f); } +#[cfg(not(stage0))] +pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { _each(v, f) } + /// Like `each()`, but for the case where you have /// a vector with mutable contents and you would like /// to mutate the contents as you iterate. #[inline(always)] -pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) { - do vec::as_mut_buf(v) |p, n| { +pub fn _each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool { + let mut broke = false; + do as_mut_buf(v) |p, n| { let mut n = n; let mut p = p; while n > 0 { unsafe { let q: &'r mut T = cast::transmute_mut_region(&mut *p); - if !f(q) { - break; - } + if !f(q) { break; } p = p.offset(1); } n -= 1; } + broke = n > 0; } + return broke; +} + +#[cfg(stage0)] +pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) { + _each_mut(v, f); +} +#[cfg(not(stage0))] +pub fn each_mut<'r,T>(v: &'r mut [T], f: &fn(elem: &'r mut T) -> bool) -> bool { + _each_mut(v, f) } /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pub fn each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) { +pub fn _each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool { let mut i = 0; let n = v.len(); while i < n { if !f(&const v[i]) { - return; + return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn each_const<t>(v: &const [t], f: &fn(elem: &const t) -> bool) { + _each_const(v, f); +} +#[cfg(not(stage0))] +pub fn each_const<t>(v: &const [t], f: &fn(elem: &const t) -> bool) -> bool { + _each_const(v, f) } /** @@ -1550,12 +1578,20 @@ pub fn each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { +pub fn _eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { let mut i = 0; for each(v) |p| { - if !f(i, p) { return; } + if !f(i, p) { return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { _eachi(v, f); } +#[cfg(not(stage0))] +pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { + _eachi(v, f) } /** @@ -1564,14 +1600,26 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { +pub fn _eachi_mut<'r,T>(v: &'r mut [T], + f: &fn(uint, v: &'r mut T) -> bool) -> bool { let mut i = 0; for each_mut(v) |p| { if !f(i, p) { - return; + return false; } i += 1; } + return true; +} + +#[cfg(stage0)] +pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { + _eachi_mut(v, f); +} +#[cfg(not(stage0))] +pub fn eachi_mut<'r,T>(v: &'r mut [T], + f: &fn(uint, v: &'r mut T) -> bool) -> bool { + _eachi_mut(v, f) } /** @@ -1580,8 +1628,17 @@ pub fn eachi_mut<'r,T>(v: &'r mut [T], f: &fn(uint, v: &'r mut T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] +pub fn _each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool { + _eachi_reverse(v, |_i, v| blk(v)) +} + +#[cfg(stage0)] pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) { - eachi_reverse(v, |_i, v| blk(v)) + _each_reverse(v, blk); +} +#[cfg(not(stage0))] +pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) -> bool { + _each_reverse(v, blk) } /** @@ -1590,14 +1647,26 @@ pub fn each_reverse<'r,T>(v: &'r [T], blk: &fn(v: &'r T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { +pub fn _eachi_reverse<'r,T>(v: &'r [T], + blk: &fn(i: uint, v: &'r T) -> bool) -> bool { let mut i = v.len(); while i > 0 { i -= 1; if !blk(i, &v[i]) { - return; + return false; } } + return true; +} + +#[cfg(stage0)] +pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { + _eachi_reverse(v, blk); +} +#[cfg(not(stage0))] +pub fn eachi_reverse<'r,T>(v: &'r [T], + blk: &fn(i: uint, v: &'r T) -> bool) -> bool { + _eachi_reverse(v, blk) } /** @@ -1608,13 +1677,23 @@ pub fn eachi_reverse<'r,T>(v: &'r [T], blk: &fn(i: uint, v: &'r T) -> bool) { * Both vectors must have the same length */ #[inline] -pub fn each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { +pub fn _each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool { assert!(len(v1) == len(v2)); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { - return; + return false; } } + return true; +} + +#[cfg(stage0)] +pub fn each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { + _each2(v1, v2, f); +} +#[cfg(not(stage0))] +pub fn each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) -> bool { + _each2(v1, v2, f) } /** @@ -1627,7 +1706,8 @@ pub fn each2<U, T>(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) { +#[cfg(not(stage0))] +pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) -> bool { let ln = len(v); if ln <= 1 { put(v); @@ -1641,12 +1721,13 @@ pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) { rest.push_all(const_slice(v, i+1u, ln)); for each_permutation(rest) |permutation| { if !put(append(~[elt], permutation)) { - return; + return false; } } i += 1u; } } + return true; } /** @@ -1663,6 +1744,7 @@ pub fn each_permutation<T:Copy>(v: &[T], put: &fn(ts: &[T]) -> bool) { * ~~~ * */ +#[cfg(stage0)] pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) { assert!(1u <= n); if n > v.len() { return; } @@ -1670,6 +1752,29 @@ pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) { if !it(v.slice(i, i + n)) { return } } } +/** + * Iterate over all contiguous windows of length `n` of the vector `v`. + * + * # Example + * + * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`) + * + * ~~~ + * for windowed(2, &[1,2,3,4]) |v| { + * io::println(fmt!("%?", v)); + * } + * ~~~ + * + */ +#[cfg(not(stage0))] +pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool { + assert!(1u <= n); + if n > v.len() { return true; } + for uint::range(0, v.len() - n + 1) |i| { + if !it(v.slice(i, i + n)) { return false; } + } + return true; +} /** * Work with the buffer of a vector. @@ -1932,8 +2037,14 @@ pub trait ImmutableVector<'self, T> { fn initn(&self, n: uint) -> &'self [T]; fn last(&self) -> &'self T; fn last_opt(&self) -> Option<&'self T>; + #[cfg(stage0)] fn each_reverse(&self, blk: &fn(&T) -> bool); + #[cfg(not(stage0))] + fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool; + #[cfg(stage0)] fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool); + #[cfg(not(stage0))] + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool; fn foldr<'a, U>(&'a self, z: U, p: &fn(t: &'a T, u: U) -> U) -> U; fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U]; fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; @@ -1995,15 +2106,29 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// Iterates over a vector's elements in reverse. #[inline] + #[cfg(stage0)] fn each_reverse(&self, blk: &fn(&T) -> bool) { each_reverse(*self, blk) } + /// Iterates over a vector's elements in reverse. + #[inline] + #[cfg(not(stage0))] + fn each_reverse(&self, blk: &fn(&T) -> bool) -> bool { + each_reverse(*self, blk) + } /// Iterates over a vector's elements and indices in reverse. + #[cfg(stage0)] #[inline] fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) { eachi_reverse(*self, blk) } + /// Iterates over a vector's elements and indices in reverse. + #[cfg(not(stage0))] + #[inline] + fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) -> bool { + eachi_reverse(*self, blk) + } /// Reduce a vector from right to left #[inline] @@ -2555,44 +2680,81 @@ pub mod bytes { // ITERATION TRAIT METHODS impl<'self,A> old_iter::BaseIter<A> for &'self [A] { + #[cfg(stage0)] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option<uint> { Some(self.len()) } } // FIXME(#4148): This should be redundant impl<A> old_iter::BaseIter<A> for ~[A] { + #[cfg(stage0)] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option<uint> { Some(self.len()) } } // FIXME(#4148): This should be redundant impl<A> old_iter::BaseIter<A> for @[A] { + #[cfg(stage0)] + #[inline(always)] + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { + each(*self, blk) + } + #[cfg(not(stage0))] #[inline(always)] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } + fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { + each(*self, blk) + } #[inline(always)] fn size_hint(&self) -> Option<uint> { Some(self.len()) } } impl<'self,A> old_iter::MutableIter<A> for &'self mut [A] { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { + each_mut(*self, blk) + } } // FIXME(#4148): This should be redundant impl<A> old_iter::MutableIter<A> for ~[A] { + #[cfg(stage0)] #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) } + #[cfg(not(stage0))] + #[inline(always)] + fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) -> bool { + each_mut(*self, blk) + } } // FIXME(#4148): This should be redundant +#[cfg(stage0)] impl<A> old_iter::MutableIter<A> for @mut [A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) { @@ -2600,10 +2762,23 @@ impl<A> old_iter::MutableIter<A> for @mut [A] { } } +#[cfg(not(stage0))] +impl<A> old_iter::MutableIter<A> for @mut [A] { + #[inline(always)] + fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) -> bool { + each_mut(*self, blk) + } +} + impl<'self,A> old_iter::ExtendedIter<A> for &'self [A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -2627,16 +2802,27 @@ impl<'self,A> old_iter::ExtendedIter<A> for &'self [A] { impl<'self,A> old_iter::ExtendedMutableIter<A> for &'self mut [A] { #[inline(always)] + #[cfg(stage0)] pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) { eachi_mut(*self, blk) } + #[inline(always)] + #[cfg(not(stage0))] + pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) -> bool { + eachi_mut(*self, blk) + } } // FIXME(#4148): This should be redundant impl<A> old_iter::ExtendedIter<A> for ~[A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -2660,9 +2846,14 @@ impl<A> old_iter::ExtendedIter<A> for ~[A] { // FIXME(#4148): This should be redundant impl<A> old_iter::ExtendedIter<A> for @[A] { + #[cfg(stage0)] pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { old_iter::eachi(self, blk) } + #[cfg(not(stage0))] + pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { + old_iter::eachi(self, blk) + } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { old_iter::all(self, blk) } @@ -4399,7 +4590,7 @@ mod tests { } i += 0; false - } + }; } #[test] @@ -4414,7 +4605,7 @@ mod tests { } i += 0; false - } + }; } #[test]  | 
