#[no_std];
#[no_core];

use zero;

pub trait OwnedVector<T> {
    unsafe fn push_fast(&mut self, t: T);
    unsafe fn len(&self) -> uint;
    unsafe fn set_len(&mut self, newlen: uint);
    unsafe fn as_mut_buf<U>(&self, f: &fn(*mut T, uint) -> U) -> U;
    unsafe fn data(&self) -> *u8;
}

pub struct Vec<T> {
    fill: uint,
    alloc: uint,
    data: T
}


impl<T> OwnedVector<T> for ~[T] {
    //FIXME: Does not check to see if we have space
    // See: https://github.com/mozilla/rust/blob/master/src/libstd/vec.rs#L1317
    unsafe fn push_fast(&mut self, t: T) {
        let repr: **mut Vec<u8> = zero::transmute(self);
        let fill = (**repr).fill;
        (**repr).fill += zero::size_of::<T>();
        let p = &(**repr).data  as *u8 as uint;
        let mut i = 0;
        while i < zero::size_of::<T>() {
            *((p+fill+i) as *mut u8) = *((&t as *T as uint + i) as *mut u8);
            i += 1;
        }
    }

    unsafe fn len(&self) -> uint {
        let repr: **Vec<u8> = zero::transmute(self);
        ((**repr).fill / zero::size_of::<T>()) as uint
    }

    unsafe fn set_len(&mut self, newlen: uint) {
        let repr: **mut Vec<u8> = zero::transmute(self);
        (**repr).fill = zero::size_of::<T>() * newlen;
    }

    unsafe fn as_mut_buf<U>(&self, f: &fn(*mut T, uint) -> U) -> U {
        let repr: **mut Vec<T> = zero::transmute(self);
        f(&mut (**repr).data as *mut T, (**repr).fill / zero::size_of::<T>())
    }

    unsafe fn data(&self) -> *u8 {
        let repr: **mut Vec<u8> = zero::transmute(self);
        &(**repr).data as *u8
    }
}