use super::alloc::*;
use core::ops::{Index, IndexMut};
#[repr(C)]
pub struct TPArrayBlock<L, E> {
pub label: L,
len: usize,
elements: E,
}
impl<L, E> TPArrayBlock<L, E> {
pub fn new_ptr<'a>(label: L, len: usize) -> &'a mut Self {
let l_layout = size_align::<L>();
let d_layout = size_align_array::<E>(len);
let (size, align) = size_align_multiple(&[l_layout, size_align::<usize>(), d_layout]);
let new_ptr = unsafe { allocate::<Self>(size, align) };
new_ptr.label = label;
new_ptr
}
#[inline]
pub unsafe fn unchecked_access<'a>(&'a self, index: usize) -> &'a mut E {
let element = &self.elements as *const E as *mut E;
let element = element.offset(index as isize);
&mut *element
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
}
impl<L, E> Index<usize> for TPArrayBlock<L, E> {
type Output = E;
#[inline]
fn index(&self, index: usize) -> &E {
assert!(index < self.len());
unsafe { self.unchecked_access(index) }
}
}
impl<L, E> IndexMut<usize> for TPArrayBlock<L, E> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut E {
assert!(index < self.len());
unsafe { self.unchecked_access(index) }
}
}
impl<L, E> Clone for &mut TPArrayBlock<L, E>
where
L: Clone,
E: Clone,
{
#[inline]
fn clone(&self) -> Self {
let new_ptr = TPArrayBlock::new_ptr(self.label.clone(), self.len());
for i in 0..self.len() {
new_ptr[i] = self[i].clone();
}
new_ptr
}
}
#[repr(C)]
pub struct FPArrayBlock<L, E> {
pub label: L,
pub elements: [E],
}
impl<L, E> FPArrayBlock<L, E> {
pub fn new_ptr<'a>(label: L, len: usize) -> &'a mut Self {
let l_layout = size_align::<L>();
let d_layout = size_align_array::<E>(len);
let (size, align) = size_align_multiple(&[l_layout, d_layout]);
let new_ptr = unsafe {
let new_ptr = allocate::<E>(size, align);
let new_ptr = std::slice::from_raw_parts(new_ptr, len);
&mut *(new_ptr as *const [E] as *mut [E] as *mut Self)
};
new_ptr.label = label;
new_ptr
}
#[inline]
pub unsafe fn unchecked_access(&self, index: usize) -> &mut E {
let elements = &self.elements[index] as *const E as *mut E;
&mut *elements
}
#[inline]
pub fn len(&self) -> usize {
self.elements.len()
}
}
impl<L, E> Index<usize> for FPArrayBlock<L, E> {
type Output = E;
#[inline]
fn index(&self, index: usize) -> &E {
assert!(index < self.len());
unsafe { self.unchecked_access(index) }
}
}
impl<L, E> IndexMut<usize> for FPArrayBlock<L, E> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut E {
assert!(index < self.len());
unsafe { self.unchecked_access(index) }
}
}
impl<L, E> Clone for &mut FPArrayBlock<L, E>
where
L: Clone,
E: Clone,
{
#[inline]
fn clone(&self) -> Self {
let new_ptr = FPArrayBlock::new_ptr(self.label.clone(), self.len());
for i in 0..self.len() {
new_ptr[i] = self[i].clone();
}
new_ptr
}
}