use std::alloc::{alloc_zeroed, dealloc, Layout};
#[derive(Clone)]
pub struct PushBuffer<T>
{
buffer : * mut T,
pub index : isize,
len : isize
}
impl PushBuffer<f32>
{
pub fn new(len : usize) -> Self
{
let layout = Layout::array::<f32>(len);
match layout
{
Ok(layout) =>
{
let buffer = unsafe { alloc_zeroed(layout) as * mut f32 };
return PushBuffer { buffer, index : 0, len : len as isize };
}
Err(error) => { panic!("{}", error); }
}
}
}
impl PushBuffer<f64>
{
pub fn new(len : usize) -> Self
{
let layout = Layout::array::<f64>(len);
match layout
{
Ok(layout) =>
{
let buffer = unsafe { alloc_zeroed(layout) as * mut f64 };
return PushBuffer { buffer, index : 0, len : len as isize };
}
Err(error) => { panic!("{}", error); }
}
}
}
impl<T : Copy> PushBuffer<T>
{
pub fn push(& mut self, value : T)
{
if self.index <= self.len
{
unsafe { * self.buffer.offset(self.index) = value; }
self.index += 1;
}
else
{
unsafe
{
(1..self.len).for_each(|x| * self.buffer.offset(x - 1) = * self.buffer.offset(x));
* self.buffer.offset(self.index) = value;
}
}
}
pub fn len(& self) -> isize { return self.len; }
}
impl<T> std::ops::Index<usize> for PushBuffer<T>
{
type Output = T;
fn index(&self, index: usize) -> & Self::Output
{
let data = unsafe { self.buffer.offset(index as isize).as_ref() };
match data
{
None => { panic!("Access to invalid memory"); }
Some(reference) => { return reference; }
}
}
}
impl<T> std::ops::IndexMut<usize> for PushBuffer<T>
{
fn index_mut(&mut self, index: usize) -> & mut Self::Output
{
let data = unsafe { self.buffer.offset(index as isize).as_mut() };
match data
{
None => { panic!("Access to invalid memory"); }
Some(reference) => { return reference; }
}
}
}
impl<T> Drop for PushBuffer<T>
{
fn drop(&mut self)
{
let layout = Layout::array::<f64>(self.len as usize);
match layout
{
Ok(layout) => { unsafe { dealloc(self.buffer as * mut u8, layout); } }
Err(error) => { panic!("{}", error); }
}
}
}
#[derive(Clone)]
pub struct CircularBuffer<T>
{
buffer : * mut T,
read : isize,
write : isize,
len : isize
}
impl CircularBuffer<f32>
{
pub fn new(len : usize) -> Self
{
let layout = Layout::array::<f32>(len);
match layout
{
Ok(layout) =>
{
let buffer = unsafe { alloc_zeroed(layout) as * mut f32 };
return CircularBuffer { buffer, read : 0, write : 0, len : len as isize };
}
Err(error) => { panic!("{}", error); }
}
}
}
impl CircularBuffer<f64>
{
pub fn new(len : usize) -> Self
{
let layout = Layout::array::<f64>(len);
match layout
{
Ok(layout) =>
{
let buffer = unsafe { alloc_zeroed(layout) as * mut f64 };
return CircularBuffer { buffer, read : 0, write : 0, len : len as isize };
}
Err(error) => { panic!("{}", error); }
}
}
}
impl<T : Copy + PartialEq> CircularBuffer<T>
{
pub fn push(& mut self, value : T)
{
unsafe { * self.buffer.offset(self.write) = value; }
if self.write < self.len() { self.write += 1; } else { self.write = 0; }
}
pub fn next(& mut self) -> T
{
let value = unsafe { *self.buffer.offset(self.read) };
if self.write < self.len() { self.read += 1; } else { self.read = 0; }
return value;
}
pub fn init_write(& mut self, index : isize) { self.write = index; }
pub fn init_read(& mut self, index : isize) { self.write = index; }
pub fn len(& self) -> isize { return self.len; }
}
impl<T> Drop for CircularBuffer<T>
{
fn drop(&mut self)
{
let layout = Layout::array::<f64>(self.len as usize);
match layout
{
Ok(layout) => { unsafe { dealloc(self.buffer as * mut u8, layout); } }
Err(error) => { panic!("{}", error); }
}
}
}