use alloc::vec;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[allow(unused_imports)]
use std::compile_error;
use std::mem::{forget, size_of};
use std::ptr::NonNull;
use crate::imp_prelude::*;
use crate::{dimension, ArcArray1, ArcArray2};
#[macro_export]
macro_rules! array {
($([$([$([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
compile_error!("Arrays of 7 dimensions or more (or ndarrays of Rust arrays) cannot be constructed with the array! macro.");
}};
($([$([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
$crate::Array6::from(vec![$([$([$([$([$([$($x,)*],)*],)*],)*],)*],)*])
}};
($([$([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
$crate::Array5::from(vec![$([$([$([$([$($x,)*],)*],)*],)*],)*])
}};
($([$([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*]),+ $(,)*) => {{
$crate::Array4::from(vec![$([$([$([$($x,)*],)*],)*],)*])
}};
($([$([$($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 const fn aview0<A>(x: &A) -> ArrayView0<'_, A>
{
ArrayBase {
data: ViewRepr::new(),
ptr: unsafe { NonNull::new_unchecked(x as *const A as *mut A) },
dim: Ix0(),
strides: Ix0(),
}
}
pub const fn aview1<A>(xs: &[A]) -> ArrayView1<'_, A>
{
if size_of::<A>() == 0 {
assert!(
xs.len() <= isize::MAX as usize,
"Slice length must fit in `isize`.",
);
}
ArrayBase {
data: ViewRepr::new(),
ptr: unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) },
dim: Ix1(xs.len()),
strides: Ix1(1),
}
}
pub const fn aview2<A, const N: usize>(xs: &[[A; N]]) -> ArrayView2<'_, A>
{
let cols = N;
let rows = xs.len();
if size_of::<A>() == 0 {
if let Some(n_elems) = rows.checked_mul(cols) {
assert!(
rows <= isize::MAX as usize
&& cols <= isize::MAX as usize
&& n_elems <= isize::MAX as usize,
"Product of non-zero axis lengths must not overflow isize.",
);
} else {
panic!("Overflow in number of elements.");
}
} else if N == 0 {
assert!(
rows <= isize::MAX as usize,
"Product of non-zero axis lengths must not overflow isize.",
);
}
let ptr = unsafe { NonNull::new_unchecked(xs.as_ptr() as *mut A) };
let dim = Ix2(rows, cols);
let strides = if rows == 0 || cols == 0 {
Ix2(0, 0)
} else {
Ix2(cols, 1)
};
ArrayBase {
data: ViewRepr::new(),
ptr,
dim,
strides,
}
}
pub fn aview_mut1<A>(xs: &mut [A]) -> ArrayViewMut1<'_, A>
{
ArrayViewMut::from(xs)
}
pub fn aview_mut2<A, const N: usize>(xs: &mut [[A; N]]) -> ArrayViewMut2<'_, A>
{
ArrayViewMut2::from(xs)
}
pub fn arr2<A: Clone, const N: usize>(xs: &[[A; N]]) -> Array2<A>
{
Array2::from(xs.to_vec())
}
macro_rules! impl_from_nested_vec {
($arr_type:ty, $ix_type:tt, $($n:ident),+) => {
impl<A, $(const $n: usize),+> From<Vec<$arr_type>> for Array<A, $ix_type>
{
fn from(mut xs: Vec<$arr_type>) -> Self
{
let dim = $ix_type(xs.len(), $($n),+);
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 $($n == 0 ||)+ false {
Vec::new()
} else {
let expand_cap = cap $(* $n)+;
Vec::from_raw_parts(ptr as *mut A, expand_len, expand_cap)
};
ArrayBase::from_shape_vec_unchecked(dim, v)
}
}
}
};
}
impl_from_nested_vec!([A; N], Ix2, N);
impl_from_nested_vec!([[A; M]; N], Ix3, N, M);
impl_from_nested_vec!([[[A; L]; M]; N], Ix4, N, M, L);
impl_from_nested_vec!([[[[A; K]; L]; M]; N], Ix5, N, M, L, K);
impl_from_nested_vec!([[[[[A; J]; K]; L]; M]; N], Ix6, N, M, L, K, J);
pub fn rcarr2<A: Clone, const N: usize>(xs: &[[A; N]]) -> ArcArray2<A>
{
arr2(xs).into_shared()
}
pub fn arr3<A: Clone, const N: usize, const M: usize>(xs: &[[[A; M]; N]]) -> Array3<A>
{
Array3::from(xs.to_vec())
}
pub fn rcarr3<A: Clone, const N: usize, const M: usize>(xs: &[[[A; M]; N]]) -> ArcArray<A, Ix3>
{
arr3(xs).into_shared()
}