about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-07-09 21:59:30 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-07-09 22:05:42 -0400
commitf74250e3a970f81388a73aeb8f3d53304d77c34b (patch)
tree11f09e9cf29767eaac299c1f01ee1b260d7bf640
parent137d1fb210a844a76f89d7355a1aaf9f7a88af33 (diff)
downloadrust-f74250e3a970f81388a73aeb8f3d53304d77c34b.tar.gz
rust-f74250e3a970f81388a73aeb8f3d53304d77c34b.zip
vec::with_capacity: do one alloc for non-managed
-rw-r--r--src/libstd/vec.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 2d730b7a6a2..0b29caacb7a 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -27,7 +27,7 @@ use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
 use ptr;
 use ptr::RawPtr;
-use rt::global_heap::realloc_raw;
+use rt::global_heap::{malloc_raw, realloc_raw};
 use sys;
 use sys::size_of;
 use uint;
@@ -101,12 +101,31 @@ pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] {
 }
 
 /// Creates a new vector with a capacity of `capacity`
+#[cfg(stage0)]
 pub fn with_capacity<T>(capacity: uint) -> ~[T] {
     let mut vec = ~[];
     vec.reserve(capacity);
     vec
 }
 
+/// Creates a new vector with a capacity of `capacity`
+#[cfg(not(stage0))]
+pub fn with_capacity<T>(capacity: uint) -> ~[T] {
+    unsafe {
+        if contains_managed::<T>() {
+            let mut vec = ~[];
+            vec.reserve(capacity);
+            vec
+        } else {
+            let alloc = capacity * sys::nonzero_size_of::<T>();
+            let ptr = malloc_raw(alloc + size_of::<raw::VecRepr>()) as *mut raw::VecRepr;
+            (*ptr).unboxed.alloc = alloc;
+            (*ptr).unboxed.fill = 0;
+            cast::transmute(ptr)
+        }
+    }
+}
+
 /**
  * Builds a vector by calling a provided function with an argument
  * function that pushes an element to the back of a vector.