]> git.lizzy.rs Git - rust.git/commitdiff
vec::with_capacity: do one alloc for non-managed
authorDaniel Micay <danielmicay@gmail.com>
Wed, 10 Jul 2013 01:59:30 +0000 (21:59 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Wed, 10 Jul 2013 02:05:42 +0000 (22:05 -0400)
src/libstd/vec.rs

index 2d730b7a6a2004efdd0f76c434dd3be2acc6e522..0b29caacb7a3553b7c5e4d62f26ea473428ab2c4 100644 (file)
@@ -27,7 +27,7 @@
 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.