]> git.lizzy.rs Git - rust.git/commitdiff
core: add consume_reverse
authorErick Tryzelaar <erick.tryzelaar@gmail.com>
Fri, 29 Mar 2013 14:29:52 +0000 (07:29 -0700)
committerErick Tryzelaar <erick.tryzelaar@gmail.com>
Fri, 29 Mar 2013 16:04:26 +0000 (09:04 -0700)
src/libcore/vec.rs

index 174960560dfd6baad347b829e882ea8128f5cc96..426166ec430aec31382d8e4b43fff23a79e6595a 100644 (file)
@@ -558,6 +558,28 @@ pub fn consume<T>(mut v: ~[T], f: &fn(uint, v: T)) {
     }
 }
 
+pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
+    unsafe {
+        do as_mut_buf(v) |p, ln| {
+            let mut i = ln;
+            while i > 0 {
+                i -= 1;
+
+                // NB: This unsafe operation counts on init writing 0s to the
+                // holes we create in the vector. That ensures that, if the
+                // iterator fails then we won't try to clean up the consumed
+                // elements during unwinding
+                let mut x = intrinsics::init();
+                let p = ptr::mut_offset(p, i);
+                x <-> *p;
+                f(i, x);
+            }
+        }
+
+        raw::set_len(&mut v, 0);
+    }
+}
+
 /// Remove the last element from a vector and return it
 pub fn pop<T>(v: &mut ~[T]) -> T {
     let ln = v.len();
@@ -1983,6 +2005,7 @@ pub trait OwnedVector<T> {
     fn truncate(&mut self, newlen: uint);
     fn retain(&mut self, f: &fn(t: &T) -> bool);
     fn consume(self, f: &fn(uint, v: T));
+    fn consume_reverse(self, f: &fn(uint, v: T));
     fn filter(self, f: &fn(t: &T) -> bool) -> ~[T];
     fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]);
     fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>);
@@ -2044,6 +2067,11 @@ fn consume(self, f: &fn(uint, v: T)) {
         consume(self, f)
     }
 
+    #[inline]
+    fn consume_reverse(self, f: &fn(uint, v: T)) {
+        consume_reverse(self, f)
+    }
+
     #[inline]
     fn filter(self, f: &fn(&T) -> bool) -> ~[T] {
         filter(self, f)