#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use std::hash;
use std::mem;
use std::mem::size_of;
use std::ops::{Index, IndexMut};
use std::{iter::FromIterator, slice};
use crate::imp_prelude::*;
use crate::Arc;
use crate::{
dimension,
iter::{Iter, IterMut},
numeric_util,
FoldWhile,
NdIndex,
OwnedArcRepr,
Zip,
};
#[cold]
#[inline(never)]
pub(crate) fn array_out_of_bounds() -> !
{
panic!("ndarray: index out of bounds");
}
#[inline(always)]
pub fn debug_bounds_check<A, D, I, T>(_a: &T, _index: &I)
where
D: Dimension,
I: NdIndex<D>,
T: AsRef<LayoutRef<A, D>> + ?Sized,
{
let _layout_ref = _a.as_ref();
debug_bounds_check_ref!(_layout_ref, *_index);
}
impl<A, D, I> Index<I> for ArrayRef<A, D>
where
D: Dimension,
I: NdIndex<D>,
{
type Output = A;
#[inline]
fn index(&self, index: I) -> &Self::Output
{
debug_bounds_check_ref!(self, index);
unsafe {
&*self._ptr().as_ptr().offset(
index
.index_checked(self._dim(), self._strides())
.unwrap_or_else(|| array_out_of_bounds()),
)
}
}
}
impl<A, D, I> IndexMut<I> for ArrayRef<A, D>
where
D: Dimension,
I: NdIndex<D>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut A
{
debug_bounds_check_ref!(self, index);
unsafe {
&mut *self.as_mut_ptr().offset(
index
.index_checked(self._dim(), self._strides())
.unwrap_or_else(|| array_out_of_bounds()),
)
}
}
}
impl<S, D, I> Index<I> for ArrayBase<S, D>
where
D: Dimension,
I: NdIndex<D>,
S: Data,
{
type Output = S::Elem;
#[inline]
fn index(&self, index: I) -> &S::Elem
{
Index::index(&**self, index)
}
}
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
where
D: Dimension,
I: NdIndex<D>,
S: DataMut,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut S::Elem
{
IndexMut::index_mut(&mut (**self), index)
}
}
impl<A, B, D> PartialEq<ArrayRef<B, D>> for ArrayRef<A, D>
where
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, rhs: &ArrayRef<B, D>) -> bool
{
if self.shape() != rhs.shape() {
return false;
}
if let Some(self_s) = self.as_slice() {
if let Some(rhs_s) = rhs.as_slice() {
return numeric_util::unrolled_eq(self_s, rhs_s);
}
}
Zip::from(self)
.and(rhs)
.fold_while(true, |_, a, b| {
if a != b {
FoldWhile::Done(false)
} else {
FoldWhile::Continue(true)
}
})
.into_inner()
}
}
impl<A, B, D> PartialEq<&ArrayRef<B, D>> for ArrayRef<A, D>
where
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, rhs: &&ArrayRef<B, D>) -> bool
{
*self == **rhs
}
}
impl<A, B, D> PartialEq<ArrayRef<B, D>> for &ArrayRef<A, D>
where
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, rhs: &ArrayRef<B, D>) -> bool
{
**self == *rhs
}
}
impl<A, D> Eq for ArrayRef<A, D>
where
D: Dimension,
A: Eq,
{
}
impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
where
A: PartialEq<B>,
S: Data<Elem = A>,
S2: Data<Elem = B>,
D: Dimension,
{
fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
{
PartialEq::eq(&**self, &**rhs)
}
}
impl<A, B, S, S2, D> PartialEq<&ArrayBase<S2, D>> for ArrayBase<S, D>
where
A: PartialEq<B>,
S: Data<Elem = A>,
S2: Data<Elem = B>,
D: Dimension,
{
fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool
{
*self == **rhs
}
}
impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &ArrayBase<S, D>
where
A: PartialEq<B>,
S: Data<Elem = A>,
S2: Data<Elem = B>,
D: Dimension,
{
fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
{
**self == *rhs
}
}
impl<S, D> Eq for ArrayBase<S, D>
where
D: Dimension,
S: Data,
S::Elem: Eq,
{
}
impl<A, B, S, D> PartialEq<ArrayRef<B, D>> for ArrayBase<S, D>
where
S: Data<Elem = A>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &ArrayRef<B, D>) -> bool
{
**self == other
}
}
impl<A, B, S, D> PartialEq<&ArrayRef<B, D>> for ArrayBase<S, D>
where
S: Data<Elem = A>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &&ArrayRef<B, D>) -> bool
{
**self == *other
}
}
impl<A, B, S, D> PartialEq<ArrayRef<B, D>> for &ArrayBase<S, D>
where
S: Data<Elem = A>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &ArrayRef<B, D>) -> bool
{
**self == other
}
}
impl<A, B, S, D> PartialEq<ArrayBase<S, D>> for ArrayRef<A, D>
where
S: Data<Elem = B>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &ArrayBase<S, D>) -> bool
{
self == **other
}
}
impl<A, B, S, D> PartialEq<&ArrayBase<S, D>> for ArrayRef<A, D>
where
S: Data<Elem = B>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &&ArrayBase<S, D>) -> bool
{
self == ***other
}
}
impl<A, B, S, D> PartialEq<ArrayBase<S, D>> for &ArrayRef<A, D>
where
S: Data<Elem = B>,
A: PartialEq<B>,
D: Dimension,
{
fn eq(&self, other: &ArrayBase<S, D>) -> bool
{
*self == **other
}
}
impl<A, S> From<Box<[A]>> for ArrayBase<S, Ix1>
where S: DataOwned<Elem = A>
{
fn from(b: Box<[A]>) -> Self
{
Self::from_vec(b.into_vec())
}
}
impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
where S: DataOwned<Elem = A>
{
fn from(v: Vec<A>) -> Self
{
Self::from_vec(v)
}
}
impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
where S: DataOwned<Elem = A>
{
fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
where I: IntoIterator<Item = A>
{
Self::from_iter(iterable)
}
}
impl<'a, A, D> IntoIterator for &'a ArrayRef<A, D>
where D: Dimension
{
type Item = &'a A;
type IntoIter = Iter<'a, A, D>;
fn into_iter(self) -> Self::IntoIter
{
self.iter()
}
}
impl<'a, A, D> IntoIterator for &'a mut ArrayRef<A, D>
where D: Dimension
{
type Item = &'a mut A;
type IntoIter = IterMut<'a, A, D>;
fn into_iter(self) -> Self::IntoIter
{
self.iter_mut()
}
}
impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
where
D: Dimension,
S: Data,
{
type Item = &'a S::Elem;
type IntoIter = Iter<'a, S::Elem, D>;
fn into_iter(self) -> Self::IntoIter
{
self.iter()
}
}
impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
where
D: Dimension,
S: DataMut,
{
type Item = &'a mut S::Elem;
type IntoIter = IterMut<'a, S::Elem, D>;
fn into_iter(self) -> Self::IntoIter
{
self.iter_mut()
}
}
impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
where D: Dimension
{
type Item = &'a A;
type IntoIter = Iter<'a, A, D>;
fn into_iter(self) -> Self::IntoIter
{
Iter::new(self)
}
}
impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
where D: Dimension
{
type Item = &'a mut A;
type IntoIter = IterMut<'a, A, D>;
fn into_iter(self) -> Self::IntoIter
{
IterMut::new(self)
}
}
impl<A, D> hash::Hash for ArrayRef<A, D>
where
D: Dimension,
A: hash::Hash,
{
fn hash<H: hash::Hasher>(&self, state: &mut H)
{
self.shape().hash(state);
if let Some(self_s) = self.as_slice() {
hash::Hash::hash_slice(self_s, state);
} else {
for row in self.rows() {
if let Some(row_s) = row.as_slice() {
hash::Hash::hash_slice(row_s, state);
} else {
for elt in row {
elt.hash(state)
}
}
}
}
}
}
impl<S, D> hash::Hash for ArrayBase<S, D>
where
D: Dimension,
S: Data,
S::Elem: hash::Hash,
{
fn hash<H: hash::Hasher>(&self, state: &mut H)
{
(**self).hash(state)
}
}
unsafe impl<S, D> Sync for ArrayBase<S, D>
where
S: Sync + Data,
D: Sync,
{
}
unsafe impl<S, D> Send for ArrayBase<S, D>
where
S: Send + Data,
D: Send,
{
}
unsafe impl<A, D> Sync for ArrayRef<A, D> where A: Sync {}
unsafe impl<A, D> Send for ArrayRef<A, D> where A: Send {}
#[cfg(feature = "serde")]
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
where Slice: AsRef<[A]>
{
fn from(slice: &'a Slice) -> Self
{
aview1(slice.as_ref())
}
}
impl<'a, A, const M: usize, const N: usize> From<&'a [[A; N]; M]> for ArrayView<'a, A, Ix2>
{
fn from(xs: &'a [[A; N]; M]) -> Self
{
Self::from(&xs[..])
}
}
impl<'a, A, const N: usize> From<&'a [[A; N]]> for ArrayView<'a, A, Ix2>
{
fn from(xs: &'a [[A; N]]) -> Self
{
aview2(xs)
}
}
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
where
S: Data<Elem = A>,
D: Dimension,
{
fn from(array: &'a ArrayBase<S, D>) -> Self
{
array.view()
}
}
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
where Slice: AsMut<[A]>
{
fn from(slice: &'a mut Slice) -> Self
{
let xs = slice.as_mut();
if mem::size_of::<A>() == 0 {
assert!(
xs.len() <= isize::MAX as usize,
"Slice length must fit in `isize`.",
);
}
unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
}
}
impl<'a, A, const M: usize, const N: usize> From<&'a mut [[A; N]; M]> for ArrayViewMut<'a, A, Ix2>
{
fn from(xs: &'a mut [[A; N]; M]) -> Self
{
Self::from(&mut xs[..])
}
}
impl<'a, A, const N: usize> From<&'a mut [[A; N]]> for ArrayViewMut<'a, A, Ix2>
{
fn from(xs: &'a mut [[A; N]]) -> Self
{
let cols = N;
let rows = xs.len();
let dim = Ix2(rows, cols);
if size_of::<A>() == 0 {
dimension::size_of_shape_checked(&dim).expect("Product of non-zero axis lengths must not overflow isize.");
} else if N == 0 {
assert!(
xs.len() <= isize::MAX as usize,
"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())
}
}
}
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
where
S: DataMut<Elem = A>,
D: Dimension,
{
fn from(array: &'a mut ArrayBase<S, D>) -> Self
{
array.view_mut()
}
}
impl<A, D> From<Array<A, D>> for ArcArray<A, D>
where D: Dimension
{
fn from(arr: Array<A, D>) -> ArcArray<A, D>
{
let data = OwnedArcRepr(Arc::new(arr.data));
unsafe { ArrayBase::from_data_ptr(data, arr.parts.ptr).with_strides_dim(arr.parts.strides, arr.parts.dim) }
}
}
pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
where D: Dimension
{
}
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
where
T: Into<ArrayView<'a, A, D>>,
D: Dimension,
{
}
impl<A, S, D> Default for ArrayBase<S, D>
where
S: DataOwned<Elem = A>,
D: Dimension,
A: Default,
{
fn default() -> Self
{
ArrayBase::default(D::default())
}
}
#[cfg(test)]
mod tests
{
use crate::array;
use alloc::vec;
#[test]
fn test_eq_traits()
{
let a = array![1, 2, 3];
let a_ref = &*a;
let b = array![1, 2, 3];
let b_ref = &*b;
assert_eq!(a, b);
assert_eq!(a, &b);
assert_eq!(&a, b);
assert_eq!(&a, &b);
assert_eq!(a_ref, b_ref);
assert_eq!(&a_ref, b_ref);
assert_eq!(a_ref, &b_ref);
assert_eq!(&a_ref, &b_ref);
assert_eq!(a_ref, b);
assert_eq!(a_ref, &b);
assert_eq!(&a_ref, &b);
assert_eq!(a, b_ref);
assert_eq!(&a, b_ref);
assert_eq!(&a, &b_ref);
}
}