1#[cfg(not(feature = "std"))]
10use alloc::boxed::Box;
11#[cfg(not(feature = "std"))]
12use alloc::vec::Vec;
13use std::hash;
14use std::mem;
15use std::mem::size_of;
16use std::ops::{Index, IndexMut};
17use std::{iter::FromIterator, slice};
18
19use crate::imp_prelude::*;
20use crate::Arc;
21
22use crate::{
23 dimension,
24 iter::{Iter, IterMut},
25 numeric_util,
26 FoldWhile,
27 NdIndex,
28 OwnedArcRepr,
29 Zip,
30};
31
32#[cold]
33#[inline(never)]
34pub(crate) fn array_out_of_bounds() -> !
35{
36 panic!("ndarray: index out of bounds");
37}
38
39#[inline(always)]
40pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
41where
42 D: Dimension,
43 I: NdIndex<D>,
44 S: Data,
45{
46 debug_bounds_check!(_a, *_index);
47}
48
49impl<S, D, I> Index<I> for ArrayBase<S, D>
53where
54 D: Dimension,
55 I: NdIndex<D>,
56 S: Data,
57{
58 type Output = S::Elem;
59 #[inline]
60 fn index(&self, index: I) -> &S::Elem
61 {
62 debug_bounds_check!(self, index);
63 unsafe {
64 &*self.ptr.as_ptr().offset(
65 index
66 .index_checked(&self.dim, &self.strides)
67 .unwrap_or_else(|| array_out_of_bounds()),
68 )
69 }
70 }
71}
72
73impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
77where
78 D: Dimension,
79 I: NdIndex<D>,
80 S: DataMut,
81{
82 #[inline]
83 fn index_mut(&mut self, index: I) -> &mut S::Elem
84 {
85 debug_bounds_check!(self, index);
86 unsafe {
87 &mut *self.as_mut_ptr().offset(
88 index
89 .index_checked(&self.dim, &self.strides)
90 .unwrap_or_else(|| array_out_of_bounds()),
91 )
92 }
93 }
94}
95
96impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
99where
100 A: PartialEq<B>,
101 S: Data<Elem = A>,
102 S2: Data<Elem = B>,
103 D: Dimension,
104{
105 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
106 {
107 if self.shape() != rhs.shape() {
108 return false;
109 }
110 if let Some(self_s) = self.as_slice() {
111 if let Some(rhs_s) = rhs.as_slice() {
112 return numeric_util::unrolled_eq(self_s, rhs_s);
113 }
114 }
115 Zip::from(self)
116 .and(rhs)
117 .fold_while(true, |_, a, b| {
118 if a != b {
119 FoldWhile::Done(false)
120 } else {
121 FoldWhile::Continue(true)
122 }
123 })
124 .into_inner()
125 }
126}
127
128#[allow(clippy::unconditional_recursion)] impl<'a, A, B, S, S2, D> PartialEq<&'a ArrayBase<S2, D>> for ArrayBase<S, D>
132where
133 A: PartialEq<B>,
134 S: Data<Elem = A>,
135 S2: Data<Elem = B>,
136 D: Dimension,
137{
138 fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool
139 {
140 *self == **rhs
141 }
142}
143
144#[allow(clippy::unconditional_recursion)] impl<'a, A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &'a ArrayBase<S, D>
148where
149 A: PartialEq<B>,
150 S: Data<Elem = A>,
151 S2: Data<Elem = B>,
152 D: Dimension,
153{
154 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
155 {
156 **self == *rhs
157 }
158}
159
160impl<S, D> Eq for ArrayBase<S, D>
161where
162 D: Dimension,
163 S: Data,
164 S::Elem: Eq,
165{
166}
167
168impl<A, S> From<Box<[A]>> for ArrayBase<S, Ix1>
169where S: DataOwned<Elem = A>
170{
171 fn from(b: Box<[A]>) -> Self
175 {
176 Self::from_vec(b.into_vec())
177 }
178}
179
180impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
181where S: DataOwned<Elem = A>
182{
183 fn from(v: Vec<A>) -> Self
193 {
194 Self::from_vec(v)
195 }
196}
197
198impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
199where S: DataOwned<Elem = A>
200{
201 fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
213 where I: IntoIterator<Item = A>
214 {
215 Self::from_iter(iterable)
216 }
217}
218
219impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
220where
221 D: Dimension,
222 S: Data,
223{
224 type Item = &'a S::Elem;
225 type IntoIter = Iter<'a, S::Elem, D>;
226
227 fn into_iter(self) -> Self::IntoIter
228 {
229 self.iter()
230 }
231}
232
233impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
234where
235 D: Dimension,
236 S: DataMut,
237{
238 type Item = &'a mut S::Elem;
239 type IntoIter = IterMut<'a, S::Elem, D>;
240
241 fn into_iter(self) -> Self::IntoIter
242 {
243 self.iter_mut()
244 }
245}
246
247impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
248where D: Dimension
249{
250 type Item = &'a A;
251 type IntoIter = Iter<'a, A, D>;
252
253 fn into_iter(self) -> Self::IntoIter
254 {
255 self.into_iter_()
256 }
257}
258
259impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
260where D: Dimension
261{
262 type Item = &'a mut A;
263 type IntoIter = IterMut<'a, A, D>;
264
265 fn into_iter(self) -> Self::IntoIter
266 {
267 self.into_iter_()
268 }
269}
270
271impl<S, D> hash::Hash for ArrayBase<S, D>
272where
273 D: Dimension,
274 S: Data,
275 S::Elem: hash::Hash,
276{
277 fn hash<H: hash::Hasher>(&self, state: &mut H)
279 {
280 self.shape().hash(state);
281 if let Some(self_s) = self.as_slice() {
282 hash::Hash::hash_slice(self_s, state);
283 } else {
284 for row in self.rows() {
285 if let Some(row_s) = row.as_slice() {
286 hash::Hash::hash_slice(row_s, state);
287 } else {
288 for elt in row {
289 elt.hash(state)
290 }
291 }
292 }
293 }
294 }
295}
296
297unsafe impl<S, D> Sync for ArrayBase<S, D>
304where
305 S: Sync + Data,
306 D: Sync,
307{
308}
309
310unsafe impl<S, D> Send for ArrayBase<S, D>
312where
313 S: Send + Data,
314 D: Send,
315{
316}
317
318#[cfg(feature = "serde")]
319pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
321
322impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
329where Slice: AsRef<[A]>
330{
331 fn from(slice: &'a Slice) -> Self
335 {
336 aview1(slice.as_ref())
337 }
338}
339
340impl<'a, A, const M: usize, const N: usize> From<&'a [[A; N]; M]> for ArrayView<'a, A, Ix2>
346{
347 fn from(xs: &'a [[A; N]; M]) -> Self
349 {
350 Self::from(&xs[..])
351 }
352}
353
354impl<'a, A, const N: usize> From<&'a [[A; N]]> for ArrayView<'a, A, Ix2>
360{
361 fn from(xs: &'a [[A; N]]) -> Self
363 {
364 aview2(xs)
365 }
366}
367
368impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
370where
371 S: Data<Elem = A>,
372 D: Dimension,
373{
374 fn from(array: &'a ArrayBase<S, D>) -> Self
376 {
377 array.view()
378 }
379}
380
381impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
383where Slice: AsMut<[A]>
384{
385 fn from(slice: &'a mut Slice) -> Self
389 {
390 let xs = slice.as_mut();
391 if mem::size_of::<A>() == 0 {
392 assert!(
393 xs.len() <= isize::MAX as usize,
394 "Slice length must fit in `isize`.",
395 );
396 }
397 unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
398 }
399}
400
401impl<'a, A, const M: usize, const N: usize> From<&'a mut [[A; N]; M]> for ArrayViewMut<'a, A, Ix2>
407{
408 fn from(xs: &'a mut [[A; N]; M]) -> Self
410 {
411 Self::from(&mut xs[..])
412 }
413}
414
415impl<'a, A, const N: usize> From<&'a mut [[A; N]]> for ArrayViewMut<'a, A, Ix2>
421{
422 fn from(xs: &'a mut [[A; N]]) -> Self
424 {
425 let cols = N;
426 let rows = xs.len();
427 let dim = Ix2(rows, cols);
428 if size_of::<A>() == 0 {
429 dimension::size_of_shape_checked(&dim).expect("Product of non-zero axis lengths must not overflow isize.");
430 } else if N == 0 {
431 assert!(
432 xs.len() <= isize::MAX as usize,
433 "Product of non-zero axis lengths must not overflow isize.",
434 );
435 }
436
437 unsafe {
440 let data = slice::from_raw_parts_mut(xs.as_mut_ptr() as *mut A, cols * rows);
441 ArrayViewMut::from_shape_ptr(dim, data.as_mut_ptr())
442 }
443 }
444}
445
446impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
448where
449 S: DataMut<Elem = A>,
450 D: Dimension,
451{
452 fn from(array: &'a mut ArrayBase<S, D>) -> Self
454 {
455 array.view_mut()
456 }
457}
458
459impl<A, D> From<Array<A, D>> for ArcArray<A, D>
460where D: Dimension
461{
462 fn from(arr: Array<A, D>) -> ArcArray<A, D>
463 {
464 let data = OwnedArcRepr(Arc::new(arr.data));
465 unsafe { ArrayBase::from_data_ptr(data, arr.ptr).with_strides_dim(arr.strides, arr.dim) }
467 }
468}
469
470pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
492where D: Dimension
493{
494}
495impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
496where
497 T: Into<ArrayView<'a, A, D>>,
498 D: Dimension,
499{
500}
501
502impl<A, S, D> Default for ArrayBase<S, D>
515where
516 S: DataOwned<Elem = A>,
517 D: Dimension,
518 A: Default,
519{
520 fn default() -> Self
523 {
524 ArrayBase::default(D::default())
525 }
526}