diff options
| author | Luqman Aden <laden@csclub.uwaterloo.ca> | 2014-12-03 17:22:11 -0500 |
|---|---|---|
| committer | Luqman Aden <laden@csclub.uwaterloo.ca> | 2014-12-28 19:40:47 -0500 |
| commit | bb4473774866a1a9a3965a62db3298f1be874418 (patch) | |
| tree | ea523de3e9476f207ff04ca79d3915eb19cb03b8 | |
| parent | ef5da14edb09d6425b1b6576d418e12c268ddf17 (diff) | |
libcollections: Use NonZero in Vec.
| -rw-r--r-- | src/libcollections/vec.rs | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index d700b187e8a..0739cef3353 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -58,7 +58,7 @@ use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; use core::num::{Int, UnsignedInt}; use core::ops; -use core::ptr::{mod, Unique}; +use core::ptr::{mod, NonZero}; use core::raw::Slice as RawSlice; use core::uint; @@ -133,7 +133,7 @@ use slice::CloneSliceExt; #[unsafe_no_drop_flag] #[stable] pub struct Vec<T> { - ptr: Unique<T>, + ptr: NonZero<*mut T>, len: uint, cap: uint, } @@ -176,7 +176,7 @@ impl<T> Vec<T> { // non-null value which is fine since we never call deallocate on the ptr // if cap is 0. The reason for this is because the pointer of a slice // being NULL would break the null pointer optimization for enums. - Vec { ptr: Unique(EMPTY as *mut T), len: 0, cap: 0 } + Vec { ptr: NonZero(EMPTY as *mut T), len: 0, cap: 0 } } /// Constructs a new, empty `Vec<T>` with the specified capacity. @@ -209,7 +209,7 @@ impl<T> Vec<T> { #[stable] pub fn with_capacity(capacity: uint) -> Vec<T> { if mem::size_of::<T>() == 0 { - Vec { ptr: Unique(EMPTY as *mut T), len: 0, cap: uint::MAX } + Vec { ptr: NonZero(EMPTY as *mut T), len: 0, cap: uint::MAX } } else if capacity == 0 { Vec::new() } else { @@ -217,7 +217,7 @@ impl<T> Vec<T> { .expect("capacity overflow"); let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) }; if ptr.is_null() { ::alloc::oom() } - Vec { ptr: Unique(ptr as *mut T), len: 0, cap: capacity } + Vec { ptr: NonZero(ptr as *mut T), len: 0, cap: capacity } } } @@ -284,7 +284,7 @@ impl<T> Vec<T> { #[unstable = "needs finalization"] pub unsafe fn from_raw_parts(ptr: *mut T, length: uint, capacity: uint) -> Vec<T> { - Vec { ptr: Unique(ptr), len: length, cap: capacity } + Vec { ptr: NonZero(ptr), len: length, cap: capacity } } /// Creates a vector by copying the elements from a raw pointer. @@ -792,10 +792,11 @@ impl<T> Vec<T> { pub fn shrink_to_fit(&mut self) { if mem::size_of::<T>() == 0 { return } + let NonZero(ptr) = self.ptr; if self.len == 0 { if self.cap != 0 { unsafe { - dealloc(self.ptr.0, self.cap) + dealloc(ptr, self.cap) } self.cap = 0; } @@ -803,11 +804,12 @@ impl<T> Vec<T> { unsafe { // Overflow check is unnecessary as the vector is already at // least this large. - self.ptr = Unique(reallocate(self.ptr.0 as *mut u8, - self.cap * mem::size_of::<T>(), - self.len * mem::size_of::<T>(), - mem::min_align_of::<T>()) as *mut T); - if self.ptr.0.is_null() { ::alloc::oom() } + let ptr = reallocate(ptr as *mut u8, + self.cap * mem::size_of::<T>(), + self.len * mem::size_of::<T>(), + mem::min_align_of::<T>()) as *mut T; + if ptr.is_null() { ::alloc::oom() } + self.ptr = NonZero(ptr); } self.cap = self.len; } @@ -865,9 +867,10 @@ impl<T> Vec<T> { #[inline] #[stable] pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { + let NonZero(ptr) = self.ptr; unsafe { mem::transmute(RawSlice { - data: self.ptr.0 as *const T, + data: ptr as *const T, len: self.len, }) } @@ -890,9 +893,9 @@ impl<T> Vec<T> { #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> IntoIter<T> { unsafe { - let ptr = self.ptr.0; + let NonZero(ptr) = self.ptr; let cap = self.cap; - let begin = self.ptr.0 as *const T; + let begin = ptr as *const T; let end = if mem::size_of::<T>() == 0 { (ptr as uint + self.len()) as *const T } else { @@ -1110,14 +1113,16 @@ impl<T> Vec<T> { let size = max(old_size, 2 * mem::size_of::<T>()) * 2; if old_size > size { panic!("capacity overflow") } unsafe { - self.ptr = Unique(alloc_or_realloc(self.ptr.0, old_size, size)); - if self.ptr.0.is_null() { ::alloc::oom() } + let NonZero(ptr) = self.ptr; + let ptr = alloc_or_realloc(ptr, old_size, size); + if ptr.is_null() { ::alloc::oom() } + self.ptr = NonZero(ptr); } self.cap = max(self.cap, 2) * 2; } unsafe { - let end = self.ptr.0.offset(self.len as int); + let NonZero(end) = self.ptr.offset(self.len as int); ptr::write(&mut *end, value); self.len += 1; } @@ -1231,10 +1236,10 @@ impl<T> Vec<T> { let size = capacity.checked_mul(mem::size_of::<T>()) .expect("capacity overflow"); unsafe { - self.ptr = Unique(alloc_or_realloc(self.ptr.0, - self.cap * mem::size_of::<T>(), - size)); - if self.ptr.0.is_null() { ::alloc::oom() } + let NonZero(ptr) = self.ptr; + let ptr = alloc_or_realloc(ptr, self.cap * mem::size_of::<T>(), size); + if ptr.is_null() { ::alloc::oom() } + self.ptr = NonZero(ptr); } self.cap = capacity; } @@ -1355,9 +1360,10 @@ impl<T> AsSlice<T> for Vec<T> { #[inline] #[stable] fn as_slice<'a>(&'a self) -> &'a [T] { + let NonZero(ptr) = self.ptr; unsafe { mem::transmute(RawSlice { - data: self.ptr.0 as *const T, + data: ptr as *const T, len: self.len }) } @@ -1382,7 +1388,8 @@ impl<T> Drop for Vec<T> { for x in self.iter() { ptr::read(x); } - dealloc(self.ptr.0, self.cap) + let NonZero(ptr) = self.ptr; + dealloc(ptr, self.cap) } } } @@ -1420,7 +1427,7 @@ impl<T> IntoIter<T> { for _x in self { } let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; mem::forget(self); - Vec { ptr: Unique(allocation), cap: cap, len: 0 } + Vec { ptr: NonZero(allocation), cap: cap, len: 0 } } } |
