AMDiS  0.1
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 
14 namespace 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>>
109  struct CheckSize
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
typename remove_cvref< T >::type remove_cvref_t
Helper alias template for remove_cvref.
Definition: TypeTraits.hpp:24
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
constexpr auto static_size(Container const &container)
Return a static constant size of the container.
Definition: StaticSize.hpp:99
Definition: StaticSize.hpp:274
constexpr auto static_num_rows(Matrix const &matrix)
Return a static constant rows of the matrix.
Definition: StaticSize.hpp:182
constexpr auto static_num_cols(Matrix const &matrix)
Return a static constant columns of the matrix.
Definition: StaticSize.hpp:264
Definition: StaticSize.hpp:109
Definition: StaticSize.hpp:192