about summary refs log tree commit diff
path: root/src/libstd/priority_queue.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-09 12:37:00 -0700
committerbors <bors@rust-lang.org>2013-05-09 12:37:00 -0700
commit76758562539ef3c439dd28ad53636f6b70382e7b (patch)
tree116ee84d37fff9ff3393bb28a66f59bd98a95132 /src/libstd/priority_queue.rs
parentce9c0225c451c00c3eebe4e496185143a18814b9 (diff)
parent414970c46f75c730d7fed029deb48b0d1c454391 (diff)
downloadrust-76758562539ef3c439dd28ad53636f6b70382e7b.tar.gz
rust-76758562539ef3c439dd28ad53636f6b70382e7b.zip
auto merge of #6354 : Aatch/rust/uninit-intrinsic, r=graydon
Adds an `uninit` intrinsic.

It's just an empty function, so llvm optimizes it down to nothing.

I changed all of the `init` intrinsic usages to `uninit` where it seemed appropriate to.


Diffstat (limited to 'src/libstd/priority_queue.rs')
-rw-r--r--src/libstd/priority_queue.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs
index 248650452de..b2f8c9c3c4e 100644
--- a/src/libstd/priority_queue.rs
+++ b/src/libstd/priority_queue.rs
@@ -16,6 +16,8 @@ use core::old_iter::BaseIter;
 extern "rust-intrinsic" mod rusti {
     fn move_val_init<T>(dst: &mut T, src: T);
     fn init<T>() -> T;
+    #[cfg(not(stage0))]
+    fn uninit<T>() -> T;
 }
 
 pub struct PriorityQueue<T> {
@@ -132,6 +134,27 @@ pub impl <T:Ord> PriorityQueue<T> {
     // vector over the junk element.  This reduces the constant factor
     // compared to using swaps, which involves twice as many moves.
 
+    #[cfg(not(stage0))]
+    priv fn siftup(&mut self, start: uint, mut pos: uint) {
+        unsafe {
+            let new = *ptr::to_unsafe_ptr(&self.data[pos]);
+
+            while pos > start {
+                let parent = (pos - 1) >> 1;
+                if new > self.data[parent] {
+                    let mut x = rusti::uninit();
+                    x <-> self.data[parent];
+                    rusti::move_val_init(&mut self.data[pos], x);
+                    pos = parent;
+                    loop
+                }
+                break
+            }
+            rusti::move_val_init(&mut self.data[pos], new);
+        }
+    }
+
+    #[cfg(stage0)]
     priv fn siftup(&mut self, start: uint, mut pos: uint) {
         unsafe {
             let new = *ptr::to_unsafe_ptr(&self.data[pos]);
@@ -151,6 +174,32 @@ pub impl <T:Ord> PriorityQueue<T> {
         }
     }
 
+
+    #[cfg(not(stage0))]
+    priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
+        unsafe {
+            let start = pos;
+            let new = *ptr::to_unsafe_ptr(&self.data[pos]);
+
+            let mut child = 2 * pos + 1;
+            while child < end {
+                let right = child + 1;
+                if right < end && !(self.data[child] > self.data[right]) {
+                    child = right;
+                }
+                let mut x = rusti::uninit();
+                x <-> self.data[child];
+                rusti::move_val_init(&mut self.data[pos], x);
+                pos = child;
+                child = 2 * pos + 1;
+            }
+
+            rusti::move_val_init(&mut self.data[pos], new);
+            self.siftup(start, pos);
+        }
+    }
+
+    #[cfg(stage0)]
     priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
         unsafe {
             let start = pos;