From 4d610e36bdbd1213a9cb1d25fb796792040a0d25 Mon Sep 17 00:00:00 2001 From: Clark Gaebel Date: Tue, 28 Oct 2014 10:22:34 -0700 Subject: [PATCH 1/3] util: Primarily fixes a bug where SmallVec.into_iter just doesn't work. into_iter used to use `inline_size` as the capacity insetad of the actual capacity. This patch fixes that, adds some utility methods to `SmallVec` to bring it closer in functionality to `Vec`, and removes the obsolete `owns_managed` calls. --- components/util/smallvec.rs | 59 ++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs index 5185c4ee521..00c43b76b9e 100644 --- a/components/util/smallvec.rs +++ b/components/util/smallvec.rs @@ -12,7 +12,6 @@ use std::kinds::marker::ContravariantLifetime; use std::mem; use std::ptr; use std::raw::Slice; -use rustrt::local_heap; use alloc::heap; // Generic code for all small vectors @@ -60,6 +59,7 @@ pub trait SmallVecPrivate { pub trait SmallVec : SmallVecPrivate where T: 'static { fn inline_size(&self) -> uint; fn len(&self) -> uint; + fn is_empty(&self) -> bool; fn cap(&self) -> uint; fn spilled(&self) -> bool { @@ -110,12 +110,13 @@ pub trait SmallVec : SmallVecPrivate where T: 'static { } else { None }; + let cap = self.cap(); let inline_size = self.inline_size(); self.set_cap(inline_size); self.set_len(0); SmallVecMoveIterator { allocation: ptr_opt, - cap: inline_size, + cap: cap, iter: iter, lifetime: ContravariantLifetime::<'a>, } @@ -169,13 +170,9 @@ pub trait SmallVec : SmallVecPrivate where T: 'static { ptr::copy_nonoverlapping_memory(new_alloc, self.begin(), self.len()); if self.spilled() { - if intrinsics::owns_managed::() { - local_heap::local_free(self.ptr() as *mut u8) - } else { - heap::deallocate(self.mut_ptr() as *mut u8, - mem::size_of::() * self.cap(), - mem::min_align_of::()) - } + heap::deallocate(self.mut_ptr() as *mut u8, + mem::size_of::() * self.cap(), + mem::min_align_of::()) } else { let mut_begin: *mut T = mem::transmute(self.begin()); intrinsics::set_memory(mut_begin, 0, self.len()) @@ -326,13 +323,9 @@ impl<'a, T: 'static> Drop for SmallVecMoveIterator<'a,T> { None => {} Some(allocation) => { unsafe { - if intrinsics::owns_managed::() { - local_heap::local_free(allocation as *mut u8) - } else { - heap::deallocate(allocation as *mut u8, - mem::size_of::() * self.cap, - mem::min_align_of::()) - } + heap::deallocate(allocation as *mut u8, + mem::size_of::() * self.cap, + mem::min_align_of::()) } } } @@ -383,6 +376,9 @@ macro_rules! def_small_vector( fn len(&self) -> uint { self.len } + fn is_empty(&self) -> bool { + self.len == 0 + } fn cap(&self) -> uint { self.cap } @@ -405,6 +401,26 @@ macro_rules! def_small_vector( } } + impl FromIterator for $name { + fn from_iter>(mut iter: I) -> $name { + let mut v = $name::new(); + + for elem in iter { + v.push(elem); + } + + v + } + } + + impl Extendable for $name { + fn extend>(&mut self, mut iter: I) { + for elem in iter { + self.push(elem); + } + } + } + impl $name { #[inline] pub fn new() -> $name { @@ -444,13 +460,9 @@ macro_rules! def_small_vector_drop_impl( *ptr.offset(i as int) = mem::uninitialized(); } - if intrinsics::owns_managed::() { - local_heap::local_free(self.ptr() as *mut u8) - } else { - heap::deallocate(self.mut_ptr() as *mut u8, - mem::size_of::() * self.cap(), - mem::min_align_of::()) - } + heap::deallocate(self.mut_ptr() as *mut u8, + mem::size_of::() * self.cap(), + mem::min_align_of::()) } } } @@ -527,4 +539,3 @@ pub mod tests { ].as_slice()); } } - From fe363996282a069bb38a3449da59bc411fa9d066 Mon Sep 17 00:00:00 2001 From: Clark Gaebel Date: Tue, 28 Oct 2014 10:36:41 -0700 Subject: [PATCH 2/3] use size hints --- components/util/smallvec.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs index 00c43b76b9e..139c1d09300 100644 --- a/components/util/smallvec.rs +++ b/components/util/smallvec.rs @@ -405,6 +405,12 @@ macro_rules! def_small_vector( fn from_iter>(mut iter: I) -> $name { let mut v = $name::new(); + let (lower_size_bound, _) = iter.size_hint(); + + if lower_size_bound > v.cap() { + v.grow(lower_size_bound); + } + for elem in iter { v.push(elem); } @@ -415,6 +421,14 @@ macro_rules! def_small_vector( impl Extendable for $name { fn extend>(&mut self, mut iter: I) { + let (lower_size_bound, _) = iter.size_hint(); + + let target_len = self.len() + lower_size_bound; + + if target_len > self.cap() { + v.grow(target_len); + } + for elem in iter { self.push(elem); } From d661ec84148f3abd689c081283a2553573a0a115 Mon Sep 17 00:00:00 2001 From: Clark Gaebel Date: Tue, 28 Oct 2014 12:01:33 -0700 Subject: [PATCH 3/3] fix the build --- components/util/smallvec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs index 139c1d09300..f0767c3ec5a 100644 --- a/components/util/smallvec.rs +++ b/components/util/smallvec.rs @@ -426,7 +426,7 @@ macro_rules! def_small_vector( let target_len = self.len() + lower_size_bound; if target_len > self.cap() { - v.grow(target_len); + self.grow(target_len); } for elem in iter {