1#[cfg(not(feature = "std"))]
10use alloc::vec::Vec;
11use std::fmt::Debug;
12use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
13use std::ops::{Index, IndexMut};
14
15use super::axes_of;
16use super::conversion::Convert;
17use super::ops::DimAdd;
18use super::{stride_offset, stride_offset_checked};
19use crate::itertools::{enumerate, zip};
20use crate::IntoDimension;
21use crate::RemoveAxis;
22use crate::{ArrayView1, ArrayViewMut1};
23use crate::{Axis, DimMax};
24use crate::{Dim, Ix, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, IxDynImpl, Ixs};
25
26pub trait Dimension:
33 Clone
34 + Eq
35 + Debug
36 + Send
37 + Sync
38 + Default
39 + IndexMut<usize, Output = usize>
40 + Add<Self, Output = Self>
41 + AddAssign
42 + for<'x> AddAssign<&'x Self>
43 + Sub<Self, Output = Self>
44 + SubAssign
45 + for<'x> SubAssign<&'x Self>
46 + Mul<usize, Output = Self>
47 + Mul<Self, Output = Self>
48 + MulAssign
49 + for<'x> MulAssign<&'x Self>
50 + MulAssign<usize>
51 + DimMax<Ix0, Output = Self>
52 + DimMax<Self, Output = Self>
53 + DimMax<IxDyn, Output = IxDyn>
54 + DimMax<<Self as Dimension>::Smaller, Output = Self>
55 + DimMax<<Self as Dimension>::Larger, Output = <Self as Dimension>::Larger>
56 + DimAdd<Self>
57 + DimAdd<<Self as Dimension>::Smaller>
58 + DimAdd<<Self as Dimension>::Larger>
59 + DimAdd<Ix0, Output = Self>
60 + DimAdd<Ix1, Output = <Self as Dimension>::Larger>
61 + DimAdd<IxDyn, Output = IxDyn>
62{
63 const NDIM: Option<usize>;
67 type Pattern: IntoDimension<Dim = Self> + Clone + Debug + PartialEq + Eq + Default;
74 type Smaller: Dimension;
76 type Larger: Dimension + RemoveAxis;
78
79 fn ndim(&self) -> usize;
81
82 fn into_pattern(self) -> Self::Pattern;
84
85 fn size(&self) -> usize
87 {
88 self.slice().iter().product()
89 }
90
91 fn size_checked(&self) -> Option<usize>
93 {
94 self.slice()
95 .iter()
96 .try_fold(1_usize, |s, &a| s.checked_mul(a))
97 }
98
99 #[doc(hidden)]
100 fn slice(&self) -> &[Ix];
101
102 #[doc(hidden)]
103 fn slice_mut(&mut self) -> &mut [Ix];
104
105 fn as_array_view(&self) -> ArrayView1<'_, Ix>
107 {
108 ArrayView1::from(self.slice())
109 }
110
111 fn as_array_view_mut(&mut self) -> ArrayViewMut1<'_, Ix>
113 {
114 ArrayViewMut1::from(self.slice_mut())
115 }
116
117 #[doc(hidden)]
118 fn equal(&self, rhs: &Self) -> bool
119 {
120 self.slice() == rhs.slice()
121 }
122
123 #[doc(hidden)]
128 fn default_strides(&self) -> Self
129 {
130 let mut strides = Self::zeros(self.ndim());
133 if self.slice().iter().all(|&d| d != 0) {
135 let mut it = strides.slice_mut().iter_mut().rev();
136 if let Some(rs) = it.next() {
138 *rs = 1;
139 }
140 let mut cum_prod = 1;
141 for (rs, dim) in it.zip(self.slice().iter().rev()) {
142 cum_prod *= *dim;
143 *rs = cum_prod;
144 }
145 }
146 strides
147 }
148
149 #[doc(hidden)]
154 fn fortran_strides(&self) -> Self
155 {
156 let mut strides = Self::zeros(self.ndim());
159 if self.slice().iter().all(|&d| d != 0) {
161 let mut it = strides.slice_mut().iter_mut();
162 if let Some(rs) = it.next() {
164 *rs = 1;
165 }
166 let mut cum_prod = 1;
167 for (rs, dim) in it.zip(self.slice()) {
168 cum_prod *= *dim;
169 *rs = cum_prod;
170 }
171 }
172 strides
173 }
174
175 fn zeros(ndim: usize) -> Self;
182
183 #[doc(hidden)]
184 #[inline]
185 fn first_index(&self) -> Option<Self>
186 {
187 for ax in self.slice().iter() {
188 if *ax == 0 {
189 return None;
190 }
191 }
192 Some(Self::zeros(self.ndim()))
193 }
194
195 #[doc(hidden)]
196 #[inline]
200 fn next_for(&self, index: Self) -> Option<Self>
201 {
202 let mut index = index;
203 let mut done = false;
204 for (&dim, ix) in zip(self.slice(), index.slice_mut()).rev() {
205 *ix += 1;
206 if *ix == dim {
207 *ix = 0;
208 } else {
209 done = true;
210 break;
211 }
212 }
213 if done {
214 Some(index)
215 } else {
216 None
217 }
218 }
219
220 #[doc(hidden)]
221 #[inline]
226 fn next_for_f(&self, index: &mut Self) -> bool
227 {
228 let mut end_iteration = true;
229 for (&dim, ix) in zip(self.slice(), index.slice_mut()) {
230 *ix += 1;
231 if *ix == dim {
232 *ix = 0;
233 } else {
234 end_iteration = false;
235 break;
236 }
237 }
238 !end_iteration
239 }
240
241 #[doc(hidden)]
249 fn strides_equivalent<D>(&self, strides1: &Self, strides2: &D) -> bool
250 where D: Dimension
251 {
252 let shape_ndim = self.ndim();
253 shape_ndim == strides1.ndim()
254 && shape_ndim == strides2.ndim()
255 && izip!(self.slice(), strides1.slice(), strides2.slice())
256 .all(|(&d, &s1, &s2)| d <= 1 || s1 as isize == s2 as isize)
257 }
258
259 #[doc(hidden)]
260 fn stride_offset(index: &Self, strides: &Self) -> isize
262 {
263 let mut offset = 0;
264 for (&i, &s) in izip!(index.slice(), strides.slice()) {
265 offset += stride_offset(i, s);
266 }
267 offset
268 }
269
270 #[doc(hidden)]
271 fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize>
273 {
274 stride_offset_checked(self.slice(), strides.slice(), index.slice())
275 }
276
277 #[doc(hidden)]
278 fn last_elem(&self) -> usize
279 {
280 if self.ndim() == 0 {
281 0
282 } else {
283 self.slice()[self.ndim() - 1]
284 }
285 }
286
287 #[doc(hidden)]
288 fn set_last_elem(&mut self, i: usize)
289 {
290 let nd = self.ndim();
291 self.slice_mut()[nd - 1] = i;
292 }
293
294 #[doc(hidden)]
295 fn is_contiguous(dim: &Self, strides: &Self) -> bool
296 {
297 let defaults = dim.default_strides();
298 if strides.equal(&defaults) {
299 return true;
300 }
301 if dim.ndim() == 1 {
302 dim[0] <= 1 || strides[0] as isize == -1
306 } else {
307 let order = strides._fastest_varying_stride_order();
308 let strides = strides.slice();
309
310 let dim_slice = dim.slice();
311 let mut cstride = 1;
312 for &i in order.slice() {
313 if dim_slice[i] != 1 && (strides[i] as isize).unsigned_abs() != cstride {
315 return false;
316 }
317 cstride *= dim_slice[i];
318 }
319 true
320 }
321 }
322
323 #[doc(hidden)]
328 fn _fastest_varying_stride_order(&self) -> Self
329 {
330 let mut indices = self.clone();
331 for (i, elt) in enumerate(indices.slice_mut()) {
332 *elt = i;
333 }
334 let strides = self.slice();
335 indices
336 .slice_mut()
337 .sort_by_key(|&i| (strides[i] as isize).abs());
338 indices
339 }
340
341 #[doc(hidden)]
344 fn min_stride_axis(&self, strides: &Self) -> Axis
345 {
346 let n = match self.ndim() {
347 0 => panic!("min_stride_axis: Array must have ndim > 0"),
348 1 => return Axis(0),
349 n => n,
350 };
351 axes_of(self, strides)
352 .rev()
353 .min_by_key(|ax| ax.stride.abs())
354 .map_or(Axis(n - 1), |ax| ax.axis)
355 }
356
357 #[doc(hidden)]
360 fn max_stride_axis(&self, strides: &Self) -> Axis
361 {
362 match self.ndim() {
363 0 => panic!("max_stride_axis: Array must have ndim > 0"),
364 1 => return Axis(0),
365 _ => {}
366 }
367 axes_of(self, strides)
368 .filter(|ax| ax.len > 1)
369 .max_by_key(|ax| ax.stride.abs())
370 .map_or(Axis(0), |ax| ax.axis)
371 }
372
373 fn into_dyn(self) -> IxDyn
375 {
376 IxDyn(self.slice())
377 }
378
379 #[doc(hidden)]
380 fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
381 {
382 let mut s = Self::default();
383 if s.ndim() == d.ndim() {
384 for i in 0..d.ndim() {
385 s[i] = d[i];
386 }
387 Some(s)
388 } else {
389 None
390 }
391 }
392
393 #[doc(hidden)]
394 fn insert_axis(&self, axis: Axis) -> Self::Larger;
395
396 #[doc(hidden)]
397 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller;
398
399 private_decl! {}
400}
401
402macro_rules! impl_insert_axis_array(
405 ($n:expr) => (
406 #[inline]
407 fn insert_axis(&self, axis: Axis) -> Self::Larger {
408 debug_assert!(axis.index() <= $n);
409 let mut out = [1; $n + 1];
410 out[0..axis.index()].copy_from_slice(&self.slice()[0..axis.index()]);
411 out[axis.index()+1..=$n].copy_from_slice(&self.slice()[axis.index()..$n]);
412 Dim(out)
413 }
414 );
415);
416
417impl Dimension for Dim<[Ix; 0]>
418{
419 const NDIM: Option<usize> = Some(0);
420 type Pattern = ();
421 type Smaller = Self;
422 type Larger = Ix1;
423 #[inline]
425 fn ndim(&self) -> usize
426 {
427 0
428 }
429 #[inline]
430 fn slice(&self) -> &[Ix]
431 {
432 &[]
433 }
434 #[inline]
435 fn slice_mut(&mut self) -> &mut [Ix]
436 {
437 &mut []
438 }
439 #[inline]
440 fn _fastest_varying_stride_order(&self) -> Self
441 {
442 Ix0()
443 }
444 #[inline]
445 fn into_pattern(self) -> Self::Pattern {}
446 #[inline]
447 fn zeros(ndim: usize) -> Self
448 {
449 assert_eq!(ndim, 0);
450 Self::default()
451 }
452 #[inline]
453 fn next_for(&self, _index: Self) -> Option<Self>
454 {
455 None
456 }
457 impl_insert_axis_array!(0);
458 #[inline]
459 fn try_remove_axis(&self, _ignore: Axis) -> Self::Smaller
460 {
461 *self
462 }
463
464 private_impl! {}
465}
466
467impl Dimension for Dim<[Ix; 1]>
468{
469 const NDIM: Option<usize> = Some(1);
470 type Pattern = Ix;
471 type Smaller = Ix0;
472 type Larger = Ix2;
473 #[inline]
474 fn ndim(&self) -> usize
475 {
476 1
477 }
478 #[inline]
479 fn slice(&self) -> &[Ix]
480 {
481 self.ix()
482 }
483 #[inline]
484 fn slice_mut(&mut self) -> &mut [Ix]
485 {
486 self.ixm()
487 }
488 #[inline]
489 fn into_pattern(self) -> Self::Pattern
490 {
491 get!(&self, 0)
492 }
493 #[inline]
494 fn zeros(ndim: usize) -> Self
495 {
496 assert_eq!(ndim, 1);
497 Self::default()
498 }
499 #[inline]
500 fn next_for(&self, mut index: Self) -> Option<Self>
501 {
502 getm!(index, 0) += 1;
503 if get!(&index, 0) < get!(self, 0) {
504 Some(index)
505 } else {
506 None
507 }
508 }
509
510 #[inline]
511 fn equal(&self, rhs: &Self) -> bool
512 {
513 get!(self, 0) == get!(rhs, 0)
514 }
515
516 #[inline]
517 fn size(&self) -> usize
518 {
519 get!(self, 0)
520 }
521 #[inline]
522 fn size_checked(&self) -> Option<usize>
523 {
524 Some(get!(self, 0))
525 }
526
527 #[inline]
528 fn default_strides(&self) -> Self
529 {
530 if get!(self, 0) == 0 {
531 Ix1(0)
532 } else {
533 Ix1(1)
534 }
535 }
536
537 #[inline]
538 fn _fastest_varying_stride_order(&self) -> Self
539 {
540 Ix1(0)
541 }
542
543 #[inline(always)]
544 fn min_stride_axis(&self, _: &Self) -> Axis
545 {
546 Axis(0)
547 }
548
549 #[inline(always)]
550 fn max_stride_axis(&self, _: &Self) -> Axis
551 {
552 Axis(0)
553 }
554
555 #[inline]
556 fn first_index(&self) -> Option<Self>
557 {
558 if get!(self, 0) != 0 {
559 Some(Ix1(0))
560 } else {
561 None
562 }
563 }
564
565 #[inline(always)]
567 fn stride_offset(index: &Self, stride: &Self) -> isize
568 {
569 stride_offset(get!(index, 0), get!(stride, 0))
570 }
571
572 #[inline]
574 fn stride_offset_checked(&self, stride: &Self, index: &Self) -> Option<isize>
575 {
576 if get!(index, 0) < get!(self, 0) {
577 Some(stride_offset(get!(index, 0), get!(stride, 0)))
578 } else {
579 None
580 }
581 }
582 impl_insert_axis_array!(1);
583 #[inline]
584 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller
585 {
586 self.remove_axis(axis)
587 }
588
589 fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
590 {
591 if 1 == d.ndim() {
592 Some(Ix1(d[0]))
593 } else {
594 None
595 }
596 }
597 private_impl! {}
598}
599
600impl Dimension for Dim<[Ix; 2]>
601{
602 const NDIM: Option<usize> = Some(2);
603 type Pattern = (Ix, Ix);
604 type Smaller = Ix1;
605 type Larger = Ix3;
606 #[inline]
607 fn ndim(&self) -> usize
608 {
609 2
610 }
611 #[inline]
612 fn into_pattern(self) -> Self::Pattern
613 {
614 self.ix().convert()
615 }
616 #[inline]
617 fn slice(&self) -> &[Ix]
618 {
619 self.ix()
620 }
621 #[inline]
622 fn slice_mut(&mut self) -> &mut [Ix]
623 {
624 self.ixm()
625 }
626 #[inline]
627 fn zeros(ndim: usize) -> Self
628 {
629 assert_eq!(ndim, 2);
630 Self::default()
631 }
632 #[inline]
633 fn next_for(&self, index: Self) -> Option<Self>
634 {
635 let mut i = get!(&index, 0);
636 let mut j = get!(&index, 1);
637 let imax = get!(self, 0);
638 let jmax = get!(self, 1);
639 j += 1;
640 if j >= jmax {
641 j = 0;
642 i += 1;
643 if i >= imax {
644 return None;
645 }
646 }
647 Some(Ix2(i, j))
648 }
649
650 #[inline]
651 fn equal(&self, rhs: &Self) -> bool
652 {
653 get!(self, 0) == get!(rhs, 0) && get!(self, 1) == get!(rhs, 1)
654 }
655
656 #[inline]
657 fn size(&self) -> usize
658 {
659 get!(self, 0) * get!(self, 1)
660 }
661
662 #[inline]
663 fn size_checked(&self) -> Option<usize>
664 {
665 let m = get!(self, 0);
666 let n = get!(self, 1);
667 m.checked_mul(n)
668 }
669
670 #[inline]
671 fn last_elem(&self) -> usize
672 {
673 get!(self, 1)
674 }
675
676 #[inline]
677 fn set_last_elem(&mut self, i: usize)
678 {
679 getm!(self, 1) = i;
680 }
681
682 #[inline]
683 fn default_strides(&self) -> Self
684 {
685 let m = get!(self, 0);
686 let n = get!(self, 1);
687 if m == 0 || n == 0 {
688 Ix2(0, 0)
689 } else {
690 Ix2(n, 1)
691 }
692 }
693 #[inline]
694 fn fortran_strides(&self) -> Self
695 {
696 let m = get!(self, 0);
697 let n = get!(self, 1);
698 if m == 0 || n == 0 {
699 Ix2(0, 0)
700 } else {
701 Ix2(1, m)
702 }
703 }
704
705 #[inline]
706 fn _fastest_varying_stride_order(&self) -> Self
707 {
708 if (get!(self, 0) as Ixs).abs() <= (get!(self, 1) as Ixs).abs() {
709 Ix2(0, 1)
710 } else {
711 Ix2(1, 0)
712 }
713 }
714
715 #[inline]
716 fn min_stride_axis(&self, strides: &Self) -> Axis
717 {
718 let s = get!(strides, 0) as Ixs;
719 let t = get!(strides, 1) as Ixs;
720 if s.abs() < t.abs() {
721 Axis(0)
722 } else {
723 Axis(1)
724 }
725 }
726
727 #[inline]
728 fn first_index(&self) -> Option<Self>
729 {
730 let m = get!(self, 0);
731 let n = get!(self, 1);
732 if m != 0 && n != 0 {
733 Some(Ix2(0, 0))
734 } else {
735 None
736 }
737 }
738
739 #[inline(always)]
741 fn stride_offset(index: &Self, strides: &Self) -> isize
742 {
743 let i = get!(index, 0);
744 let j = get!(index, 1);
745 let s = get!(strides, 0);
746 let t = get!(strides, 1);
747 stride_offset(i, s) + stride_offset(j, t)
748 }
749
750 #[inline]
752 fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize>
753 {
754 let m = get!(self, 0);
755 let n = get!(self, 1);
756 let i = get!(index, 0);
757 let j = get!(index, 1);
758 let s = get!(strides, 0);
759 let t = get!(strides, 1);
760 if i < m && j < n {
761 Some(stride_offset(i, s) + stride_offset(j, t))
762 } else {
763 None
764 }
765 }
766 impl_insert_axis_array!(2);
767 #[inline]
768 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller
769 {
770 self.remove_axis(axis)
771 }
772 private_impl! {}
773}
774
775impl Dimension for Dim<[Ix; 3]>
776{
777 const NDIM: Option<usize> = Some(3);
778 type Pattern = (Ix, Ix, Ix);
779 type Smaller = Ix2;
780 type Larger = Ix4;
781 #[inline]
782 fn ndim(&self) -> usize
783 {
784 3
785 }
786 #[inline]
787 fn into_pattern(self) -> Self::Pattern
788 {
789 self.ix().convert()
790 }
791 #[inline]
792 fn slice(&self) -> &[Ix]
793 {
794 self.ix()
795 }
796 #[inline]
797 fn slice_mut(&mut self) -> &mut [Ix]
798 {
799 self.ixm()
800 }
801
802 #[inline]
803 fn size(&self) -> usize
804 {
805 let m = get!(self, 0);
806 let n = get!(self, 1);
807 let o = get!(self, 2);
808 m * n * o
809 }
810
811 #[inline]
812 fn zeros(ndim: usize) -> Self
813 {
814 assert_eq!(ndim, 3);
815 Self::default()
816 }
817
818 #[inline]
819 fn next_for(&self, index: Self) -> Option<Self>
820 {
821 let mut i = get!(&index, 0);
822 let mut j = get!(&index, 1);
823 let mut k = get!(&index, 2);
824 let imax = get!(self, 0);
825 let jmax = get!(self, 1);
826 let kmax = get!(self, 2);
827 k += 1;
828 if k == kmax {
829 k = 0;
830 j += 1;
831 if j == jmax {
832 j = 0;
833 i += 1;
834 if i == imax {
835 return None;
836 }
837 }
838 }
839 Some(Ix3(i, j, k))
840 }
841
842 #[inline]
844 fn stride_offset(index: &Self, strides: &Self) -> isize
845 {
846 let i = get!(index, 0);
847 let j = get!(index, 1);
848 let k = get!(index, 2);
849 let s = get!(strides, 0);
850 let t = get!(strides, 1);
851 let u = get!(strides, 2);
852 stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u)
853 }
854
855 #[inline]
857 fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize>
858 {
859 let m = get!(self, 0);
860 let n = get!(self, 1);
861 let l = get!(self, 2);
862 let i = get!(index, 0);
863 let j = get!(index, 1);
864 let k = get!(index, 2);
865 let s = get!(strides, 0);
866 let t = get!(strides, 1);
867 let u = get!(strides, 2);
868 if i < m && j < n && k < l {
869 Some(stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u))
870 } else {
871 None
872 }
873 }
874
875 #[inline]
876 fn _fastest_varying_stride_order(&self) -> Self
877 {
878 let mut stride = *self;
879 let mut order = Ix3(0, 1, 2);
880 macro_rules! swap {
881 ($stride:expr, $order:expr, $x:expr, $y:expr) => {
882 if ($stride[$x] as isize).abs() > ($stride[$y] as isize).abs() {
883 $stride.swap($x, $y);
884 $order.ixm().swap($x, $y);
885 }
886 };
887 }
888 {
889 let strides = stride.slice_mut();
891 swap![strides, order, 1, 2];
892 swap![strides, order, 0, 1];
893 swap![strides, order, 1, 2];
894 }
895 order
896 }
897 impl_insert_axis_array!(3);
898 #[inline]
899 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller
900 {
901 self.remove_axis(axis)
902 }
903 private_impl! {}
904}
905
906macro_rules! large_dim {
907 ($n:expr, $name:ident, $pattern:ty, $larger:ty, { $($insert_axis:tt)* }) => (
908 impl Dimension for Dim<[Ix; $n]> {
909 const NDIM: Option<usize> = Some($n);
910 type Pattern = $pattern;
911 type Smaller = Dim<[Ix; $n - 1]>;
912 type Larger = $larger;
913 #[inline]
914 fn ndim(&self) -> usize { $n }
915 #[inline]
916 fn into_pattern(self) -> Self::Pattern {
917 self.ix().convert()
918 }
919 #[inline]
920 fn slice(&self) -> &[Ix] { self.ix() }
921 #[inline]
922 fn slice_mut(&mut self) -> &mut [Ix] { self.ixm() }
923 #[inline]
924 fn zeros(ndim: usize) -> Self {
925 assert_eq!(ndim, $n);
926 Self::default()
927 }
928 $($insert_axis)*
929 #[inline]
930 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
931 self.remove_axis(axis)
932 }
933 private_impl!{}
934 }
935 );
936}
937
938large_dim!(4, Ix4, (Ix, Ix, Ix, Ix), Ix5, {
939 impl_insert_axis_array!(4);
940});
941large_dim!(5, Ix5, (Ix, Ix, Ix, Ix, Ix), Ix6, {
942 impl_insert_axis_array!(5);
943});
944large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
945 fn insert_axis(&self, axis: Axis) -> Self::Larger {
946 debug_assert!(axis.index() <= self.ndim());
947 let mut out = Vec::with_capacity(self.ndim() + 1);
948 out.extend_from_slice(&self.slice()[0..axis.index()]);
949 out.push(1);
950 out.extend_from_slice(&self.slice()[axis.index()..self.ndim()]);
951 Dim(out)
952 }
953});
954
955impl Dimension for IxDyn
958{
959 const NDIM: Option<usize> = None;
960 type Pattern = Self;
961 type Smaller = Self;
962 type Larger = Self;
963 #[inline]
964 fn ndim(&self) -> usize
965 {
966 self.ix().len()
967 }
968 #[inline]
969 fn slice(&self) -> &[Ix]
970 {
971 self.ix()
972 }
973 #[inline]
974 fn slice_mut(&mut self) -> &mut [Ix]
975 {
976 self.ixm()
977 }
978 #[inline]
979 fn into_pattern(self) -> Self::Pattern
980 {
981 self
982 }
983
984 #[inline]
985 fn zeros(ndim: usize) -> Self
986 {
987 IxDyn::zeros(ndim)
988 }
989
990 #[inline]
991 fn insert_axis(&self, axis: Axis) -> Self::Larger
992 {
993 debug_assert!(axis.index() <= self.ndim());
994 Dim::new(self.ix().insert(axis.index()))
995 }
996
997 #[inline]
998 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller
999 {
1000 if self.ndim() > 0 {
1001 self.remove_axis(axis)
1002 } else {
1003 self.clone()
1004 }
1005 }
1006
1007 fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
1008 {
1009 Some(IxDyn(d.slice()))
1010 }
1011
1012 fn into_dyn(self) -> IxDyn
1013 {
1014 self
1015 }
1016
1017 private_impl! {}
1018}
1019
1020impl Index<usize> for Dim<IxDynImpl>
1021{
1022 type Output = <IxDynImpl as Index<usize>>::Output;
1023 fn index(&self, index: usize) -> &Self::Output
1024 {
1025 &self.ix()[index]
1026 }
1027}
1028
1029impl IndexMut<usize> for Dim<IxDynImpl>
1030{
1031 fn index_mut(&mut self, index: usize) -> &mut Self::Output
1032 {
1033 &mut self.ixm()[index]
1034 }
1035}