libcollections: Use NonZero in Vec.
This commit is contained in:
parent
ef5da14edb
commit
bb44737748
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user