dvec/vec interface cleanup: fixing reach, reverse, adding more pure

This commit is contained in:
Ben Blum 2012-07-17 13:24:04 -04:00
parent b67bfe50ef
commit 156eceb24a
2 changed files with 71 additions and 25 deletions
src/libcore

@ -76,7 +76,7 @@ fn unwrap<A>(-d: dvec<A>) -> ~[mut A] {
}
impl private_methods<A> for dvec<A> {
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 @@ impl extensions<A> for dvec<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 @@ impl extensions<A> for dvec<A> {
result
}
}
// Reverse the elements in the list, in place
fn reverse() {
do self.borrow |v| {
vec::reverse(v);
}
}
}
impl extensions<A:copy> for dvec<A> {
@ -229,23 +238,25 @@ impl extensions<A:copy> for dvec<A> {
*
* 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 @@ impl extensions<A:copy> for dvec<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 @@ impl extensions<A:copy> for dvec<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 }
}
}

@ -71,7 +71,7 @@ export zip;
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 @@ pure fn from_elem<T: copy>(n_elts: uint, t: T) -> ~[T] {
}
/// Produces a mut vector from an immutable vector.
fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
pure fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
unsafe { ::unsafe::transmute(v) }
}
/// Produces an immutable vector from a mut vector.
fn from_mut<T>(+v: ~[mut T]) -> ~[T] {
pure fn from_mut<T>(+v: ~[mut T]) -> ~[T] {
unsafe { ::unsafe::transmute(v) }
}
@ -1038,6 +1038,42 @@ pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
}
}
/**
* Iterates over a vector's elements in reverse
*
* Return true to continue, false to break.
*/
#[inline(always)]
pure fn reach<T>(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<T>(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
*