ndarray/dimension/
conversion.rs1use num_traits::Zero;
12use std::ops::{Index, IndexMut};
13use alloc::vec::Vec;
14
15use crate::{Dim, Dimension, Ix, Ix1, IxDyn, IxDynImpl};
16
17macro_rules! index {
20 ($m:ident $arg:tt 0) => ($m!($arg));
21 ($m:ident $arg:tt 1) => ($m!($arg 0));
22 ($m:ident $arg:tt 2) => ($m!($arg 0 1));
23 ($m:ident $arg:tt 3) => ($m!($arg 0 1 2));
24 ($m:ident $arg:tt 4) => ($m!($arg 0 1 2 3));
25 ($m:ident $arg:tt 5) => ($m!($arg 0 1 2 3 4));
26 ($m:ident $arg:tt 6) => ($m!($arg 0 1 2 3 4 5));
27 ($m:ident $arg:tt 7) => ($m!($arg 0 1 2 3 4 5 6));
28}
29
30macro_rules! index_item {
31 ($m:ident $arg:tt 0) => ();
32 ($m:ident $arg:tt 1) => ($m!($arg 0););
33 ($m:ident $arg:tt 2) => ($m!($arg 0 1););
34 ($m:ident $arg:tt 3) => ($m!($arg 0 1 2););
35 ($m:ident $arg:tt 4) => ($m!($arg 0 1 2 3););
36 ($m:ident $arg:tt 5) => ($m!($arg 0 1 2 3 4););
37 ($m:ident $arg:tt 6) => ($m!($arg 0 1 2 3 4 5););
38 ($m:ident $arg:tt 7) => ($m!($arg 0 1 2 3 4 5 6););
39}
40
41pub trait IntoDimension {
43 type Dim: Dimension;
44 fn into_dimension(self) -> Self::Dim;
45}
46
47impl IntoDimension for Ix {
48 type Dim = Ix1;
49 #[inline(always)]
50 fn into_dimension(self) -> Ix1 {
51 Ix1(self)
52 }
53}
54
55impl<D> IntoDimension for D
56where
57 D: Dimension,
58{
59 type Dim = D;
60 #[inline(always)]
61 fn into_dimension(self) -> Self {
62 self
63 }
64}
65
66impl IntoDimension for IxDynImpl {
67 type Dim = IxDyn;
68 #[inline(always)]
69 fn into_dimension(self) -> Self::Dim {
70 Dim::new(self)
71 }
72}
73
74impl IntoDimension for Vec<Ix> {
75 type Dim = IxDyn;
76 #[inline(always)]
77 fn into_dimension(self) -> Self::Dim {
78 Dim::new(IxDynImpl::from(self))
79 }
80}
81
82pub trait Convert {
83 type To;
84 fn convert(self) -> Self::To;
85}
86
87macro_rules! sub {
88 ($_x:tt $y:tt) => {
89 $y
90 };
91}
92
93macro_rules! tuple_type {
94 ([$T:ident] $($index:tt)*) => (
95 ( $(sub!($index $T), )* )
96 )
97}
98
99macro_rules! tuple_expr {
100 ([$self_:expr] $($index:tt)*) => (
101 ( $($self_[$index], )* )
102 )
103}
104
105macro_rules! array_expr {
106 ([$self_:expr] $($index:tt)*) => (
107 [$($self_ . $index, )*]
108 )
109}
110
111macro_rules! array_zero {
112 ([] $($index:tt)*) => (
113 [$(sub!($index 0), )*]
114 )
115}
116
117macro_rules! tuple_to_array {
118 ([] $($n:tt)*) => {
119 $(
120 impl Convert for [Ix; $n] {
121 type To = index!(tuple_type [Ix] $n);
122 #[inline]
123 fn convert(self) -> Self::To {
124 index!(tuple_expr [self] $n)
125 }
126 }
127
128 impl IntoDimension for [Ix; $n] {
129 type Dim = Dim<[Ix; $n]>;
130 #[inline(always)]
131 fn into_dimension(self) -> Self::Dim {
132 Dim::new(self)
133 }
134 }
135
136 impl IntoDimension for index!(tuple_type [Ix] $n) {
137 type Dim = Dim<[Ix; $n]>;
138 #[inline(always)]
139 fn into_dimension(self) -> Self::Dim {
140 Dim::new(index!(array_expr [self] $n))
141 }
142 }
143
144 impl Index<usize> for Dim<[Ix; $n]> {
145 type Output = usize;
146 #[inline(always)]
147 fn index(&self, index: usize) -> &Self::Output {
148 &self.ix()[index]
149 }
150 }
151
152 impl IndexMut<usize> for Dim<[Ix; $n]> {
153 #[inline(always)]
154 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
155 &mut self.ixm()[index]
156 }
157 }
158
159 impl Zero for Dim<[Ix; $n]> {
160 #[inline]
161 fn zero() -> Self {
162 Dim::new(index!(array_zero [] $n))
163 }
164 fn is_zero(&self) -> bool {
165 self.slice().iter().all(|x| *x == 0)
166 }
167 }
168
169 )*
170 }
171}
172
173index_item!(tuple_to_array [] 7);