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<A, D, I, T>(_a: &T, _index: &I)
41where
42 D: Dimension,
43 I: NdIndex<D>,
44 T: AsRef<LayoutRef<A, D>> + ?Sized,
45{
46 let _layout_ref = _a.as_ref();
47 debug_bounds_check_ref!(_layout_ref, *_index);
48}
49
50impl<A, D, I> Index<I> for ArrayRef<A, D>
54where
55 D: Dimension,
56 I: NdIndex<D>,
57{
58 type Output = A;
59
60 #[inline]
61 fn index(&self, index: I) -> &Self::Output
62 {
63 debug_bounds_check_ref!(self, index);
64 unsafe {
65 &*self._ptr().as_ptr().offset(
66 index
67 .index_checked(self._dim(), self._strides())
68 .unwrap_or_else(|| array_out_of_bounds()),
69 )
70 }
71 }
72}
73
74impl<A, D, I> IndexMut<I> for ArrayRef<A, D>
78where
79 D: Dimension,
80 I: NdIndex<D>,
81{
82 #[inline]
83 fn index_mut(&mut self, index: I) -> &mut A
84 {
85 debug_bounds_check_ref!(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<S, D, I> Index<I> for ArrayBase<S, D>
100where
101 D: Dimension,
102 I: NdIndex<D>,
103 S: Data,
104{
105 type Output = S::Elem;
106
107 #[inline]
108 fn index(&self, index: I) -> &S::Elem
109 {
110 Index::index(&**self, index)
111 }
112}
113
114impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
118where
119 D: Dimension,
120 I: NdIndex<D>,
121 S: DataMut,
122{
123 #[inline]
124 fn index_mut(&mut self, index: I) -> &mut S::Elem
125 {
126 IndexMut::index_mut(&mut (**self), index)
127 }
128}
129
130impl<A, B, D> PartialEq<ArrayRef<B, D>> for ArrayRef<A, D>
133where
134 A: PartialEq<B>,
135 D: Dimension,
136{
137 fn eq(&self, rhs: &ArrayRef<B, D>) -> bool
138 {
139 if self.shape() != rhs.shape() {
140 return false;
141 }
142 if let Some(self_s) = self.as_slice() {
143 if let Some(rhs_s) = rhs.as_slice() {
144 return numeric_util::unrolled_eq(self_s, rhs_s);
145 }
146 }
147 Zip::from(self)
148 .and(rhs)
149 .fold_while(true, |_, a, b| {
150 if a != b {
151 FoldWhile::Done(false)
152 } else {
153 FoldWhile::Continue(true)
154 }
155 })
156 .into_inner()
157 }
158}
159
160impl<A, B, D> PartialEq<&ArrayRef<B, D>> for ArrayRef<A, D>
163where
164 A: PartialEq<B>,
165 D: Dimension,
166{
167 fn eq(&self, rhs: &&ArrayRef<B, D>) -> bool
168 {
169 *self == **rhs
170 }
171}
172
173impl<A, B, D> PartialEq<ArrayRef<B, D>> for &ArrayRef<A, D>
176where
177 A: PartialEq<B>,
178 D: Dimension,
179{
180 fn eq(&self, rhs: &ArrayRef<B, D>) -> bool
181 {
182 **self == *rhs
183 }
184}
185
186impl<A, D> Eq for ArrayRef<A, D>
187where
188 D: Dimension,
189 A: Eq,
190{
191}
192
193impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
196where
197 A: PartialEq<B>,
198 S: Data<Elem = A>,
199 S2: Data<Elem = B>,
200 D: Dimension,
201{
202 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
203 {
204 PartialEq::eq(&**self, &**rhs)
205 }
206}
207
208#[allow(clippy::unconditional_recursion)] impl<A, B, S, S2, D> PartialEq<&ArrayBase<S2, D>> for ArrayBase<S, D>
212where
213 A: PartialEq<B>,
214 S: Data<Elem = A>,
215 S2: Data<Elem = B>,
216 D: Dimension,
217{
218 fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool
219 {
220 *self == **rhs
221 }
222}
223
224#[allow(clippy::unconditional_recursion)] impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &ArrayBase<S, D>
228where
229 A: PartialEq<B>,
230 S: Data<Elem = A>,
231 S2: Data<Elem = B>,
232 D: Dimension,
233{
234 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool
235 {
236 **self == *rhs
237 }
238}
239
240impl<S, D> Eq for ArrayBase<S, D>
241where
242 D: Dimension,
243 S: Data,
244 S::Elem: Eq,
245{
246}
247
248impl<A, S> From<Box<[A]>> for ArrayBase<S, Ix1>
249where S: DataOwned<Elem = A>
250{
251 fn from(b: Box<[A]>) -> Self
255 {
256 Self::from_vec(b.into_vec())
257 }
258}
259
260impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
261where S: DataOwned<Elem = A>
262{
263 fn from(v: Vec<A>) -> Self
273 {
274 Self::from_vec(v)
275 }
276}
277
278impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
279where S: DataOwned<Elem = A>
280{
281 fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
293 where I: IntoIterator<Item = A>
294 {
295 Self::from_iter(iterable)
296 }
297}
298
299impl<'a, A, D> IntoIterator for &'a ArrayRef<A, D>
300where D: Dimension
301{
302 type Item = &'a A;
303
304 type IntoIter = Iter<'a, A, D>;
305
306 fn into_iter(self) -> Self::IntoIter
307 {
308 self.iter()
309 }
310}
311
312impl<'a, A, D> IntoIterator for &'a mut ArrayRef<A, D>
313where D: Dimension
314{
315 type Item = &'a mut A;
316
317 type IntoIter = IterMut<'a, A, D>;
318
319 fn into_iter(self) -> Self::IntoIter
320 {
321 self.iter_mut()
322 }
323}
324
325impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
326where
327 D: Dimension,
328 S: Data,
329{
330 type Item = &'a S::Elem;
331 type IntoIter = Iter<'a, S::Elem, D>;
332
333 fn into_iter(self) -> Self::IntoIter
334 {
335 self.iter()
336 }
337}
338
339impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
340where
341 D: Dimension,
342 S: DataMut,
343{
344 type Item = &'a mut S::Elem;
345 type IntoIter = IterMut<'a, S::Elem, D>;
346
347 fn into_iter(self) -> Self::IntoIter
348 {
349 self.iter_mut()
350 }
351}
352
353impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
354where D: Dimension
355{
356 type Item = &'a A;
357 type IntoIter = Iter<'a, A, D>;
358
359 fn into_iter(self) -> Self::IntoIter
360 {
361 Iter::new(self)
362 }
363}
364
365impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
366where D: Dimension
367{
368 type Item = &'a mut A;
369 type IntoIter = IterMut<'a, A, D>;
370
371 fn into_iter(self) -> Self::IntoIter
372 {
373 IterMut::new(self)
374 }
375}
376
377impl<A, D> hash::Hash for ArrayRef<A, D>
378where
379 D: Dimension,
380 A: hash::Hash,
381{
382 fn hash<H: hash::Hasher>(&self, state: &mut H)
384 {
385 self.shape().hash(state);
386 if let Some(self_s) = self.as_slice() {
387 hash::Hash::hash_slice(self_s, state);
388 } else {
389 for row in self.rows() {
390 if let Some(row_s) = row.as_slice() {
391 hash::Hash::hash_slice(row_s, state);
392 } else {
393 for elt in row {
394 elt.hash(state)
395 }
396 }
397 }
398 }
399 }
400}
401
402impl<S, D> hash::Hash for ArrayBase<S, D>
403where
404 D: Dimension,
405 S: Data,
406 S::Elem: hash::Hash,
407{
408 fn hash<H: hash::Hasher>(&self, state: &mut H)
410 {
411 (**self).hash(state)
412 }
413}
414
415unsafe impl<S, D> Sync for ArrayBase<S, D>
422where
423 S: Sync + Data,
424 D: Sync,
425{
426}
427
428unsafe impl<S, D> Send for ArrayBase<S, D>
430where
431 S: Send + Data,
432 D: Send,
433{
434}
435
436#[cfg(feature = "serde")]
437#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
438pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
440
441impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
448where Slice: AsRef<[A]>
449{
450 fn from(slice: &'a Slice) -> Self
454 {
455 aview1(slice.as_ref())
456 }
457}
458
459impl<'a, A, const M: usize, const N: usize> From<&'a [[A; N]; M]> for ArrayView<'a, A, Ix2>
465{
466 fn from(xs: &'a [[A; N]; M]) -> Self
468 {
469 Self::from(&xs[..])
470 }
471}
472
473impl<'a, A, const N: usize> From<&'a [[A; N]]> for ArrayView<'a, A, Ix2>
479{
480 fn from(xs: &'a [[A; N]]) -> Self
482 {
483 aview2(xs)
484 }
485}
486
487impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
489where
490 S: Data<Elem = A>,
491 D: Dimension,
492{
493 fn from(array: &'a ArrayBase<S, D>) -> Self
495 {
496 array.view()
497 }
498}
499
500impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
502where Slice: AsMut<[A]>
503{
504 fn from(slice: &'a mut Slice) -> Self
508 {
509 let xs = slice.as_mut();
510 if mem::size_of::<A>() == 0 {
511 assert!(
512 xs.len() <= isize::MAX as usize,
513 "Slice length must fit in `isize`.",
514 );
515 }
516 unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
517 }
518}
519
520impl<'a, A, const M: usize, const N: usize> From<&'a mut [[A; N]; M]> for ArrayViewMut<'a, A, Ix2>
526{
527 fn from(xs: &'a mut [[A; N]; M]) -> Self
529 {
530 Self::from(&mut xs[..])
531 }
532}
533
534impl<'a, A, const N: usize> From<&'a mut [[A; N]]> for ArrayViewMut<'a, A, Ix2>
540{
541 fn from(xs: &'a mut [[A; N]]) -> Self
543 {
544 let cols = N;
545 let rows = xs.len();
546 let dim = Ix2(rows, cols);
547 if size_of::<A>() == 0 {
548 dimension::size_of_shape_checked(&dim).expect("Product of non-zero axis lengths must not overflow isize.");
549 } else if N == 0 {
550 assert!(
551 xs.len() <= isize::MAX as usize,
552 "Product of non-zero axis lengths must not overflow isize.",
553 );
554 }
555
556 unsafe {
559 let data = slice::from_raw_parts_mut(xs.as_mut_ptr() as *mut A, cols * rows);
560 ArrayViewMut::from_shape_ptr(dim, data.as_mut_ptr())
561 }
562 }
563}
564
565impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
567where
568 S: DataMut<Elem = A>,
569 D: Dimension,
570{
571 fn from(array: &'a mut ArrayBase<S, D>) -> Self
573 {
574 array.view_mut()
575 }
576}
577
578impl<A, D> From<Array<A, D>> for ArcArray<A, D>
579where D: Dimension
580{
581 fn from(arr: Array<A, D>) -> ArcArray<A, D>
582 {
583 let data = OwnedArcRepr(Arc::new(arr.data));
584 unsafe { ArrayBase::from_data_ptr(data, arr.parts.ptr).with_strides_dim(arr.parts.strides, arr.parts.dim) }
586 }
587}
588
589pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
611where D: Dimension
612{
613}
614impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
615where
616 T: Into<ArrayView<'a, A, D>>,
617 D: Dimension,
618{
619}
620
621impl<A, S, D> Default for ArrayBase<S, D>
634where
635 S: DataOwned<Elem = A>,
636 D: Dimension,
637 A: Default,
638{
639 fn default() -> Self
642 {
643 ArrayBase::default(D::default())
644 }
645}