Thanks to visit codestin.com
Credit goes to docs.rs

ndarray/dimension/
conversion.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Tuple to array conversion, IntoDimension, and related things
10
11#[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
18/// $m: macro callback
19/// $m is called with $arg and then the indices corresponding to the size argument
20macro_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
42/// Argument conversion a dimension.
43pub trait IntoDimension
44{
45    /// The concrete type of the resultant dimension.
46    type Dim: Dimension;
47
48    /// Convert into a type that implements [`Dimension`].
49    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);