bullet 0.1.2

Supersonic Math
use std::ptr::Unique;
use std::ops::{Deref, DerefMut};
use super::*;

pub struct Buffer<T: Copy> {
    ptr: Unique<T>,
    len: usize,
    cap: usize
}
impl<T: Copy> Buffer<T> {
    #[inline]
    pub fn with_capacity(count: usize) -> Result<Buffer<T>, CudaError> {
        let mut ptr = ptr::null_mut();
        unsafe {
            cuMemHostAlloc(&mut ptr as *mut _ as *mut *mut c_void, count * mem::size_of::<T>(), CU_MEMHOSTALLOC_DEVICEMAP)?;
        }
        Ok(Buffer {
            ptr: Unique::new(ptr).unwrap(),
            len: 0,
            cap: count
        })
    }
    #[inline]
    pub fn push(&mut self, t: T) {
        assert!(self.len < self.cap);
        unsafe {
            ptr::write(self.ptr.as_ptr().offset(self.len as isize), t);
        }
        self.len += 1;
    }
    #[inline]
    pub fn dev_ptr(&self) -> Result<u64, CudaError> {
        let mut d_ptr = 0u64;
        unsafe {
            cuMemHostGetDevicePointer_v2(&mut d_ptr, self.ptr.as_ptr() as *mut c_void, 0)?;
        }
        Ok(d_ptr)
    }
    #[inline]
    pub fn len(&self) -> usize {
        self.len
    }
    #[inline]
    pub unsafe fn set_len(&mut self, len: usize) {
        assert!(len <= self.cap);
        self.len = len;
    }
}
impl<T: Copy> Deref for Buffer<T> {
    type Target = [T];
    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self.ptr.as_ptr(), self.len)
        }
    }
}
impl<T: Copy> DerefMut for Buffer<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len)
        }
    }
}
impl<T: Copy> Drop for Buffer<T> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            cuMemFreeHost(self.ptr.as_ptr() as *mut c_void);
        }
    }
}