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;
46 fn into_dimension(self) -> Self::Dim;
47}
48
49impl IntoDimension for Ix
50{
51 type Dim = Ix1;
52 #[inline(always)]
53 fn into_dimension(self) -> Ix1
54 {
55 Ix1(self)
56 }
57}
58
59impl<D> IntoDimension for D
60where D: Dimension
61{
62 type Dim = D;
63 #[inline(always)]
64 fn into_dimension(self) -> Self
65 {
66 self
67 }
68}
69
70impl IntoDimension for IxDynImpl
71{
72 type Dim = IxDyn;
73 #[inline(always)]
74 fn into_dimension(self) -> Self::Dim
75 {
76 Dim::new(self)
77 }
78}
79
80impl IntoDimension for Vec<Ix>
81{
82 type Dim = IxDyn;
83 #[inline(always)]
84 fn into_dimension(self) -> Self::Dim
85 {
86 Dim::new(IxDynImpl::from(self))
87 }
88}
89
90pub trait Convert
91{
92 type To;
93 fn convert(self) -> Self::To;
94}
95
96macro_rules! sub {
97 ($_x:tt $y:tt) => {
98 $y
99 };
100}
101
102macro_rules! tuple_type {
103 ([$T:ident] $($index:tt)*) => (
104 ( $(sub!($index $T), )* )
105 );
106}
107
108macro_rules! tuple_expr {
109 ([$self_:expr] $($index:tt)*) => (
110 ( $($self_[$index], )* )
111 );
112}
113
114macro_rules! array_expr {
115 ([$self_:expr] $($index:tt)*) => (
116 [$($self_ . $index, )*]
117 );
118}
119
120macro_rules! array_zero {
121 ([] $($index:tt)*) => (
122 [$(sub!($index 0), )*]
123 );
124}
125
126macro_rules! tuple_to_array {
127 ([] $($n:tt)*) => {
128 $(
129 impl Convert for [Ix; $n] {
130 type To = index!(tuple_type [Ix] $n);
131 #[inline]
132 fn convert(self) -> Self::To {
133 index!(tuple_expr [self] $n)
134 }
135 }
136
137 impl IntoDimension for [Ix; $n] {
138 type Dim = Dim<[Ix; $n]>;
139 #[inline(always)]
140 fn into_dimension(self) -> Self::Dim {
141 Dim::new(self)
142 }
143 }
144
145 impl IntoDimension for index!(tuple_type [Ix] $n) {
146 type Dim = Dim<[Ix; $n]>;
147 #[inline(always)]
148 fn into_dimension(self) -> Self::Dim {
149 Dim::new(index!(array_expr [self] $n))
150 }
151 }
152
153 impl Index<usize> for Dim<[Ix; $n]> {
154 type Output = usize;
155 #[inline(always)]
156 fn index(&self, index: usize) -> &Self::Output {
157 &self.ix()[index]
158 }
159 }
160
161 impl IndexMut<usize> for Dim<[Ix; $n]> {
162 #[inline(always)]
163 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
164 &mut self.ixm()[index]
165 }
166 }
167
168 impl Zero for Dim<[Ix; $n]> {
169 #[inline]
170 fn zero() -> Self {
171 Dim::new(index!(array_zero [] $n))
172 }
173 fn is_zero(&self) -> bool {
174 self.slice().iter().all(|x| *x == 0)
175 }
176 }
177
178 )*
179 };
180}
181
182index_item!(tuple_to_array [] 7);