1use std::hash;
10use std::iter::FromIterator;
11use std::iter::IntoIterator;
12use std::mem;
13use std::ops::{Index, IndexMut};
14use alloc::boxed::Box;
15use alloc::vec::Vec;
16
17use crate::imp_prelude::*;
18use crate::iter::{Iter, IterMut};
19use crate::NdIndex;
20
21use crate::numeric_util;
22use crate::{FoldWhile, Zip};
23
24#[cold]
25#[inline(never)]
26pub(crate) fn array_out_of_bounds() -> ! {
27 panic!("ndarray: index out of bounds");
28}
29
30#[inline(always)]
31pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
32where
33 D: Dimension,
34 I: NdIndex<D>,
35 S: Data,
36{
37 debug_bounds_check!(_a, *_index);
38}
39
40impl<S, D, I> Index<I> for ArrayBase<S, D>
44where
45 D: Dimension,
46 I: NdIndex<D>,
47 S: Data,
48{
49 type Output = S::Elem;
50 #[inline]
51 fn index(&self, index: I) -> &S::Elem {
52 debug_bounds_check!(self, index);
53 unsafe {
54 &*self.ptr.as_ptr().offset(
55 index
56 .index_checked(&self.dim, &self.strides)
57 .unwrap_or_else(|| array_out_of_bounds()),
58 )
59 }
60 }
61}
62
63impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
67where
68 D: Dimension,
69 I: NdIndex<D>,
70 S: DataMut,
71{
72 #[inline]
73 fn index_mut(&mut self, index: I) -> &mut S::Elem {
74 debug_bounds_check!(self, index);
75 unsafe {
76 &mut *self.as_mut_ptr().offset(
77 index
78 .index_checked(&self.dim, &self.strides)
79 .unwrap_or_else(|| array_out_of_bounds()),
80 )
81 }
82 }
83}
84
85impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
88where
89 A: PartialEq<B>,
90 S: Data<Elem = A>,
91 S2: Data<Elem = B>,
92 D: Dimension,
93{
94 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
95 if self.shape() != rhs.shape() {
96 return false;
97 }
98 if let Some(self_s) = self.as_slice() {
99 if let Some(rhs_s) = rhs.as_slice() {
100 return numeric_util::unrolled_eq(self_s, rhs_s);
101 }
102 }
103 Zip::from(self)
104 .and(rhs)
105 .fold_while(true, |_, a, b| {
106 if a != b {
107 FoldWhile::Done(false)
108 } else {
109 FoldWhile::Continue(true)
110 }
111 })
112 .into_inner()
113 }
114}
115
116impl<'a, A, B, S, S2, D> PartialEq<&'a ArrayBase<S2, D>> for ArrayBase<S, D>
119where
120 A: PartialEq<B>,
121 S: Data<Elem = A>,
122 S2: Data<Elem = B>,
123 D: Dimension,
124{
125 fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool {
126 *self == **rhs
127 }
128}
129
130impl<'a, A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &'a ArrayBase<S, D>
133where
134 A: PartialEq<B>,
135 S: Data<Elem = A>,
136 S2: Data<Elem = B>,
137 D: Dimension,
138{
139 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
140 **self == *rhs
141 }
142}
143
144impl<S, D> Eq for ArrayBase<S, D>
145where
146 D: Dimension,
147 S: Data,
148 S::Elem: Eq,
149{
150}
151
152impl<A, S> From<Box<[A]>> for ArrayBase<S, Ix1>
153where
154 S: DataOwned<Elem = A>,
155{
156 fn from(b: Box<[A]>) -> Self {
160 Self::from_vec(b.into_vec())
161 }
162}
163
164impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
165where
166 S: DataOwned<Elem = A>,
167{
168 fn from(v: Vec<A>) -> Self {
178 Self::from_vec(v)
179 }
180}
181
182impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
183where
184 S: DataOwned<Elem = A>,
185{
186 fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
198 where
199 I: IntoIterator<Item = A>,
200 {
201 Self::from_iter(iterable)
202 }
203}
204
205impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
206where
207 D: Dimension,
208 S: Data,
209{
210 type Item = &'a S::Elem;
211 type IntoIter = Iter<'a, S::Elem, D>;
212
213 fn into_iter(self) -> Self::IntoIter {
214 self.iter()
215 }
216}
217
218impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
219where
220 D: Dimension,
221 S: DataMut,
222{
223 type Item = &'a mut S::Elem;
224 type IntoIter = IterMut<'a, S::Elem, D>;
225
226 fn into_iter(self) -> Self::IntoIter {
227 self.iter_mut()
228 }
229}
230
231impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
232where
233 D: Dimension,
234{
235 type Item = &'a A;
236 type IntoIter = Iter<'a, A, D>;
237
238 fn into_iter(self) -> Self::IntoIter {
239 self.into_iter_()
240 }
241}
242
243impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
244where
245 D: Dimension,
246{
247 type Item = &'a mut A;
248 type IntoIter = IterMut<'a, A, D>;
249
250 fn into_iter(self) -> Self::IntoIter {
251 self.into_iter_()
252 }
253}
254
255impl<S, D> hash::Hash for ArrayBase<S, D>
256where
257 D: Dimension,
258 S: Data,
259 S::Elem: hash::Hash,
260{
261 fn hash<H: hash::Hasher>(&self, state: &mut H) {
263 self.shape().hash(state);
264 if let Some(self_s) = self.as_slice() {
265 hash::Hash::hash_slice(self_s, state);
266 } else {
267 for row in self.rows() {
268 if let Some(row_s) = row.as_slice() {
269 hash::Hash::hash_slice(row_s, state);
270 } else {
271 for elt in row {
272 elt.hash(state)
273 }
274 }
275 }
276 }
277 }
278}
279
280unsafe impl<S, D> Sync for ArrayBase<S, D>
287where
288 S: Sync + Data,
289 D: Sync,
290{
291}
292
293unsafe impl<S, D> Send for ArrayBase<S, D>
295where
296 S: Send + Data,
297 D: Send,
298{
299}
300
301#[cfg(any(feature = "serde"))]
302pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
304
305impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
308where
309 Slice: AsRef<[A]>,
310{
311 fn from(slice: &'a Slice) -> Self {
315 let xs = slice.as_ref();
316 if mem::size_of::<A>() == 0 {
317 assert!(
318 xs.len() <= ::std::isize::MAX as usize,
319 "Slice length must fit in `isize`.",
320 );
321 }
322 unsafe { Self::from_shape_ptr(xs.len(), xs.as_ptr()) }
323 }
324}
325
326impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
328where
329 S: Data<Elem = A>,
330 D: Dimension,
331{
332 fn from(array: &'a ArrayBase<S, D>) -> Self {
334 array.view()
335 }
336}
337
338impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
340where
341 Slice: AsMut<[A]>,
342{
343 fn from(slice: &'a mut Slice) -> Self {
347 let xs = slice.as_mut();
348 if mem::size_of::<A>() == 0 {
349 assert!(
350 xs.len() <= ::std::isize::MAX as usize,
351 "Slice length must fit in `isize`.",
352 );
353 }
354 unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
355 }
356}
357
358impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
360where
361 S: DataMut<Elem = A>,
362 D: Dimension,
363{
364 fn from(array: &'a mut ArrayBase<S, D>) -> Self {
366 array.view_mut()
367 }
368}
369
370impl<A, D> From<Array<A, D>> for ArcArray<A, D>
371where
372 D: Dimension,
373{
374 fn from(arr: Array<A, D>) -> ArcArray<A, D> {
375 arr.into_shared()
376 }
377}
378
379pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
401where
402 D: Dimension,
403{
404}
405impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
406where
407 T: Into<ArrayView<'a, A, D>>,
408 D: Dimension,
409{
410}
411
412impl<A, S, D> Default for ArrayBase<S, D>
425where
426 S: DataOwned<Elem = A>,
427 D: Dimension,
428 A: Default,
429{
430 fn default() -> Self {
433 ArrayBase::default(D::default())
434 }
435}