use std::alloc::{Layout, LayoutError};
use super::ArrayError;
use super::{Iter, IterMut, IntoIter};
pub struct Array<T> {
pub(in super) pointer : *mut T,
size : usize
}
impl<T> Array<T> {
#[inline]
pub fn new(size: usize) -> Result<Array<T>, ArrayError> {
unsafe {
let layout = std::alloc::Layout::array::<T>(size)?;
let ptr = std::alloc::alloc(layout) as *mut T;
if ptr.is_null() {
Err(ArrayError("allocation returned null pointer".to_string()))
} else {
Ok(Self { pointer: ptr, size })
}
}
}
#[inline]
pub unsafe fn from_pointer(ptr: *mut T, size: usize) -> Self {
Self { pointer : ptr, size }
}
#[inline]
pub fn size(&self) -> usize {
self.size
}
#[inline]
pub unsafe fn get_ptr(&self, index: usize) -> *const T {
self.pointer.add(index)
}
#[inline]
pub unsafe fn get_mut_ptr(&self, index: usize) -> *mut T {
self.pointer.add(index)
}
#[inline]
pub fn try_get(&self, index: usize) -> Option<&T> {
if self.size <= index {
None
} else {
unsafe { Some(self.get(index)) }
}
}
#[inline]
pub unsafe fn get(&self, index: usize) -> &T {
&(*(self.pointer.add(index)))
}
#[inline]
pub fn try_get_mut(&mut self, index: usize) -> Option<&mut T> {
if self.size <= index {
None
} else {
unsafe { Some(self.get_mut(index)) }
}
}
#[inline]
pub unsafe fn get_mut(&mut self, index: usize) -> &mut T {
&mut (*(self.pointer.add(index)))
}
#[inline]
pub fn try_set(&mut self, index: usize, value: T) -> Option<()> {
if self.size <= index {
None
} else {
unsafe { Some(self.set(index, value)) }
}
}
#[inline]
pub unsafe fn set(&mut self, index: usize, value: T) {
*(self.pointer.add(index)) = value
}
#[inline]
pub fn iter(&self) -> Iter<T> {
Iter::new(self)
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut::new(self)
}
#[inline]
pub fn into_vec(self) -> Vec<T> {
unsafe{
Vec::from_raw_parts(self.pointer, self.size, self.size)
}
}
#[inline]
pub fn as_ptr(&self) -> *const T {
self.pointer.as_const()
}
#[inline]
pub fn as_mut_ptr(&self) -> *mut T {
self.pointer
}
}
impl<'a, T> IntoIterator for &'a Array<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Array<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T> IntoIterator for Array<T> {
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
impl<T> std::ops::Index<usize> for Array<T> {
type Output = T;
#[inline]
#[rustc_on_unimplemented(
message = "array indices are of type `usize` or `Index`",
label = "array indices are of type `usize` or `Index`"
)]
fn index(&self, index: usize) -> &Self::Output {
self.try_get(index).expect("index out of bounds")
}
}
impl<T> std::ops::IndexMut<usize> for Array<T> {
#[inline]
#[rustc_on_unimplemented(
message = "array indices are of type `usize` or `Index`",
label = "array indices are of type `usize` or `Index`"
)]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.try_get_mut(index).expect("index out of bounds")
}
}
impl<T> Drop for Array<T> {
fn drop(&mut self) {
unsafe { self.pointer.drop_in_place() };
}
}
impl<T> From<Vec<T>> for Array<T> {
fn from(vec: Vec<T>) -> Self {
let size = vec.len();
let mut array = Array::new(size)
.expect("failed to create new Array");
let mut i = 0_usize;
unsafe {
for item in vec {
*array.get_mut(i) = item;
i += 1
}
}
array
}
}
impl<T: Clone> Clone for Array<T> {
fn clone(&self) -> Self {
let arr = Array::new(self.size)
.expect("failed to crate new Array");
unsafe {
for i in 0..self.size {
*arr.get_mut_ptr(i) = std::ptr::read(self.get_ptr(i));
}
}
arr
}
}
impl<T> std::ops::Deref for Array<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { std::slice::from_raw_parts(self.pointer, self.size) }
}
}
impl<T> std::ops::DerefMut for Array<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { std::slice::from_raw_parts_mut(self.pointer, self.size) }
}
}
impl<T> Array<T> {
pub fn take_from_iter<I: Iterator>(iterator: &mut I, n: usize) -> Self
where
I : Iterator,
T : From<I::Item>
{
let mut arr = Array::new(n)
.expect("failed to create new Array");
unsafe {
for i in 0..n {
match iterator.next() {
None => break,
Some(val) => *arr.get_mut_ptr(i) = val.into()
}
}
}
arr
}
}