/rust/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/shape_builder.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::dimension::IntoDimension; |
2 | | use crate::Dimension; |
3 | | use crate::order::Order; |
4 | | |
5 | | /// A contiguous array shape of n dimensions. |
6 | | /// |
7 | | /// Either c- or f- memory ordered (*c* a.k.a *row major* is the default). |
8 | | #[derive(Copy, Clone, Debug)] |
9 | | pub struct Shape<D> { |
10 | | /// Shape (axis lengths) |
11 | | pub(crate) dim: D, |
12 | | /// Strides can only be C or F here |
13 | | pub(crate) strides: Strides<Contiguous>, |
14 | | } |
15 | | |
16 | | #[derive(Copy, Clone, Debug)] |
17 | | pub(crate) enum Contiguous {} |
18 | | |
19 | | impl<D> Shape<D> { |
20 | 0 | pub(crate) fn is_c(&self) -> bool { |
21 | 0 | matches!(self.strides, Strides::C) |
22 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::Shape<ndarray::dimension::dim::Dim<[usize; 1]>>>::is_c Unexecuted instantiation: <ndarray::shape_builder::Shape<_>>::is_c |
23 | | } |
24 | | |
25 | | /// An array shape of n dimensions in c-order, f-order or custom strides. |
26 | | #[derive(Copy, Clone, Debug)] |
27 | | pub struct StrideShape<D> { |
28 | | pub(crate) dim: D, |
29 | | pub(crate) strides: Strides<D>, |
30 | | } |
31 | | |
32 | | impl<D> StrideShape<D> |
33 | | where |
34 | | D: Dimension, |
35 | | { |
36 | | /// Return a reference to the dimension |
37 | 0 | pub fn raw_dim(&self) -> &D { |
38 | 0 | &self.dim |
39 | 0 | } |
40 | | /// Return the size of the shape in number of elements |
41 | 0 | pub fn size(&self) -> usize { |
42 | 0 | self.dim.size() |
43 | 0 | } |
44 | | } |
45 | | |
46 | | /// Stride description |
47 | | #[derive(Copy, Clone, Debug)] |
48 | | pub(crate) enum Strides<D> { |
49 | | /// Row-major ("C"-order) |
50 | | C, |
51 | | /// Column-major ("F"-order) |
52 | | F, |
53 | | /// Custom strides |
54 | | Custom(D), |
55 | | } |
56 | | |
57 | | impl<D> Strides<D> { |
58 | | /// Return strides for `dim` (computed from dimension if c/f, else return the custom stride) |
59 | 0 | pub(crate) fn strides_for_dim(self, dim: &D) -> D |
60 | 0 | where |
61 | 0 | D: Dimension, |
62 | 0 | { |
63 | 0 | match self { |
64 | 0 | Strides::C => dim.default_strides(), |
65 | 0 | Strides::F => dim.fortran_strides(), |
66 | 0 | Strides::Custom(c) => { |
67 | 0 | debug_assert_eq!( |
68 | 0 | c.ndim(), |
69 | 0 | dim.ndim(), |
70 | 0 | "Custom strides given with {} dimensions, expected {}", |
71 | 0 | c.ndim(), |
72 | 0 | dim.ndim() |
73 | | ); |
74 | 0 | c |
75 | | } |
76 | | } |
77 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::Strides<ndarray::dimension::dim::Dim<[usize; 1]>>>::strides_for_dim Unexecuted instantiation: <ndarray::shape_builder::Strides<_>>::strides_for_dim |
78 | | |
79 | 0 | pub(crate) fn is_custom(&self) -> bool { |
80 | 0 | matches!(*self, Strides::Custom(_)) |
81 | 0 | } |
82 | | } |
83 | | |
84 | | /// A trait for `Shape` and `D where D: Dimension` that allows |
85 | | /// customizing the memory layout (strides) of an array shape. |
86 | | /// |
87 | | /// This trait is used together with array constructor methods like |
88 | | /// `Array::from_shape_vec`. |
89 | | pub trait ShapeBuilder { |
90 | | type Dim: Dimension; |
91 | | type Strides; |
92 | | |
93 | | fn into_shape(self) -> Shape<Self::Dim>; |
94 | | fn f(self) -> Shape<Self::Dim>; |
95 | | fn set_f(self, is_f: bool) -> Shape<Self::Dim>; |
96 | | fn strides(self, strides: Self::Strides) -> StrideShape<Self::Dim>; |
97 | | } |
98 | | |
99 | | impl<D> From<D> for Shape<D> |
100 | | where |
101 | | D: Dimension, |
102 | | { |
103 | | /// Create a `Shape` from `dimension`, using the default memory layout. |
104 | 0 | fn from(dimension: D) -> Shape<D> { |
105 | 0 | dimension.into_shape() |
106 | 0 | } |
107 | | } |
108 | | |
109 | | impl<T, D> From<T> for StrideShape<D> |
110 | | where |
111 | | D: Dimension, |
112 | | T: ShapeBuilder<Dim = D>, |
113 | | { |
114 | 0 | fn from(value: T) -> Self { |
115 | 0 | let shape = value.into_shape(); |
116 | 0 | let st = if shape.is_c() { Strides::C } else { Strides::F }; |
117 | 0 | StrideShape { |
118 | 0 | strides: st, |
119 | 0 | dim: shape.dim, |
120 | 0 | } |
121 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::StrideShape<ndarray::dimension::dim::Dim<[usize; 1]>> as core::convert::From<ndarray::dimension::dim::Dim<[usize; 1]>>>::from Unexecuted instantiation: <ndarray::shape_builder::StrideShape<ndarray::dimension::dim::Dim<[usize; 1]>> as core::convert::From<ndarray::shape_builder::Shape<ndarray::dimension::dim::Dim<[usize; 1]>>>>::from Unexecuted instantiation: <ndarray::shape_builder::StrideShape<ndarray::dimension::dim::Dim<[usize; 1]>> as core::convert::From<usize>>::from Unexecuted instantiation: <ndarray::shape_builder::StrideShape<_> as core::convert::From<_>>::from |
122 | | } |
123 | | |
124 | | impl<T> ShapeBuilder for T |
125 | | where |
126 | | T: IntoDimension, |
127 | | { |
128 | | type Dim = T::Dim; |
129 | | type Strides = T; |
130 | 0 | fn into_shape(self) -> Shape<Self::Dim> { |
131 | 0 | Shape { |
132 | 0 | dim: self.into_dimension(), |
133 | 0 | strides: Strides::C, |
134 | 0 | } |
135 | 0 | } Unexecuted instantiation: <ndarray::dimension::dim::Dim<[usize; 1]> as ndarray::shape_builder::ShapeBuilder>::into_shape Unexecuted instantiation: <[usize; 1] as ndarray::shape_builder::ShapeBuilder>::into_shape Unexecuted instantiation: <usize as ndarray::shape_builder::ShapeBuilder>::into_shape Unexecuted instantiation: <_ as ndarray::shape_builder::ShapeBuilder>::into_shape |
136 | 0 | fn f(self) -> Shape<Self::Dim> { |
137 | 0 | self.set_f(true) |
138 | 0 | } |
139 | 0 | fn set_f(self, is_f: bool) -> Shape<Self::Dim> { |
140 | 0 | self.into_shape().set_f(is_f) |
141 | 0 | } Unexecuted instantiation: <ndarray::dimension::dim::Dim<[usize; 1]> as ndarray::shape_builder::ShapeBuilder>::set_f Unexecuted instantiation: <_ as ndarray::shape_builder::ShapeBuilder>::set_f |
142 | 0 | fn strides(self, st: T) -> StrideShape<Self::Dim> { |
143 | 0 | self.into_shape().strides(st.into_dimension()) |
144 | 0 | } Unexecuted instantiation: <ndarray::dimension::dim::Dim<[usize; 1]> as ndarray::shape_builder::ShapeBuilder>::strides Unexecuted instantiation: <[usize; 1] as ndarray::shape_builder::ShapeBuilder>::strides Unexecuted instantiation: <_ as ndarray::shape_builder::ShapeBuilder>::strides |
145 | | } |
146 | | |
147 | | impl<D> ShapeBuilder for Shape<D> |
148 | | where |
149 | | D: Dimension, |
150 | | { |
151 | | type Dim = D; |
152 | | type Strides = D; |
153 | | |
154 | 0 | fn into_shape(self) -> Shape<D> { |
155 | 0 | self |
156 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::Shape<ndarray::dimension::dim::Dim<[usize; 1]>> as ndarray::shape_builder::ShapeBuilder>::into_shape Unexecuted instantiation: <ndarray::shape_builder::Shape<_> as ndarray::shape_builder::ShapeBuilder>::into_shape |
157 | | |
158 | 0 | fn f(self) -> Self { |
159 | 0 | self.set_f(true) |
160 | 0 | } |
161 | | |
162 | 0 | fn set_f(mut self, is_f: bool) -> Self { |
163 | 0 | self.strides = if !is_f { Strides::C } else { Strides::F }; |
164 | 0 | self |
165 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::Shape<ndarray::dimension::dim::Dim<[usize; 1]>> as ndarray::shape_builder::ShapeBuilder>::set_f Unexecuted instantiation: <ndarray::shape_builder::Shape<_> as ndarray::shape_builder::ShapeBuilder>::set_f |
166 | | |
167 | 0 | fn strides(self, st: D) -> StrideShape<D> { |
168 | 0 | StrideShape { |
169 | 0 | dim: self.dim, |
170 | 0 | strides: Strides::Custom(st), |
171 | 0 | } |
172 | 0 | } Unexecuted instantiation: <ndarray::shape_builder::Shape<ndarray::dimension::dim::Dim<[usize; 1]>> as ndarray::shape_builder::ShapeBuilder>::strides Unexecuted instantiation: <ndarray::shape_builder::Shape<_> as ndarray::shape_builder::ShapeBuilder>::strides |
173 | | } |
174 | | |
175 | | impl<D> Shape<D> |
176 | | where |
177 | | D: Dimension, |
178 | | { |
179 | | /// Return a reference to the dimension |
180 | 0 | pub fn raw_dim(&self) -> &D { |
181 | 0 | &self.dim |
182 | 0 | } |
183 | | /// Return the size of the shape in number of elements |
184 | 0 | pub fn size(&self) -> usize { |
185 | 0 | self.dim.size() |
186 | 0 | } |
187 | | } |
188 | | |
189 | | |
190 | | /// Array shape argument with optional order parameter |
191 | | /// |
192 | | /// Shape or array dimension argument, with optional [`Order`] parameter. |
193 | | /// |
194 | | /// This is an argument conversion trait that is used to accept an array shape and |
195 | | /// (optionally) an ordering argument. |
196 | | /// |
197 | | /// See for example [`.to_shape()`](crate::ArrayBase::to_shape). |
198 | | pub trait ShapeArg { |
199 | | type Dim: Dimension; |
200 | | fn into_shape_and_order(self) -> (Self::Dim, Option<Order>); |
201 | | } |
202 | | |
203 | | impl<T> ShapeArg for T where T: IntoDimension { |
204 | | type Dim = T::Dim; |
205 | | |
206 | 0 | fn into_shape_and_order(self) -> (Self::Dim, Option<Order>) { |
207 | 0 | (self.into_dimension(), None) |
208 | 0 | } |
209 | | } |
210 | | |
211 | | impl<T> ShapeArg for (T, Order) where T: IntoDimension { |
212 | | type Dim = T::Dim; |
213 | | |
214 | 0 | fn into_shape_and_order(self) -> (Self::Dim, Option<Order>) { |
215 | 0 | (self.0.into_dimension(), Some(self.1)) |
216 | 0 | } |
217 | | } |