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