1use std::hash;
10use std::iter::FromIterator;
11use std::iter::IntoIterator;
12use std::mem;
13use std::ops::{Index, IndexMut};
14use alloc::vec::Vec;
15
16use crate::imp_prelude::*;
17use crate::iter::{Iter, IterMut};
18use crate::NdIndex;
19
20use crate::numeric_util;
21use crate::{FoldWhile, Zip};
22
23#[cold]
24#[inline(never)]
25pub(crate) fn array_out_of_bounds() -> ! {
26 panic!("ndarray: index out of bounds");
27}
28
29#[inline(always)]
30pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
31where
32 D: Dimension,
33 I: NdIndex<D>,
34 S: Data,
35{
36 debug_bounds_check!(_a, *_index);
37}
38
39impl<S, D, I> Index<I> for ArrayBase<S, D>
43where
44 D: Dimension,
45 I: NdIndex<D>,
46 S: Data,
47{
48 type Output = S::Elem;
49 #[inline]
50 fn index(&self, index: I) -> &S::Elem {
51 debug_bounds_check!(self, index);
52 unsafe {
53 &*self.ptr.as_ptr().offset(
54 index
55 .index_checked(&self.dim, &self.strides)
56 .unwrap_or_else(|| array_out_of_bounds()),
57 )
58 }
59 }
60}
61
62impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
66where
67 D: Dimension,
68 I: NdIndex<D>,
69 S: DataMut,
70{
71 #[inline]
72 fn index_mut(&mut self, index: I) -> &mut S::Elem {
73 debug_bounds_check!(self, index);
74 unsafe {
75 &mut *self.as_mut_ptr().offset(
76 index
77 .index_checked(&self.dim, &self.strides)
78 .unwrap_or_else(|| array_out_of_bounds()),
79 )
80 }
81 }
82}
83
84impl<A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
87where
88 A: PartialEq<B>,
89 S: Data<Elem = A>,
90 S2: Data<Elem = B>,
91 D: Dimension,
92{
93 fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
94 if self.shape() != rhs.shape() {
95 return false;
96 }
97 if let Some(self_s) = self.as_slice() {
98 if let Some(rhs_s) = rhs.as_slice() {
99 return numeric_util::unrolled_eq(self_s, rhs_s);
100 }
101 }
102 Zip::from(self)
103 .and(rhs)
104 .fold_while(true, |_, a, b| {
105 if a != b {
106 FoldWhile::Done(false)
107 } else {
108 FoldWhile::Continue(true)
109 }
110 })
111 .into_inner()
112 }
113}
114
115impl<'a, A, B, S, S2, D> PartialEq<&'a ArrayBase<S2, D>> for ArrayBase<S, D>
118where
119 A: PartialEq<B>,
120 S: Data<Elem = A>,
121 S2: Data<Elem = B>,
122 D: Dimension,
123{
124 fn eq(&self, rhs: &&ArrayBase<S2, D>) -> bool {
125 *self == **rhs
126 }
127}
128
129impl<'a, A, B, S, S2, D> PartialEq<ArrayBase<S2, D>> for &'a 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 **self == *rhs
140 }
141}
142
143impl<S, D> Eq for ArrayBase<S, D>
144where
145 D: Dimension,
146 S: Data,
147 S::Elem: Eq,
148{
149}
150
151impl<A, S> From<Vec<A>> for ArrayBase<S, Ix1>
152where
153 S: DataOwned<Elem = A>,
154{
155 fn from(v: Vec<A>) -> Self {
165 Self::from_vec(v)
166 }
167}
168
169impl<A, S> FromIterator<A> for ArrayBase<S, Ix1>
170where
171 S: DataOwned<Elem = A>,
172{
173 fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix1>
186 where
187 I: IntoIterator<Item = A>,
188 {
189 Self::from_iter(iterable)
190 }
191}
192
193impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
194where
195 D: Dimension,
196 S: Data,
197{
198 type Item = &'a S::Elem;
199 type IntoIter = Iter<'a, S::Elem, D>;
200
201 fn into_iter(self) -> Self::IntoIter {
202 self.iter()
203 }
204}
205
206impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
207where
208 D: Dimension,
209 S: DataMut,
210{
211 type Item = &'a mut S::Elem;
212 type IntoIter = IterMut<'a, S::Elem, D>;
213
214 fn into_iter(self) -> Self::IntoIter {
215 self.iter_mut()
216 }
217}
218
219impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
220where
221 D: Dimension,
222{
223 type Item = &'a A;
224 type IntoIter = Iter<'a, A, D>;
225
226 fn into_iter(self) -> Self::IntoIter {
227 self.into_iter_()
228 }
229}
230
231impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
232where
233 D: Dimension,
234{
235 type Item = &'a mut A;
236 type IntoIter = IterMut<'a, A, D>;
237
238 fn into_iter(self) -> Self::IntoIter {
239 self.into_iter_()
240 }
241}
242
243impl<'a, S, D> hash::Hash for ArrayBase<S, D>
244where
245 D: Dimension,
246 S: Data,
247 S::Elem: hash::Hash,
248{
249 fn hash<H: hash::Hasher>(&self, state: &mut H) {
251 self.shape().hash(state);
252 if let Some(self_s) = self.as_slice() {
253 hash::Hash::hash_slice(self_s, state);
254 } else {
255 for row in self.inner_rows() {
256 if let Some(row_s) = row.as_slice() {
257 hash::Hash::hash_slice(row_s, state);
258 } else {
259 for elt in row {
260 elt.hash(state)
261 }
262 }
263 }
264 }
265 }
266}
267
268unsafe impl<S, D> Sync for ArrayBase<S, D>
275where
276 S: Sync + Data,
277 D: Sync,
278{
279}
280
281unsafe impl<S, D> Send for ArrayBase<S, D>
283where
284 S: Send + Data,
285 D: Send,
286{
287}
288
289#[cfg(any(feature = "serde"))]
290pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
292
293impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayView<'a, A, Ix1>
296where
297 Slice: AsRef<[A]>,
298{
299 fn from(slice: &'a Slice) -> Self {
303 let xs = slice.as_ref();
304 if mem::size_of::<A>() == 0 {
305 assert!(
306 xs.len() <= ::std::isize::MAX as usize,
307 "Slice length must fit in `isize`.",
308 );
309 }
310 unsafe { Self::from_shape_ptr(xs.len(), xs.as_ptr()) }
311 }
312}
313
314impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayView<'a, A, D>
316where
317 S: Data<Elem = A>,
318 D: Dimension,
319{
320 fn from(array: &'a ArrayBase<S, D>) -> Self {
322 array.view()
323 }
324}
325
326impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayViewMut<'a, A, Ix1>
328where
329 Slice: AsMut<[A]>,
330{
331 fn from(slice: &'a mut Slice) -> Self {
335 let xs = slice.as_mut();
336 if mem::size_of::<A>() == 0 {
337 assert!(
338 xs.len() <= ::std::isize::MAX as usize,
339 "Slice length must fit in `isize`.",
340 );
341 }
342 unsafe { Self::from_shape_ptr(xs.len(), xs.as_mut_ptr()) }
343 }
344}
345
346impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayViewMut<'a, A, D>
348where
349 S: DataMut<Elem = A>,
350 D: Dimension,
351{
352 fn from(array: &'a mut ArrayBase<S, D>) -> Self {
354 array.view_mut()
355 }
356}
357
358pub trait AsArray<'a, A: 'a, D = Ix1>: Into<ArrayView<'a, A, D>>
380where
381 D: Dimension,
382{
383}
384impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
385where
386 T: Into<ArrayView<'a, A, D>>,
387 D: Dimension,
388{
389}
390
391impl<A, S, D> Default for ArrayBase<S, D>
404where
405 S: DataOwned<Elem = A>,
406 D: Dimension,
407 A: Default,
408{
409 fn default() -> Self {
412 ArrayBase::default(D::default())
413 }
414}