diff options
| author | Luqman Aden <laden@csclub.uwaterloo.ca> | 2014-12-04 14:58:21 -0500 |
|---|---|---|
| committer | Luqman Aden <laden@csclub.uwaterloo.ca> | 2014-12-28 19:40:48 -0500 |
| commit | 466135bfef4d110213a9aeb46f8199fa89a5f267 (patch) | |
| tree | 381e70fefb4baaa32da847cd2d236dcc0c0e171a /src/libcollections | |
| parent | 4af50548b9ed283acb62768624a8cd942eabe964 (diff) | |
| download | rust-466135bfef4d110213a9aeb46f8199fa89a5f267.tar.gz rust-466135bfef4d110213a9aeb46f8199fa89a5f267.zip | |
libcore: Make it unsafe to create NonZero and impl Deref.
Diffstat (limited to 'src/libcollections')
| -rw-r--r-- | src/libcollections/vec.rs | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 0739cef3353..6f618657280 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -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: NonZero(EMPTY as *mut T), len: 0, cap: 0 } + Vec { ptr: unsafe { NonZero::new(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: NonZero(EMPTY as *mut T), len: 0, cap: uint::MAX } + Vec { ptr: unsafe { NonZero::new(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: NonZero(ptr as *mut T), len: 0, cap: capacity } + Vec { ptr: unsafe { NonZero::new(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: NonZero(ptr), len: length, cap: capacity } + Vec { ptr: NonZero::new(ptr), len: length, cap: capacity } } /// Creates a vector by copying the elements from a raw pointer. @@ -792,11 +792,10 @@ 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(ptr, self.cap) + dealloc(*self.ptr, self.cap) } self.cap = 0; } @@ -804,12 +803,12 @@ impl<T> Vec<T> { unsafe { // Overflow check is unnecessary as the vector is already at // least this large. - let ptr = reallocate(ptr as *mut u8, + let ptr = reallocate(*self.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.ptr = NonZero::new(ptr); } self.cap = self.len; } @@ -867,10 +866,9 @@ 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: ptr as *const T, + data: *self.ptr as *const T, len: self.len, }) } @@ -893,7 +891,7 @@ impl<T> Vec<T> { #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> IntoIter<T> { unsafe { - let NonZero(ptr) = self.ptr; + let ptr = *self.ptr; let cap = self.cap; let begin = ptr as *const T; let end = if mem::size_of::<T>() == 0 { @@ -1113,16 +1111,15 @@ impl<T> Vec<T> { let size = max(old_size, 2 * mem::size_of::<T>()) * 2; if old_size > size { panic!("capacity overflow") } unsafe { - let NonZero(ptr) = self.ptr; - let ptr = alloc_or_realloc(ptr, old_size, size); + let ptr = alloc_or_realloc(*self.ptr, old_size, size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero(ptr); + self.ptr = NonZero::new(ptr); } self.cap = max(self.cap, 2) * 2; } unsafe { - let NonZero(end) = self.ptr.offset(self.len as int); + let end = *self.ptr.offset(self.len as int); ptr::write(&mut *end, value); self.len += 1; } @@ -1167,11 +1164,11 @@ impl<T> Vec<T> { #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn drain<'a>(&'a mut self) -> Drain<'a, T> { unsafe { - let begin = self.ptr.0 as *const T; + let begin = *self.ptr as *const T; let end = if mem::size_of::<T>() == 0 { - (self.ptr.0 as uint + self.len()) as *const T + (*self.ptr as uint + self.len()) as *const T } else { - self.ptr.0.offset(self.len() as int) as *const T + (*self.ptr).offset(self.len() as int) as *const T }; self.set_len(0); Drain { @@ -1236,10 +1233,9 @@ impl<T> Vec<T> { let size = capacity.checked_mul(mem::size_of::<T>()) .expect("capacity overflow"); unsafe { - let NonZero(ptr) = self.ptr; - let ptr = alloc_or_realloc(ptr, self.cap * mem::size_of::<T>(), size); + let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::<T>(), size); if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero(ptr); + self.ptr = NonZero::new(ptr); } self.cap = capacity; } @@ -1360,10 +1356,9 @@ 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: ptr as *const T, + data: *self.ptr as *const T, len: self.len }) } @@ -1388,8 +1383,7 @@ impl<T> Drop for Vec<T> { for x in self.iter() { ptr::read(x); } - let NonZero(ptr) = self.ptr; - dealloc(ptr, self.cap) + dealloc(*self.ptr, self.cap) } } } @@ -1427,7 +1421,7 @@ impl<T> IntoIter<T> { for _x in self { } let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; mem::forget(self); - Vec { ptr: NonZero(allocation), cap: cap, len: 0 } + Vec { ptr: NonZero::new(allocation), cap: cap, len: 0 } } } |
