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 fn insert_axis(&self, axis: Axis) -> Self::Larger {
383 debug_assert!(axis.index() <= $n);
384 let mut out = [1; $n + 1];
385 out[0..axis.index()].copy_from_slice(&self.slice()[0..axis.index()]);
386 out[axis.index()+1..=$n].copy_from_slice(&self.slice()[axis.index()..$n]);
387 Dim(out)
388 }
389 );
390);
391
392impl Dimension for Dim<[Ix; 0]> {
393 const NDIM: Option<usize> = Some(0);
394 type Pattern = ();
395 type Smaller = Self;
396 type Larger = Ix1;
397 #[inline]
399 fn ndim(&self) -> usize {
400 0
401 }
402 #[inline]
403 fn slice(&self) -> &[Ix] {
404 &[]
405 }
406 #[inline]
407 fn slice_mut(&mut self) -> &mut [Ix] {
408 &mut []
409 }
410 #[inline]
411 fn _fastest_varying_stride_order(&self) -> Self {
412 Ix0()
413 }
414 #[inline]
415 fn into_pattern(self) -> Self::Pattern {}
416 #[inline]
417 fn zeros(ndim: usize) -> Self {
418 assert_eq!(ndim, 0);
419 Self::default()
420 }
421 #[inline]
422 fn next_for(&self, _index: Self) -> Option<Self> {
423 None
424 }
425 #[inline]
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 #[inline]
534 impl_insert_axis_array!(1);
535 #[inline]
536 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
537 self.remove_axis(axis)
538 }
539
540 fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self> {
541 if 1 == d.ndim() {
542 Some(Ix1(d[0]))
543 } else {
544 None
545 }
546 }
547 private_impl! {}
548}
549
550impl Dimension for Dim<[Ix; 2]> {
551 const NDIM: Option<usize> = Some(2);
552 type Pattern = (Ix, Ix);
553 type Smaller = Ix1;
554 type Larger = Ix3;
555 #[inline]
556 fn ndim(&self) -> usize {
557 2
558 }
559 #[inline]
560 fn into_pattern(self) -> Self::Pattern {
561 self.ix().convert()
562 }
563 #[inline]
564 fn slice(&self) -> &[Ix] {
565 self.ix()
566 }
567 #[inline]
568 fn slice_mut(&mut self) -> &mut [Ix] {
569 self.ixm()
570 }
571 #[inline]
572 fn zeros(ndim: usize) -> Self {
573 assert_eq!(ndim, 2);
574 Self::default()
575 }
576 #[inline]
577 fn next_for(&self, index: Self) -> Option<Self> {
578 let mut i = get!(&index, 0);
579 let mut j = get!(&index, 1);
580 let imax = get!(self, 0);
581 let jmax = get!(self, 1);
582 j += 1;
583 if j >= jmax {
584 j = 0;
585 i += 1;
586 if i >= imax {
587 return None;
588 }
589 }
590 Some(Ix2(i, j))
591 }
592
593 #[inline]
594 fn equal(&self, rhs: &Self) -> bool {
595 get!(self, 0) == get!(rhs, 0) && get!(self, 1) == get!(rhs, 1)
596 }
597
598 #[inline]
599 fn size(&self) -> usize {
600 get!(self, 0) * get!(self, 1)
601 }
602
603 #[inline]
604 fn size_checked(&self) -> Option<usize> {
605 let m = get!(self, 0);
606 let n = get!(self, 1);
607 (m as usize).checked_mul(n as usize)
608 }
609
610 #[inline]
611 fn last_elem(&self) -> usize {
612 get!(self, 1)
613 }
614
615 #[inline]
616 fn set_last_elem(&mut self, i: usize) {
617 getm!(self, 1) = i;
618 }
619
620 #[inline]
621 fn default_strides(&self) -> Self {
622 let m = get!(self, 0);
623 let n = get!(self, 1);
624 if m == 0 || n == 0 {
625 Ix2(0, 0)
626 } else {
627 Ix2(n, 1)
628 }
629 }
630 #[inline]
631 fn fortran_strides(&self) -> Self {
632 let m = get!(self, 0);
633 let n = get!(self, 1);
634 if m == 0 || n == 0 {
635 Ix2(0, 0)
636 } else {
637 Ix2(1, m)
638 }
639 }
640
641 #[inline]
642 fn _fastest_varying_stride_order(&self) -> Self {
643 if (get!(self, 0) as Ixs).abs() <= (get!(self, 1) as Ixs).abs() {
644 Ix2(0, 1)
645 } else {
646 Ix2(1, 0)
647 }
648 }
649
650 #[inline]
651 fn min_stride_axis(&self, strides: &Self) -> Axis {
652 let s = get!(strides, 0) as Ixs;
653 let t = get!(strides, 1) as Ixs;
654 if s.abs() < t.abs() {
655 Axis(0)
656 } else {
657 Axis(1)
658 }
659 }
660
661 #[inline]
662 fn first_index(&self) -> Option<Self> {
663 let m = get!(self, 0);
664 let n = get!(self, 1);
665 if m != 0 && n != 0 {
666 Some(Ix2(0, 0))
667 } else {
668 None
669 }
670 }
671
672 #[inline(always)]
674 fn stride_offset(index: &Self, strides: &Self) -> isize {
675 let i = get!(index, 0);
676 let j = get!(index, 1);
677 let s = get!(strides, 0);
678 let t = get!(strides, 1);
679 stride_offset(i, s) + stride_offset(j, t)
680 }
681
682 #[inline]
684 fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize> {
685 let m = get!(self, 0);
686 let n = get!(self, 1);
687 let i = get!(index, 0);
688 let j = get!(index, 1);
689 let s = get!(strides, 0);
690 let t = get!(strides, 1);
691 if i < m && j < n {
692 Some(stride_offset(i, s) + stride_offset(j, t))
693 } else {
694 None
695 }
696 }
697 #[inline]
698 impl_insert_axis_array!(2);
699 #[inline]
700 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
701 self.remove_axis(axis)
702 }
703 private_impl! {}
704}
705
706impl Dimension for Dim<[Ix; 3]> {
707 const NDIM: Option<usize> = Some(3);
708 type Pattern = (Ix, Ix, Ix);
709 type Smaller = Ix2;
710 type Larger = Ix4;
711 #[inline]
712 fn ndim(&self) -> usize {
713 3
714 }
715 #[inline]
716 fn into_pattern(self) -> Self::Pattern {
717 self.ix().convert()
718 }
719 #[inline]
720 fn slice(&self) -> &[Ix] {
721 self.ix()
722 }
723 #[inline]
724 fn slice_mut(&mut self) -> &mut [Ix] {
725 self.ixm()
726 }
727
728 #[inline]
729 fn size(&self) -> usize {
730 let m = get!(self, 0);
731 let n = get!(self, 1);
732 let o = get!(self, 2);
733 m as usize * n as usize * o as usize
734 }
735
736 #[inline]
737 fn zeros(ndim: usize) -> Self {
738 assert_eq!(ndim, 3);
739 Self::default()
740 }
741
742 #[inline]
743 fn next_for(&self, index: Self) -> Option<Self> {
744 let mut i = get!(&index, 0);
745 let mut j = get!(&index, 1);
746 let mut k = get!(&index, 2);
747 let imax = get!(self, 0);
748 let jmax = get!(self, 1);
749 let kmax = get!(self, 2);
750 k += 1;
751 if k == kmax {
752 k = 0;
753 j += 1;
754 if j == jmax {
755 j = 0;
756 i += 1;
757 if i == imax {
758 return None;
759 }
760 }
761 }
762 Some(Ix3(i, j, k))
763 }
764
765 #[inline]
767 fn stride_offset(index: &Self, strides: &Self) -> isize {
768 let i = get!(index, 0);
769 let j = get!(index, 1);
770 let k = get!(index, 2);
771 let s = get!(strides, 0);
772 let t = get!(strides, 1);
773 let u = get!(strides, 2);
774 stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u)
775 }
776
777 #[inline]
779 fn stride_offset_checked(&self, strides: &Self, index: &Self) -> Option<isize> {
780 let m = get!(self, 0);
781 let n = get!(self, 1);
782 let l = get!(self, 2);
783 let i = get!(index, 0);
784 let j = get!(index, 1);
785 let k = get!(index, 2);
786 let s = get!(strides, 0);
787 let t = get!(strides, 1);
788 let u = get!(strides, 2);
789 if i < m && j < n && k < l {
790 Some(stride_offset(i, s) + stride_offset(j, t) + stride_offset(k, u))
791 } else {
792 None
793 }
794 }
795
796 #[inline]
797 fn _fastest_varying_stride_order(&self) -> Self {
798 let mut stride = *self;
799 let mut order = Ix3(0, 1, 2);
800 macro_rules! swap {
801 ($stride:expr, $order:expr, $x:expr, $y:expr) => {
802 if ($stride[$x] as isize).abs() > ($stride[$y] as isize).abs() {
803 $stride.swap($x, $y);
804 $order.ixm().swap($x, $y);
805 }
806 };
807 }
808 {
809 let strides = stride.slice_mut();
811 swap![strides, order, 1, 2];
812 swap![strides, order, 0, 1];
813 swap![strides, order, 1, 2];
814 }
815 order
816 }
817 #[inline]
818 impl_insert_axis_array!(3);
819 #[inline]
820 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
821 self.remove_axis(axis)
822 }
823 private_impl! {}
824}
825
826macro_rules! large_dim {
827 ($n:expr, $name:ident, $pattern:ty, $larger:ty, { $($insert_axis:tt)* }) => (
828 impl Dimension for Dim<[Ix; $n]> {
829 const NDIM: Option<usize> = Some($n);
830 type Pattern = $pattern;
831 type Smaller = Dim<[Ix; $n - 1]>;
832 type Larger = $larger;
833 #[inline]
834 fn ndim(&self) -> usize { $n }
835 #[inline]
836 fn into_pattern(self) -> Self::Pattern {
837 self.ix().convert()
838 }
839 #[inline]
840 fn slice(&self) -> &[Ix] { self.ix() }
841 #[inline]
842 fn slice_mut(&mut self) -> &mut [Ix] { self.ixm() }
843 #[inline]
844 fn zeros(ndim: usize) -> Self {
845 assert_eq!(ndim, $n);
846 Self::default()
847 }
848 #[inline]
849 $($insert_axis)*
850 #[inline]
851 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
852 self.remove_axis(axis)
853 }
854 private_impl!{}
855 }
856 )
857}
858
859large_dim!(4, Ix4, (Ix, Ix, Ix, Ix), Ix5, {
860 impl_insert_axis_array!(4);
861});
862large_dim!(5, Ix5, (Ix, Ix, Ix, Ix, Ix), Ix6, {
863 impl_insert_axis_array!(5);
864});
865large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
866 fn insert_axis(&self, axis: Axis) -> Self::Larger {
867 debug_assert!(axis.index() <= self.ndim());
868 let mut out = Vec::with_capacity(self.ndim() + 1);
869 out.extend_from_slice(&self.slice()[0..axis.index()]);
870 out.push(1);
871 out.extend_from_slice(&self.slice()[axis.index()..self.ndim()]);
872 Dim(out)
873 }
874});
875
876impl Dimension for IxDyn {
879 const NDIM: Option<usize> = None;
880 type Pattern = Self;
881 type Smaller = Self;
882 type Larger = Self;
883 #[inline]
884 fn ndim(&self) -> usize {
885 self.ix().len()
886 }
887 #[inline]
888 fn slice(&self) -> &[Ix] {
889 self.ix()
890 }
891 #[inline]
892 fn slice_mut(&mut self) -> &mut [Ix] {
893 self.ixm()
894 }
895 #[inline]
896 fn into_pattern(self) -> Self::Pattern {
897 self
898 }
899
900 #[inline]
901 fn zeros(ndim: usize) -> Self {
902 IxDyn::zeros(ndim)
903 }
904
905 #[inline]
906 fn insert_axis(&self, axis: Axis) -> Self::Larger {
907 debug_assert!(axis.index() <= self.ndim());
908 Dim::new(self.ix().insert(axis.index()))
909 }
910
911 #[inline]
912 fn try_remove_axis(&self, axis: Axis) -> Self::Smaller {
913 if self.ndim() > 0 {
914 self.remove_axis(axis)
915 } else {
916 self.clone()
917 }
918 }
919
920 fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self> {
921 Some(IxDyn(d.slice()))
922 }
923
924 fn into_dyn(self) -> IxDyn {
925 self
926 }
927
928 private_impl! {}
929}
930
931impl Index<usize> for Dim<IxDynImpl> {
932 type Output = <IxDynImpl as Index<usize>>::Output;
933 fn index(&self, index: usize) -> &Self::Output {
934 &self.ix()[index]
935 }
936}
937
938impl IndexMut<usize> for Dim<IxDynImpl> {
939 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
940 &mut self.ixm()[index]
941 }
942}