|
|
@@ -0,0 +1,227 @@ |
|
|
|
mod raw_vec; |
|
|
|
use std::mem; |
|
|
|
use std::alloc; |
|
|
|
use std::ptr; |
|
|
|
use std::ops::{Deref, DerefMut}; |
|
|
|
use raw_vec::RawVec; |
|
|
|
use std::marker::PhantomData; |
|
|
|
|
|
|
|
pub struct Vec<T> { |
|
|
|
buf: RawVec<T>, |
|
|
|
len: usize, |
|
|
|
} |
|
|
|
|
|
|
|
struct RawValIter<T> { |
|
|
|
start: *const T, |
|
|
|
end: *const T, |
|
|
|
} |
|
|
|
|
|
|
|
pub struct IntoIter<T> { |
|
|
|
_buf: RawVec<T>, // we don't actually care about this. Just need it to live. |
|
|
|
iter: RawValIter<T>, |
|
|
|
} |
|
|
|
|
|
|
|
pub struct Drain<'a, T: 'a> { |
|
|
|
vec: PhantomData<&'a mut Vec<T>>, |
|
|
|
iter: RawValIter<T>, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<T> Vec<T> { |
|
|
|
fn ptr(&self) -> *mut T { self.buf.ptr.as_ptr() } |
|
|
|
|
|
|
|
fn cap(&self) -> usize { self.buf.cap } |
|
|
|
|
|
|
|
pub fn new() -> Self { |
|
|
|
Vec { buf: RawVec::new(), len: 0 } |
|
|
|
} |
|
|
|
|
|
|
|
pub fn push(&mut self, elem: T) { |
|
|
|
if self.len == self.cap() { self.buf.grow(); } |
|
|
|
|
|
|
|
unsafe { |
|
|
|
ptr::write(self.ptr().offset(self.len as isize), elem); |
|
|
|
} |
|
|
|
|
|
|
|
self.len += 1; |
|
|
|
} |
|
|
|
|
|
|
|
pub fn pop(&mut self) -> Option<T> { |
|
|
|
if self.len == 0 { |
|
|
|
None |
|
|
|
} else { |
|
|
|
self.len -= 1; |
|
|
|
unsafe { |
|
|
|
Some(ptr::read(self.ptr().offset(self.len as isize))) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub fn insert(&mut self, index: usize, elem: T) { |
|
|
|
assert! (index <= self.len, "index out of bounds"); |
|
|
|
if self.cap() == self.len { self.buf.grow(); } |
|
|
|
|
|
|
|
unsafe { |
|
|
|
if index < self.len { |
|
|
|
ptr::copy(self.ptr().offset(index as isize), |
|
|
|
self.ptr().offset(index as isize), |
|
|
|
self.len - index); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub fn remove(&mut self, index: usize) -> T { |
|
|
|
assert!(index < self.len, "index out of bounds"); |
|
|
|
unsafe { |
|
|
|
self.len -= 1; |
|
|
|
let result = ptr::read(self.ptr().offset(index as isize)); |
|
|
|
ptr::copy(self.ptr().offset(index as isize + 1), |
|
|
|
self.ptr().offset(index as isize), self.len - index); |
|
|
|
result |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub fn into_iter(self) -> IntoIter<T> { |
|
|
|
unsafe { |
|
|
|
let iter = RawValIter::new(&self); |
|
|
|
|
|
|
|
let buf = ptr::read(&self.buf); |
|
|
|
mem::forget(self); |
|
|
|
|
|
|
|
IntoIter { |
|
|
|
iter: iter, |
|
|
|
_buf: buf, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub fn drain(&mut self) -> Drain<T> { |
|
|
|
unsafe { |
|
|
|
let iter = RawValIter::new(&self); |
|
|
|
|
|
|
|
// this is a mem::forget safety thing. If Drain is forgotten, we just |
|
|
|
// leak the whole Vec's contents. Also we need to do this *eventually* |
|
|
|
// anyway, so why not do it now? |
|
|
|
self.len = 0; |
|
|
|
|
|
|
|
Drain { |
|
|
|
iter: iter, |
|
|
|
vec: PhantomData, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Drop for Vec<T> { |
|
|
|
fn drop(&mut self) { |
|
|
|
while let Some(_) = self.pop() {} |
|
|
|
// deallocation handled by RawVec |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Deref for Vec<T> { |
|
|
|
type Target = [T]; |
|
|
|
fn deref(&self) -> &[T] { |
|
|
|
unsafe { |
|
|
|
::std::slice::from_raw_parts(self.ptr(), self.len) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> DerefMut for Vec<T> { |
|
|
|
fn deref_mut(&mut self) -> &mut [T] { |
|
|
|
unsafe { |
|
|
|
::std::slice::from_raw_parts_mut(self.ptr(), self.len) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
impl<T> RawValIter<T> { |
|
|
|
unsafe fn new(slice: &[T]) -> Self { |
|
|
|
RawValIter { |
|
|
|
start: slice.as_ptr(), |
|
|
|
end: if mem::size_of::<T>() == 0 { |
|
|
|
((slice.as_ptr() as usize) + slice.len()) as *const _ |
|
|
|
} else if slice.len() == 0 { |
|
|
|
slice.as_ptr() |
|
|
|
} else { |
|
|
|
slice.as_ptr().offset(slice.len() as isize) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Iterator for RawValIter<T> { |
|
|
|
type Item = T; |
|
|
|
fn next(&mut self) -> Option<T> { |
|
|
|
if self.start == self.end { |
|
|
|
None |
|
|
|
} else { |
|
|
|
unsafe { |
|
|
|
let result = ptr::read(self.start); |
|
|
|
self.start = if mem::size_of::<T>() == 0 { |
|
|
|
(self.start as usize + 1) as *const _ |
|
|
|
} else { |
|
|
|
self.start.offset(1) |
|
|
|
}; |
|
|
|
Some(result) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { |
|
|
|
let elem_size = mem::size_of::<T>(); |
|
|
|
let len = (self.end as usize - self.start as usize) |
|
|
|
/ if elem_size == 0 { 1 } else { elem_size }; |
|
|
|
(len, Some(len)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> DoubleEndedIterator for RawValIter<T> { |
|
|
|
fn next_back(&mut self) -> Option<T> { |
|
|
|
if self.start == self.end { |
|
|
|
None |
|
|
|
} else { |
|
|
|
unsafe { |
|
|
|
self.end = if mem::size_of::<T>() == 0 { |
|
|
|
(self.end as usize - 1) as *const _ |
|
|
|
} else { |
|
|
|
self.end.offset(-1) |
|
|
|
}; |
|
|
|
Some(ptr::read(self.end)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<T> Iterator for IntoIter<T> { |
|
|
|
type Item = T; |
|
|
|
fn next(&mut self) -> Option<T> { self.iter.next() } |
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> DoubleEndedIterator for IntoIter<T> { |
|
|
|
fn next_back(&mut self) -> Option<T> { self.iter.next_back() } |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Drop for IntoIter<T> { |
|
|
|
fn drop(&mut self){ |
|
|
|
for _ in &mut *self {} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<'a, T> Iterator for Drain<'a, T> { |
|
|
|
type Item = T; |
|
|
|
fn next(&mut self) -> Option<T> { self.iter.next() } |
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } |
|
|
|
} |
|
|
|
|
|
|
|
impl<'a, T> DoubleEndedIterator for Drain<'a, T> { |
|
|
|
fn next_back(&mut self) -> Option<T> { self.iter.next_back() } |
|
|
|
} |
|
|
|
|
|
|
|
impl<'a, T> Drop for Drain<'a, T> { |
|
|
|
fn drop(&mut self) { |
|
|
|
for _ in &mut self.iter {} |
|
|
|
} |
|
|
|
} |