about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorJames Miller <bladeon@gmail.com>2013-05-09 23:05:17 +1200
committerJames Miller <bladeon@gmail.com>2013-05-09 23:05:17 +1200
commit57509709b4ecc31b04b765bd07cd5fe672667e43 (patch)
tree06fe9f2223bc168a5b862630f02b502d8d77a0f7 /src/libcore
parentf5ab112e6b083ab20fdcf9e2fff7dde4a85940b0 (diff)
downloadrust-57509709b4ecc31b04b765bd07cd5fe672667e43.tar.gz
rust-57509709b4ecc31b04b765bd07cd5fe672667e43.zip
Make staged versions of the functions that use uninit
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/cast.rs14
-rw-r--r--src/libcore/vec.rs90
2 files changed, 104 insertions, 0 deletions
diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs
index fe5da8bae69..7451353458e 100644
--- a/src/libcore/cast.rs
+++ b/src/libcore/cast.rs
@@ -24,6 +24,7 @@ pub mod rusti {
 }
 
 /// Casts the value at `src` to U. The two types must have the same length.
+#[cfg(not(stage0))]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     let mut dest: U = unstable::intrinsics::uninit();
     {
@@ -36,6 +37,19 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     dest
 }
 
+#[cfg(stage0)]
+pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
+    let mut dest: U = unstable::intrinsics::init();
+    {
+        let dest_ptr: *mut u8 = rusti::transmute(&mut dest);
+        let src_ptr: *u8 = rusti::transmute(src);
+        unstable::intrinsics::memmove64(dest_ptr,
+                                        src_ptr,
+                                        sys::size_of::<U>() as u64);
+    }
+    dest
+}
+
 /**
  * Move a thing into the void
  *
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index ea780ff9bdd..137a573fb79 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -584,6 +584,7 @@ pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
 }
 
 /// Remove the last element from a vector and return it
+#[cfg(not(stage0))]
 pub fn pop<T>(v: &mut ~[T]) -> T {
     let ln = v.len();
     if ln == 0 {
@@ -598,6 +599,21 @@ pub fn pop<T>(v: &mut ~[T]) -> T {
     }
 }
 
+#[cfg(stage0)]
+pub fn pop<T>(v: &mut ~[T]) -> T {
+    let ln = v.len();
+    if ln == 0 {
+        fail!(~"sorry, cannot vec::pop an empty vector")
+    }
+    let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
+    unsafe {
+        let mut val = intrinsics::init();
+        val <-> *valptr;
+        raw::set_len(v, ln - 1u);
+        val
+    }
+}
+
 /**
  * Remove an element from anywhere in the vector and return it, replacing it
  * with the last element. This does not preserve ordering, but is O(1).
@@ -659,6 +675,7 @@ pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
 }
 
 #[inline(always)]
+#[cfg(not(stage0))]
 pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
     let new_len = v.len() + rhs.len();
     reserve(&mut *v, new_len);
@@ -674,7 +691,25 @@ pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
     }
 }
 
+#[inline(always)]
+#[cfg(stage0)]
+pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
+    let new_len = v.len() + rhs.len();
+    reserve(&mut *v, new_len);
+    unsafe {
+        do as_mut_buf(rhs) |p, len| {
+            for uint::range(0, len) |i| {
+                let mut x = intrinsics::init();
+                x <-> *ptr::mut_offset(p, i);
+                push(&mut *v, x);
+            }
+        }
+        raw::set_len(&mut rhs, 0);
+    }
+}
+
 /// Shorten a vector, dropping excess elements.
+#[cfg(not(stage0))]
 pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
     do as_mut_buf(*v) |p, oldlen| {
         assert!(newlen <= oldlen);
@@ -689,10 +724,27 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
     unsafe { raw::set_len(&mut *v, newlen); }
 }
 
+/// Shorten a vector, dropping excess elements.
+#[cfg(stage0)]
+pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
+    do as_mut_buf(*v) |p, oldlen| {
+        assert!(newlen <= oldlen);
+        unsafe {
+            // This loop is optimized out for non-drop types.
+            for uint::range(newlen, oldlen) |i| {
+                let mut dropped = intrinsics::init();
+                dropped <-> *ptr::mut_offset(p, i);
+            }
+        }
+    }
+    unsafe { raw::set_len(&mut *v, newlen); }
+}
+
 /**
  * Remove consecutive repeated elements from a vector; if the vector is
  * sorted, this removes all duplicates.
  */
+#[cfg(not(stage0))]
 pub fn dedup<T:Eq>(v: &mut ~[T]) {
     unsafe {
         if v.len() < 1 { return; }
@@ -726,6 +778,44 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
     }
 }
 
+/**
+ * Remove consecutive repeated elements from a vector; if the vector is
+ * sorted, this removes all duplicates.
+ */
+#[cfg(stage0)]
+pub fn dedup<T:Eq>(v: &mut ~[T]) {
+    unsafe {
+        if v.len() < 1 { return; }
+        let mut last_written = 0, next_to_read = 1;
+        do as_const_buf(*v) |p, ln| {
+            // We have a mutable reference to v, so we can make arbitrary
+            // changes. (cf. push and pop)
+            let p = p as *mut T;
+            // last_written < next_to_read <= ln
+            while next_to_read < ln {
+                // last_written < next_to_read < ln
+                if *ptr::mut_offset(p, next_to_read) ==
+                    *ptr::mut_offset(p, last_written) {
+                    let mut dropped = intrinsics::init();
+                    dropped <-> *ptr::mut_offset(p, next_to_read);
+                } else {
+                    last_written += 1;
+                    // last_written <= next_to_read < ln
+                    if next_to_read != last_written {
+                        *ptr::mut_offset(p, last_written) <->
+                            *ptr::mut_offset(p, next_to_read);
+                    }
+                }
+                // last_written <= next_to_read < ln
+                next_to_read += 1;
+                // last_written < next_to_read <= ln
+            }
+        }
+        // last_written < next_to_read == ln
+        raw::set_len(v, last_written + 1);
+    }
+}
+
 
 // Appending
 #[inline(always)]