use core::marker::{PhantomData, Unsize};
use core::{fmt, ops, ptr, slice};
use untagged_option::UntaggedOption;
use BufferFullError;
pub struct Vec<T, A>
where
A: Unsize<[T]>,
{
_marker: PhantomData<[T]>,
buffer: UntaggedOption<A>,
len: usize,
}
impl<T, A> Vec<T, A>
where
A: Unsize<[T]>,
{
pub const fn new() -> Self {
Vec {
_marker: PhantomData,
buffer: UntaggedOption::none(),
len: 0,
}
}
pub fn capacity(&self) -> usize {
let buffer: &[T] = unsafe { self.buffer.as_ref() };
buffer.len()
}
pub fn clear(&mut self) {
self.truncate(0);
}
pub fn pop(&mut self) -> Option<T> {
let buffer: &[T] = unsafe { self.buffer.as_ref() };
if self.len != 0 {
self.len -= 1;
let item = unsafe { ptr::read(&buffer[self.len]) };
Some(item)
} else {
None
}
}
pub fn push(&mut self, item: T) -> Result<(), BufferFullError> {
let capacity = self.capacity();
let buffer: &mut [T] = unsafe { self.buffer.as_mut() };
if self.len < capacity {
unsafe { ptr::write(&mut buffer[self.len], item) }
self.len += 1;
Ok(())
} else {
Err(BufferFullError)
}
}
pub fn truncate(&mut self, len: usize) {
unsafe {
while len < self.len {
self.len -= 1;
let len = self.len;
ptr::drop_in_place(self.get_unchecked_mut(len));
}
}
}
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), BufferFullError>
where
T: Clone,
{
if new_len > self.capacity() {
return Err(BufferFullError);
}
if new_len > self.len {
while self.len < new_len {
self.push(value.clone())?;
}
} else {
self.truncate(new_len);
}
Ok(())
}
pub fn resize_default(&mut self, new_len: usize) -> Result<(), BufferFullError>
where
T: Clone + Default,
{
self.resize(new_len, T::default())
}
}
impl<T, A> fmt::Debug for Vec<T, A>
where
A: Unsize<[T]>,
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let slice: &[T] = &**self;
slice.fmt(f)
}
}
impl<T, A> Drop for Vec<T, A>
where
A: Unsize<[T]>,
{
fn drop(&mut self) {
unsafe { ptr::drop_in_place(&mut self[..]) }
}
}
impl<'a, T, A> IntoIterator for &'a Vec<T, A>
where
A: Unsize<[T]>,
{
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, A> IntoIterator for &'a mut Vec<T, A>
where
A: Unsize<[T]>,
{
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T, A, B> PartialEq<Vec<T, B>> for Vec<T, A>
where
A: Unsize<[T]>,
B: Unsize<[T]>,
T: PartialEq,
{
fn eq(&self, rhs: &Vec<T, B>) -> bool {
PartialEq::eq(&**self, &**rhs)
}
}
impl<T, A> Eq for Vec<T, A>
where
A: Unsize<[T]>,
T: Eq,
{
}
impl<T, A> ops::Deref for Vec<T, A>
where
A: Unsize<[T]>,
{
type Target = [T];
fn deref(&self) -> &[T] {
let buffer: &[T] = unsafe { self.buffer.as_ref() };
&buffer[..self.len]
}
}
impl<T, A> ops::DerefMut for Vec<T, A>
where
A: Unsize<[T]>,
{
fn deref_mut(&mut self) -> &mut [T] {
let len = self.len();
let buffer: &mut [T] = unsafe { self.buffer.as_mut() };
&mut buffer[..len]
}
}
#[cfg(test)]
mod tests {
use Vec;
#[test]
fn drop() {
struct Droppable;
impl Droppable {
fn new() -> Self {
unsafe {
COUNT += 1;
}
Droppable
}
}
impl Drop for Droppable {
fn drop(&mut self) {
unsafe {
COUNT -= 1;
}
}
}
static mut COUNT: i32 = 0;
{
let mut v: Vec<Droppable, [Droppable; 2]> = Vec::new();
v.push(Droppable::new()).unwrap();
v.push(Droppable::new()).unwrap();
v.pop().unwrap();
}
assert_eq!(unsafe { COUNT }, 0);
{
let mut v: Vec<Droppable, [Droppable; 2]> = Vec::new();
v.push(Droppable::new()).unwrap();
v.push(Droppable::new()).unwrap();
}
assert_eq!(unsafe { COUNT }, 0);
}
#[test]
fn eq() {
let mut xs: Vec<i32, [i32; 4]> = Vec::new();
let mut ys: Vec<i32, [i32; 8]> = Vec::new();
assert_eq!(xs, ys);
xs.push(1).unwrap();
ys.push(1).unwrap();
assert_eq!(xs, ys);
}
#[test]
fn full() {
let mut v: Vec<i32, [i32; 4]> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
assert!(v.push(4).is_err());
}
#[test]
fn iter() {
let mut v: Vec<i32, [i32; 4]> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
let mut items = v.iter();
assert_eq!(items.next(), Some(&0));
assert_eq!(items.next(), Some(&1));
assert_eq!(items.next(), Some(&2));
assert_eq!(items.next(), Some(&3));
assert_eq!(items.next(), None);
}
#[test]
fn iter_mut() {
let mut v: Vec<i32, [i32; 4]> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
let mut items = v.iter_mut();
assert_eq!(items.next(), Some(&mut 0));
assert_eq!(items.next(), Some(&mut 1));
assert_eq!(items.next(), Some(&mut 2));
assert_eq!(items.next(), Some(&mut 3));
assert_eq!(items.next(), None);
}
#[test]
fn push_and_pop() {
let mut v: Vec<i32, [i32; 4]> = Vec::new();
assert_eq!(v.len(), 0);
assert_eq!(v.pop(), None);
assert_eq!(v.len(), 0);
v.push(0).unwrap();
assert_eq!(v.len(), 1);
assert_eq!(v.pop(), Some(0));
assert_eq!(v.len(), 0);
assert_eq!(v.pop(), None);
assert_eq!(v.len(), 0);
}
#[test]
fn resize_size_limit() {
let mut v: Vec<u8, [u8; 4]> = Vec::new();
v.resize(0, 0).unwrap();
v.resize(4, 0).unwrap();
v.resize(5, 0).err().expect("BufferFullError");
}
#[test]
fn resize_length_cases() {
let mut v: Vec<u8, [u8; 4]> = Vec::new();
assert_eq!(v.len(), 0);
v.resize(1, 0).unwrap();
assert_eq!(v.len(), 1);
v.resize(3, 0).unwrap();
assert_eq!(v.len(), 3);
v.resize(3, 0).unwrap();
assert_eq!(v.len(), 3);
v.resize(2, 0).unwrap();
assert_eq!(v.len(), 2);
v.resize(0, 0).unwrap();
assert_eq!(v.len(), 0);
}
#[test]
fn resize_contents() {
let mut v: Vec<u8, [u8; 4]> = Vec::new();
v.resize(1, 17).unwrap();
assert_eq!(v[0], 17);
v.resize(2, 18).unwrap();
assert_eq!(v[0], 17);
assert_eq!(v[1], 18);
v.resize(2, 0).unwrap();
assert_eq!(v[0], 17);
assert_eq!(v[1], 18);
v.resize(1, 0).unwrap();
assert_eq!(v[0], 17);
}
#[test]
fn resize_default() {
let mut v: Vec<u8, [u8; 4]> = Vec::new();
v.resize_default(1).unwrap();
assert_eq!(v[0], 0);
}
}