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