AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
StaticSize.hpp
1#pragma once
2
3#include <array>
4#include <tuple>
5#include <type_traits>
6
7#include <dune/common/typeutilities.hh>
8#include <amdis/common/TypeTraits.hpp>
9
10#if AMDIS_HAS_MTL
11#include <boost/numeric/mtl/operation/static_size.hpp>
12#endif
13
14namespace AMDiS
15{
16 namespace Impl
17 {
18 template <class Container>
19 struct SizeImpl
20 {
21#if AMDIS_HAS_MTL
22 // MTL4: Try if a mtl::static_size is specialized for class
23 template <class T>
24 static constexpr auto eval(T const&, Dune::PriorityTag<6>)
25 -> decltype(std::integral_constant<std::size_t,(mtl::static_num_rows<T>::value * mtl::static_num_cols<T>::value)>{})
26 {
27 return {};
28 }
29#endif
30
31 // Eigen: Try if a static SizeAtCompileTime constant is specified for class
32 template <class T>
33 static constexpr auto eval(T const&, Dune::PriorityTag<5>)
34 -> decltype(std::integral_constant<std::size_t,T::SizeAtCompileTime>{})
35 {
36 return {};
37 }
38
39 // Try if tuple_size is implemented for class
40 template <class T>
41 static constexpr auto eval(T const&, Dune::PriorityTag<4>)
42 -> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>{})
43 {
44 return {};
45 }
46
47 // Try if a static dimension constant is specified for class
48 template <class T>
49 static constexpr auto eval(T const&, Dune::PriorityTag<3>)
50 -> decltype(std::integral_constant<std::size_t,T::dimension>{})
51 {
52 return {};
53 }
54
55 // Try if a static rows and cols constants are specified for class
56 template <class T>
57 static constexpr auto eval(T const&, Dune::PriorityTag<2>)
58 -> decltype(std::integral_constant<std::size_t,(T::rows * T::cols)>{})
59 {
60 return {};
61 }
62
63 // Try if there's a static constexpr size()
64 template <class T>
65 static constexpr auto eval(T const&, Dune::PriorityTag<1>)
66 -> decltype(std::integral_constant<std::size_t,T::size()>{})
67 {
68 return {};
69 }
70
71 // Arithmetic types have size 1 otherwise size is 0
72 template <class T>
73 static constexpr auto eval(T const&, Dune::PriorityTag<0>)
74 -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic_v<T> ? 1 : 0)>{})
75 {
76 return {};
77 }
78
79 static constexpr auto eval(Container const& container)
80 {
81 return eval(container, Dune::PriorityTag<42>{});
82 }
83 };
84
85 } // end namespace Impl
86
87
98 template <class Container>
99 constexpr auto static_size(Container const& container)
100 {
101 return Impl::SizeImpl<Container>::eval(container);
102 }
103
104 template <class Container>
105 constexpr std::size_t static_size_v
106 = decltype(static_size(std::declval<remove_cvref_t<Container>>()))::value;
107
108 template <class T, std::size_t S0, std::size_t S1 = static_size_v<T>>
110 {
111 static_assert(S0 == S1, "Non-matching size");
112 };
113
114
115 namespace Impl
116 {
117 template <class Matrix>
118 struct NumRowsImpl
119 {
120#if AMDIS_HAS_MTL
121 // MTL4: Try if a mtl::static_num_rows is specialized for class
122 template <class T>
123 static constexpr auto eval(T const&, Dune::PriorityTag<4>)
124 -> decltype(std::integral_constant<std::size_t,mtl::static_num_rows<T>::value>{})
125 {
126 return {};
127 }
128#endif
129
130 // Eigen: Try if a static RowsAtCompileTime constant is specified for class
131 template <class T>
132 static constexpr auto eval(T const&, Dune::PriorityTag<3>)
133 -> decltype(std::integral_constant<std::size_t,T::RowsAtCompileTime>{})
134 {
135 return {};
136 }
137
138 // Try if a static rows constant is specified for class
139 template <class T>
140 static constexpr auto eval(T const&, Dune::PriorityTag<2>)
141 -> decltype(std::integral_constant<std::size_t,T::rows>{})
142 {
143 return {};
144 }
145
146 // Try if there's a static constexpr N()
147 template <class T>
148 static constexpr auto eval(T const&, Dune::PriorityTag<1>)
149 -> decltype(std::integral_constant<std::size_t,T::N()>{})
150 {
151 return {};
152 }
153
154 // Fallback-size is 1 for arithmetic types or 0
155 template <class T>
156 static constexpr auto eval(T const&, Dune::PriorityTag<0>)
157 -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic_v<T> ? 1 : 0)>{})
158 {
159 return {};
160 }
161
162 static constexpr auto eval(Matrix const& matrix)
163 {
164 return eval(matrix, Dune::PriorityTag<42>{});
165 }
166 };
167
168 } // end namespace Impl
169
170
181 template <class Matrix>
182 constexpr auto static_num_rows(Matrix const& matrix)
183 {
184 return Impl::NumRowsImpl<Matrix>::eval(matrix);
185 }
186
187 template <class Matrix>
188 constexpr std::size_t static_num_rows_v
189 = decltype(static_num_rows(std::declval<remove_cvref_t<Matrix>>()))::value;
190
191 template <class T, std::size_t S0, std::size_t S1 = static_num_rows<T>>
193 {
194 static_assert(S0 == S1, "Non-matching num rows");
195 };
196
197 namespace Impl
198 {
199 template <class Matrix>
200 struct NumColsImpl
201 {
202#if AMDIS_HAS_MTL
203 // MTL4: Try if a mtl::static_num_cols is specialized for class
204 template <class T>
205 static constexpr auto eval(T const&, Dune::PriorityTag<4>)
206 -> decltype(std::integral_constant<std::size_t,mtl::static_num_cols<T>::value>{})
207 {
208 return {};
209 }
210#endif
211
212 // Eigen: Try if a static ColsAtCompileTime constant is specified for class
213 template <class T>
214 static constexpr auto eval(T const&, Dune::PriorityTag<3>)
215 -> decltype(std::integral_constant<std::size_t,T::ColsAtCompileTime>{})
216 {
217 return {};
218 }
219
220 // Try if a static cols constant is specified for class
221 template <class T>
222 static constexpr auto eval(T const&, Dune::PriorityTag<2>)
223 -> decltype(std::integral_constant<std::size_t,T::cols>{})
224 {
225 return {};
226 }
227
228 // Try if there's a static constexpr M()
229 template <class T>
230 static constexpr auto eval(T const&, Dune::PriorityTag<1>)
231 -> decltype(std::integral_constant<std::size_t,T::M()>{})
232 {
233 return {};
234 }
235
236 // Fallback-size is 0
237 template <class T>
238 static constexpr auto eval(T const&, Dune::PriorityTag<0>)
239 -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic_v<T> ? 1 : 0)>{})
240 {
241 return {};
242 }
243
244 static constexpr auto eval(Matrix const& matrix)
245 {
246 return eval(matrix, Dune::PriorityTag<42>{});
247 }
248 };
249
250 } // end namespace Impl
251
252
263 template <class Matrix>
264 constexpr auto static_num_cols(Matrix const& matrix)
265 {
266 return Impl::NumColsImpl<Matrix>::eval(matrix);
267 }
268
269 template <class Matrix>
270 constexpr std::size_t static_num_cols_v
271 = decltype(static_num_cols(std::declval<remove_cvref_t<Matrix>>()))::value;
272
273 template <class T, std::size_t S0, std::size_t S1 = static_num_cols<T>>
275 {
276 static_assert(S0 == S1, "Non-matching num rows");
277 };
278
279} // end namespace AMDiS
Definition: StaticSize.hpp:275
Definition: StaticSize.hpp:193
Definition: StaticSize.hpp:110