use std::mem::{forget, size_of};
use alloc::slice;
use alloc::vec;
use alloc::vec::Vec;
use crate::imp_prelude::*;
use crate::{dimension, ArcArray1, ArcArray2};
#[macro_export]
macro_rules! array {
($([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*) => {{
$crate::Array3::from(vec![$([$([$($x,)*],)*],)*])
}};
($([$($x:expr),* $(,)*]),+ $(,)*) => {{
$crate::Array2::from(vec![$([$($x,)*],)*])
}};
($($x:expr),* $(,)*) => {{
$crate::Array::from(vec![$($x,)*])
}};
}
pub fn arr0<A>(x: A) -> Array0<A> {
unsafe { ArrayBase::from_shape_vec_unchecked((), vec![x]) }
}
pub fn arr1<A: Clone>(xs: &[A]) -> Array1<A> {
ArrayBase::from(xs.to_vec())
}
pub fn rcarr1<A: Clone>(xs: &[A]) -> ArcArray1<A> {
arr1(xs).into_shared()
}
pub fn aview0<A>(x: &A) -> ArrayView0<'_, A> {
unsafe { ArrayView::from_shape_ptr(Ix0(), x) }
}
pub fn aview1<A>(xs: &[A]) -> ArrayView1<'_, A> {
ArrayView::from(xs)
}
pub fn aview2<A, V: FixedInitializer<Elem = A>>(xs: &[V]) -> ArrayView2<'_, A> {
let cols = V::len();
let rows = xs.len();
let dim = Ix2(rows, cols);
if size_of::<V>() == 0 {
dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
}
unsafe {
let data = slice::from_raw_parts(xs.as_ptr() as *const A, cols * rows);
ArrayView::from_shape_ptr(dim, data.as_ptr())
}
}
pub fn aview_mut1<A>(xs: &mut [A]) -> ArrayViewMut1<'_, A> {
ArrayViewMut::from(xs)
}
pub fn aview_mut2<A, V: FixedInitializer<Elem = A>>(xs: &mut [V]) -> ArrayViewMut2<'_, A> {
let cols = V::len();
let rows = xs.len();
let dim = Ix2(rows, cols);
if size_of::<V>() == 0 {
dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
}
unsafe {
let data = slice::from_raw_parts_mut(xs.as_mut_ptr() as *mut A, cols * rows);
ArrayViewMut::from_shape_ptr(dim, data.as_mut_ptr())
}
}
#[allow(clippy::missing_safety_doc)] pub unsafe trait FixedInitializer {
type Elem;
fn as_init_slice(&self) -> &[Self::Elem];
fn len() -> usize;
}
macro_rules! impl_arr_init {
(__impl $n: expr) => (
unsafe impl<T> FixedInitializer for [T; $n] {
type Elem = T;
fn as_init_slice(&self) -> &[T] { self }
fn len() -> usize { $n }
}
);
() => ();
($n: expr, $($m:expr,)*) => (
impl_arr_init!(__impl $n);
impl_arr_init!($($m,)*);
)
}
impl_arr_init!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,);
pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> Array2<A>
where
V: Clone,
{
Array2::from(xs.to_vec())
}
impl<A, V> From<Vec<V>> for Array2<A>
where
V: FixedInitializer<Elem = A>,
{
fn from(mut xs: Vec<V>) -> Self {
let dim = Ix2(xs.len(), V::len());
let ptr = xs.as_mut_ptr();
let cap = xs.capacity();
let expand_len = dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
forget(xs);
unsafe {
let v = if size_of::<A>() == 0 {
Vec::from_raw_parts(ptr as *mut A, expand_len, expand_len)
} else if V::len() == 0 {
Vec::new()
} else {
let expand_cap = cap * V::len();
Vec::from_raw_parts(ptr as *mut A, expand_len, expand_cap)
};
ArrayBase::from_shape_vec_unchecked(dim, v)
}
}
}
impl<A, V, U> From<Vec<V>> for Array3<A>
where
V: FixedInitializer<Elem = U>,
U: FixedInitializer<Elem = A>,
{
fn from(mut xs: Vec<V>) -> Self {
let dim = Ix3(xs.len(), V::len(), U::len());
let ptr = xs.as_mut_ptr();
let cap = xs.capacity();
let expand_len = dimension::size_of_shape_checked(&dim)
.expect("Product of non-zero axis lengths must not overflow isize.");
forget(xs);
unsafe {
let v = if size_of::<A>() == 0 {
Vec::from_raw_parts(ptr as *mut A, expand_len, expand_len)
} else if V::len() == 0 || U::len() == 0 {
Vec::new()
} else {
let expand_cap = cap * V::len() * U::len();
Vec::from_raw_parts(ptr as *mut A, expand_len, expand_cap)
};
ArrayBase::from_shape_vec_unchecked(dim, v)
}
}
}
pub fn rcarr2<A: Clone, V: Clone + FixedInitializer<Elem = A>>(xs: &[V]) -> ArcArray2<A> {
arr2(xs).into_shared()
}
pub fn arr3<A: Clone, V: FixedInitializer<Elem = U>, U: FixedInitializer<Elem = A>>(
xs: &[V],
) -> Array3<A>
where
V: Clone,
U: Clone,
{
Array3::from(xs.to_vec())
}
pub fn rcarr3<A: Clone, V: FixedInitializer<Elem = U>, U: FixedInitializer<Elem = A>>(
xs: &[V],
) -> ArcArray<A, Ix3>
where
V: Clone,
U: Clone,
{
arr3(xs).into_shared()
}