Skip to content

Commit 156eceb

Browse files
committed
dvec/vec interface cleanup: fixing reach, reverse, adding more pure
1 parent b67bfe5 commit 156eceb

File tree

2 files changed

+71
-25
lines changed

2 files changed

+71
-25
lines changed

src/libcore/dvec.rs

+32-22
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn unwrap<A>(-d: dvec<A>) -> ~[mut A] {
7676
}
7777

7878
impl private_methods<A> for dvec<A> {
79-
fn check_not_borrowed() {
79+
pure fn check_not_borrowed() {
8080
unsafe {
8181
let data: *() = unsafe::reinterpret_cast(self.data);
8282
if data.is_null() {
@@ -119,11 +119,13 @@ impl extensions<A> for dvec<A> {
119119
}
120120

121121
/// Returns the number of elements currently in the dvec
122-
fn len() -> uint {
123-
do self.borrow |v| {
124-
let l = v.len();
125-
self.return(v);
126-
l
122+
pure fn len() -> uint {
123+
unchecked {
124+
do self.borrow |v| {
125+
let l = v.len();
126+
self.return(v);
127+
l
128+
}
127129
}
128130
}
129131

@@ -172,6 +174,13 @@ impl extensions<A> for dvec<A> {
172174
result
173175
}
174176
}
177+
178+
// Reverse the elements in the list, in place
179+
fn reverse() {
180+
do self.borrow |v| {
181+
vec::reverse(v);
182+
}
183+
}
175184
}
176185
177186
impl extensions<A:copy> for dvec<A> {
@@ -229,23 +238,25 @@ impl extensions<A:copy> for dvec<A> {
229238
*
230239
* See `unwrap()` if you do not wish to copy the contents.
231240
*/
232-
fn get() -> ~[A] {
233-
do self.borrow |v| {
234-
let w = vec::from_mut(copy v);
235-
self.return(v);
236-
w
241+
pure fn get() -> ~[A] {
242+
unchecked {
243+
do self.borrow |v| {
244+
let w = vec::from_mut(copy v);
245+
self.return(v);
246+
w
247+
}
237248
}
238249
}
239250
240251
/// Copy out an individual element
241252
#[inline(always)]
242-
fn [](idx: uint) -> A {
253+
pure fn [](idx: uint) -> A {
243254
self.get_elt(idx)
244255
}
245256
246257
/// Copy out an individual element
247258
#[inline(always)]
248-
fn get_elt(idx: uint) -> A {
259+
pure fn get_elt(idx: uint) -> A {
249260
self.check_not_borrowed();
250261
ret self.data[idx];
251262
}
@@ -271,7 +282,7 @@ impl extensions<A:copy> for dvec<A> {
271282
272283
/// Returns the last element, failing if the vector is empty
273284
#[inline(always)]
274-
fn last() -> A {
285+
pure fn last() -> A {
275286
self.check_not_borrowed();
276287
277288
let length = self.len();
@@ -285,13 +296,12 @@ impl extensions<A:copy> for dvec<A> {
285296
/// Iterates over the elements in reverse order
286297
#[inline(always)]
287298
fn reach(f: fn(A) -> bool) {
288-
let length = self.len();
289-
let mut i = 0u;
290-
while i < length {
291-
if !f(self.get_elt(i)) {
292-
break;
293-
}
294-
i += 1u;
295-
}
299+
do self.swap |v| { vec::reach(v, f); v }
300+
}
301+
302+
/// Iterates over the elements and indices in reverse order
303+
#[inline(always)]
304+
fn reachi(f: fn(uint, A) -> bool) {
305+
do self.swap |v| { vec::reachi(v, f); v }
296306
}
297307
}

src/libcore/vec.rs

+39-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export zip;
7171
export swap;
7272
export reverse;
7373
export reversed;
74-
export iter, iter_between, each, eachi;
74+
export iter, iter_between, each, eachi, reach, reachi;
7575
export iter2;
7676
export iteri;
7777
export riter;
@@ -204,12 +204,12 @@ pure fn from_elem<T: copy>(n_elts: uint, t: T) -> ~[T] {
204204
}
205205

206206
/// Produces a mut vector from an immutable vector.
207-
fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
207+
pure fn to_mut<T>(+v: ~[T]) -> ~[mut T] {
208208
unsafe { ::unsafe::transmute(v) }
209209
}
210210

211211
/// Produces an immutable vector from a mut vector.
212-
fn from_mut<T>(+v: ~[mut T]) -> ~[T] {
212+
pure fn from_mut<T>(+v: ~[mut T]) -> ~[T] {
213213
unsafe { ::unsafe::transmute(v) }
214214
}
215215

@@ -1038,6 +1038,42 @@ pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
10381038
}
10391039
}
10401040

1041+
/**
1042+
* Iterates over a vector's elements in reverse
1043+
*
1044+
* Return true to continue, false to break.
1045+
*/
1046+
#[inline(always)]
1047+
pure fn reach<T>(v: &[T], blk: fn(T) -> bool) {
1048+
do vec::unpack_slice(v) |p, n| {
1049+
let mut i = 1;
1050+
while i <= n {
1051+
unsafe {
1052+
if !blk(*ptr::offset(p, n-i)) { break; }
1053+
}
1054+
i += 1;
1055+
}
1056+
}
1057+
}
1058+
1059+
/**
1060+
* Iterates over a vector's elements and indices in reverse
1061+
*
1062+
* Return true to continue, false to break.
1063+
*/
1064+
#[inline(always)]
1065+
pure fn reachi<T>(v: &[T], blk: fn(uint, T) -> bool) {
1066+
do vec::unpack_slice(v) |p, n| {
1067+
let mut i = 1;
1068+
while i <= n {
1069+
unsafe {
1070+
if !blk(n-i, *ptr::offset(p, n-i)) { break; }
1071+
}
1072+
i += 1;
1073+
}
1074+
}
1075+
}
1076+
10411077
/**
10421078
* Iterates over two vectors simultaneously
10431079
*

0 commit comments

Comments
 (0)