diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
index 2a5df0ea1563..bdbdb6cef16b 100644
--- a/src/libcore/dvec.rs
+++ b/src/libcore/dvec.rs
@@ -76,7 +76,7 @@ fn unwrap(-d: dvec) -> ~[mut A] {
}
impl private_methods for dvec {
- fn check_not_borrowed() {
+ pure fn check_not_borrowed() {
unsafe {
let data: *() = unsafe::reinterpret_cast(self.data);
if data.is_null() {
@@ -119,11 +119,13 @@ fn swap(f: fn(-~[mut A]) -> ~[mut A]) {
}
/// Returns the number of elements currently in the dvec
- fn len() -> uint {
- do self.borrow |v| {
- let l = v.len();
- self.return(v);
- l
+ pure fn len() -> uint {
+ unchecked {
+ do self.borrow |v| {
+ let l = v.len();
+ self.return(v);
+ l
+ }
}
}
@@ -172,6 +174,13 @@ fn shift() -> A {
result
}
}
+
+ // Reverse the elements in the list, in place
+ fn reverse() {
+ do self.borrow |v| {
+ vec::reverse(v);
+ }
+ }
}
impl extensions for dvec {
@@ -229,23 +238,25 @@ fn append_iter>(ts: I) {
*
* See `unwrap()` if you do not wish to copy the contents.
*/
- fn get() -> ~[A] {
- do self.borrow |v| {
- let w = vec::from_mut(copy v);
- self.return(v);
- w
+ pure fn get() -> ~[A] {
+ unchecked {
+ do self.borrow |v| {
+ let w = vec::from_mut(copy v);
+ self.return(v);
+ w
+ }
}
}
/// Copy out an individual element
#[inline(always)]
- fn [](idx: uint) -> A {
+ pure fn [](idx: uint) -> A {
self.get_elt(idx)
}
/// Copy out an individual element
#[inline(always)]
- fn get_elt(idx: uint) -> A {
+ pure fn get_elt(idx: uint) -> A {
self.check_not_borrowed();
ret self.data[idx];
}
@@ -271,7 +282,7 @@ fn grow_set_elt(idx: uint, initval: A, val: A) {
/// Returns the last element, failing if the vector is empty
#[inline(always)]
- fn last() -> A {
+ pure fn last() -> A {
self.check_not_borrowed();
let length = self.len();
@@ -285,13 +296,12 @@ fn last() -> A {
/// Iterates over the elements in reverse order
#[inline(always)]
fn reach(f: fn(A) -> bool) {
- let length = self.len();
- let mut i = 0u;
- while i < length {
- if !f(self.get_elt(i)) {
- break;
- }
- i += 1u;
- }
+ do self.swap |v| { vec::reach(v, f); v }
+ }
+
+ /// Iterates over the elements and indices in reverse order
+ #[inline(always)]
+ fn reachi(f: fn(uint, A) -> bool) {
+ do self.swap |v| { vec::reachi(v, f); v }
}
}
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 475f15576102..60e3373fdbe0 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -71,7 +71,7 @@
export swap;
export reverse;
export reversed;
-export iter, iter_between, each, eachi;
+export iter, iter_between, each, eachi, reach, reachi;
export iter2;
export iteri;
export riter;
@@ -204,12 +204,12 @@ fn reserve_at_least(&v: ~[const T], n: uint) {
}
/// Produces a mut vector from an immutable vector.
-fn to_mut(+v: ~[T]) -> ~[mut T] {
+pure fn to_mut(+v: ~[T]) -> ~[mut T] {
unsafe { ::unsafe::transmute(v) }
}
/// Produces an immutable vector from a mut vector.
-fn from_mut(+v: ~[mut T]) -> ~[T] {
+pure fn from_mut(+v: ~[mut T]) -> ~[T] {
unsafe { ::unsafe::transmute(v) }
}
@@ -1038,6 +1038,42 @@ fn reverse(v: ~[mut T]) {
}
}
+/**
+ * Iterates over a vector's elements in reverse
+ *
+ * Return true to continue, false to break.
+ */
+#[inline(always)]
+pure fn reach(v: &[T], blk: fn(T) -> bool) {
+ do vec::unpack_slice(v) |p, n| {
+ let mut i = 1;
+ while i <= n {
+ unsafe {
+ if !blk(*ptr::offset(p, n-i)) { break; }
+ }
+ i += 1;
+ }
+ }
+}
+
+/**
+ * Iterates over a vector's elements and indices in reverse
+ *
+ * Return true to continue, false to break.
+ */
+#[inline(always)]
+pure fn reachi(v: &[T], blk: fn(uint, T) -> bool) {
+ do vec::unpack_slice(v) |p, n| {
+ let mut i = 1;
+ while i <= n {
+ unsafe {
+ if !blk(n-i, *ptr::offset(p, n-i)) { break; }
+ }
+ i += 1;
+ }
+ }
+}
+
/**
* Iterates over two vectors simultaneously
*