use core::*;
use core::ops::*;
use core::slice::*;
use crate::*;
#[repr(C)]
pub struct Vec<T> {
elements : *mut T,
count : usize,
capacity : usize,
}
impl<T> Vec<T> {
pub fn with_capacity(c: usize) -> Self {
if c == 0 { Self::new() }
else {
Self {
elements: unsafe { alloc_array(c) },
count : 0,
capacity: c,
}
}
}
pub fn new() -> Self {
Self {
elements: ptr::null_mut(),
count : 0,
capacity: 0,
}
}
#[inline]
pub fn as_slice(&self) -> &[T] { unsafe { core::slice::from_raw_parts(self.elements, self.count) } }
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] { unsafe { core::slice::from_raw_parts_mut(self.elements, self.count) } }
pub fn len(&self) -> usize { self.count }
pub fn push(&mut self, t: T) {
if self.count >= self.capacity {
let new_size = if self.capacity == 0 { 16 } else { self.capacity * 2 };
let new_ptr = unsafe { alloc_array::<T>(new_size) };
let old_ptr = self.elements;
for i in 0..self.count {
let v = unsafe { old_ptr.offset(i as isize).read() }; unsafe { new_ptr.offset(i as isize).write(v) }; }
unsafe { free_array_ptr(self.elements, self.capacity) };
self.elements = new_ptr;
self.capacity = new_size;
}
unsafe { self.elements.offset(self.count as isize).write(t) };
self.count += 1
}
pub fn pop(&mut self) -> Option<T> {
if self.count == 0 { None }
else {
let nc = self.count - 1;
let v = unsafe { ptr::read(self.get_unchecked(nc) as *const _) };
self.count -= 1;
Some(v)
}
}
#[inline]
pub fn get_unchecked(&self, idx: usize) -> &T {
let arr = unsafe { core::slice::from_raw_parts(self.elements, self.count) };
&arr[idx]
}
#[inline]
pub fn get_unchecked_mut(&mut self, idx: usize) -> &mut T {
let arr = unsafe { core::slice::from_raw_parts_mut(self.elements, self.count) };
&mut arr[idx]
}
fn drop_elements(&mut self) {
let arr = unsafe { core::slice::from_raw_parts_mut(self.elements, self.count) };
for i in 0..self.count {
unsafe { ptr::drop_in_place(&arr[i] as *const T as *mut T) };
}
}
pub fn to_iter<'a>(&self) -> ::core::slice::Iter<'a, T> {
let arr = unsafe { core::slice::from_raw_parts(self.elements, self.count) };
arr.into_iter()
}
pub fn last(&self) -> Option<&T> {
if self.count == 0 {
None
} else {
Some(&self[self.count - 1])
}
}
pub fn capacity(&self) -> usize { self.capacity }
pub fn iter(&self) -> slice::Iter<T> {
self.as_slice().into_iter()
}
pub fn iter_mut(&mut self) -> slice::IterMut<T> {
self.as_mut_slice().into_iter()
}
pub fn from_raw_parts(ptr: *mut T, len: usize, cap: usize) -> Self {
Self { elements: ptr, count: len, capacity: cap }
}
}
impl<'a, T> IntoIterator for &'a Vec<T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> slice::Iter<'a, T> {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Vec<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> slice::IterMut<'a, T> {
self.iter_mut()
}
}
impl<A> iter::FromIterator<A> for Vec<A> {
fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
let mut v = Vec::new();
let mut it = iter.into_iter();
loop {
match it.next() {
Some(r) => v.push(r),
None => break,
}
}
v
}
}
pub trait VecAppend<E: Copy> {
fn append(&mut self, arr: &[E]);
}
impl<T : Copy> VecAppend<T> for Vec<T> {
fn append(&mut self, arr: &[T]) {
for e in arr {
self.push(e.clone());
}
}
}
impl<T, I: SliceIndex<[T]>> Index<I> for Vec<T> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(self.as_slice(), index)
}
}
impl<T, I: SliceIndex<[T]>> IndexMut<I> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(self.as_mut_slice(), index)
}
}
impl<T> Drop for Vec<T> {
fn drop(&mut self) {
self.drop_elements();
unsafe { free_array_ptr(self.elements, self.capacity) }
}
}
impl<T : Clone> Clone for Vec<T> {
fn clone(&self) -> Self {
let mut c = Vec::<T>::new();
for i in 0..self.count {
let v = self.get_unchecked(i);
c.push(v.clone());
}
c
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_destructor() {
let mut v = Vec::<Vec<i32>>::new();
for i in 0..100 {
let mut vj = Vec::<i32>::new();
for j in 0..100 {
vj.push(j * i);
}
v.push(vj);
}
}
#[test]
fn test_iter() {
let mut v = Vec::new();
for i in 0..4 {
v.push(i);
assert!(v[i] == i);
}
let mut counter = 0;
for i in v.to_iter() {
if *i != counter { panic!("invalid {} != {}", i, counter) }
counter += 1;
}
}
#[test]
fn test_pop_destructor() {
let mut v = Vec::<Vec<i32>>::new();
for i in 0..100 {
let mut vj = Vec::<i32>::new();
for j in 0..100 {
vj.push(j * i);
}
v.push(vj);
}
assert!(v.len() == 100);
for _ in 0..100 {
v.pop();
}
assert!(v.len() == 0);
}
#[test]
fn test_pop_destructor_push() {
let mut v = Vec::<Vec<i32>>::new();
for i in 0..100 {
let mut vj = Vec::<i32>::new();
for j in 0..100 {
vj.push(j * i);
}
v.push(vj);
}
for _ in 0..100 {
v.pop();
}
assert!(v.len() == 0);
for i in 0..100 {
let mut vj = Vec::<i32>::new();
for j in 0..100 {
vj.push(j * i);
}
v.push(vj);
}
assert!(v.len() == 100);
}
}