ARTS 2.5.10 (git: 2f1c442c)
matpack_concepts.h
Go to the documentation of this file.
1#pragma once
2
3#include "debug.h"
4#include <complex>
5#include <concepts>
6#include <type_traits>
7
8namespace matpack {
9template <typename T>
10concept matpack_type = std::remove_cvref_t<T>::matpack_type;
11
12template <typename T>
13concept has_nelem = requires(T a) {
14 { a.nelem() } -> std::integral;
15};
16
17template <typename T>
18concept has_ncols = requires(T a) {
19 { a.ncols() } -> std::integral;
20};
21
22template <typename T>
23concept has_nrows = requires(T a) {
24 { a.nrows() } -> std::integral;
25};
26
27template <typename T>
28concept has_npages = requires(T a) {
29 { a.npages() } -> std::integral;
30};
31
32template <typename T>
33concept has_nbooks = requires(T a) {
34 { a.nbooks() } -> std::integral;
35};
36
37template <typename T>
38concept has_nshelves = requires(T a) {
39 { a.nshelves() } -> std::integral;
40};
41
42template <typename T>
43concept has_nvitrines = requires(T a) {
44 { a.nvitrines() } -> std::integral;
45};
46
47template <typename T>
48concept has_nlibraries = requires(T a) {
49 { a.nlibraries() } -> std::integral;
50};
51
53namespace external_class {
55template <typename T>
56concept has_cols = requires(T a) {
57 { a.cols() } -> std::integral;
58};
59
61template <typename T>
62concept has_rows = requires(T a) {
63 { a.rows() } -> std::integral;
64};
65
66// For instance vector and array uses size()
67template <typename T>
68concept has_size = requires(T a) {
69 { a.size() } -> std::integral;
70} and not matpack_type<T>;
71} // namespace external_class
72
75
77constexpr auto column_size(column_keeper auto&& x) {
78 using internal_type = decltype(x);
79 if constexpr (external_class::has_cols<internal_type>) return std::forward<internal_type>(x).cols();
80 else if constexpr (external_class::has_size<internal_type>) return std::forward<internal_type>(x).size();
81 else if constexpr (has_nelem<internal_type>) return std::forward<internal_type>(x).nelem();
82 else return std::forward<internal_type>(x).ncols();
83}
84
87
89constexpr auto row_size(row_keeper auto&& x) {
90 using internal_type = decltype(x);
91 if constexpr (external_class::has_rows<internal_type>) return std::forward<internal_type>(x).rows();
92 else return std::forward<internal_type>(x).nrows();
93}
94
96template <typename T> concept page_keeper = row_keeper<T> and (has_npages<T>);
97
99constexpr auto page_size(page_keeper auto&& x) {
100 using internal_type = decltype(x);
101 return std::forward<internal_type>(x).npages();
102}
103
105template <typename T> concept book_keeper = page_keeper<T> and (has_nbooks<T>);
106
108constexpr auto book_size(book_keeper auto&& x) {
109 using internal_type = decltype(x);
110 return std::forward<internal_type>(x).nbooks();
111}
112
114template <typename T> concept shelf_keeper = book_keeper<T> and (has_nshelves<T>);
115
117constexpr auto shelf_size(shelf_keeper auto&& x) {
118 using internal_type = decltype(x);
119 return std::forward<internal_type>(x).nshelves();
120}
121
123template <typename T> concept vitrine_keeper = shelf_keeper<T> and (has_nvitrines<T>);
124
126constexpr auto vitrine_size(vitrine_keeper auto&& x) {
127 using internal_type = decltype(x);
128 return std::forward<internal_type>(x).nvitrines();
129}
130
132template <typename T> concept library_keeper = vitrine_keeper<T> and (has_nlibraries<T>);
133
135constexpr auto library_size(library_keeper auto&& x) {
136 using internal_type = decltype(x);
137 return std::forward<internal_type>(x).nlibraries();
138}
139
141template <typename T>
142struct is_complex : std::false_type {};
143
145template <std::floating_point T>
146struct is_complex<std::complex<T>> : std::true_type {};
147
149template <typename T>
151 std::floating_point<std::remove_cvref_t<T>> or
152 is_complex<std::remove_cvref_t<T>>::value;
153
155template <typename T>
156concept vector_like = requires(T a) {
157 { column_size(a) } -> std::integral;
158 { a[0] } -> complex_or_real;
159};
160
162template <typename T>
163concept vector = matpack_type<T> and vector_like<T> and requires(T a) {
164 { a.nelem() } -> std::integral;
165 { a.delem() } -> std::integral;
166 { a.selem() } -> std::integral;
167 { *a.get_c_array() } -> complex_or_real;
168};
169
171template <typename T>
173
175template <typename T>
176concept matrix_like = requires(T a) {
177 { row_size(a) } -> std::integral;
178 { a(0, 0) } -> complex_or_real;
179};
180
182template <typename T>
183concept matrix = matpack_type<T> and matrix_like<T> and has_ncols<T> and has_nrows<T> and requires(T a) {
184 { a.drows() } -> std::integral;
185 { a.dcols() } -> std::integral;
186 { a.selem() } -> std::integral;
187 { *a.get_c_array() } -> complex_or_real;
188};
189
191template <typename T>
193
195template <typename T>
197
199template <typename T>
200concept tensor3_like = requires(T a) {
201 { page_size(a) } -> std::integral;
202 { a(0, 0, 0) } -> complex_or_real;
203};
204
206template <typename T>
208
210template <typename T>
211concept tensor4_like = requires(T a) {
212 { book_size(a) } -> std::integral;
213 { a(0, 0, 0, 0) } -> complex_or_real;
214};
215
217template <typename T>
219
221template <typename T>
222concept tensor5_like = requires(T a) {
223 { shelf_size(a) } -> std::integral;
224 { a(0, 0, 0, 0, 0) } -> complex_or_real;
225};
226
228template <typename T>
230
232template <typename T>
233concept tensor6_like = requires(T a) {
234 { vitrine_size(a) } -> std::integral;
235 { a(0, 0, 0, 0, 0, 0) } -> complex_or_real;
236};
237
239template <typename T>
241
243template <typename T>
244concept tensor7_like = requires(T a) {
245 { library_size(a) } -> std::integral;
246 { a(0, 0, 0, 0, 0, 0, 0) } -> complex_or_real;
247};
248
250template <typename T>
252
253template <typename T>
257
258template <matpack_like T> constexpr std::size_t dim() {
261}
262
264template <class IndexType, std::size_t N>
265constexpr std::array<IndexType, N> shape(matpack_like auto &&x) {
266 using T = decltype(x);
267 static_assert(N > 0 and N < 8, "Out of range");
268
269 static_assert((N == 1 and dim<T>() == 2) or (N == dim<T>()),
270 "Dimensions must agree, or a matrix-like that is runtime "
271 "defined as vector be used");
272
273 if constexpr (N == 7)
274 return {static_cast<IndexType>(library_size(std::forward<T>(x))),
275 static_cast<IndexType>(vitrine_size(std::forward<T>(x))),
276 static_cast<IndexType>(shelf_size(std::forward<T>(x))),
277 static_cast<IndexType>(book_size(std::forward<T>(x))),
278 static_cast<IndexType>(page_size(std::forward<T>(x))),
279 static_cast<IndexType>(row_size(std::forward<T>(x))),
280 static_cast<IndexType>(column_size(std::forward<T>(x)))};
281 else if constexpr (N == 6)
282 return {static_cast<IndexType>(vitrine_size(std::forward<T>(x))),
283 static_cast<IndexType>(shelf_size(std::forward<T>(x))),
284 static_cast<IndexType>(book_size(std::forward<T>(x))),
285 static_cast<IndexType>(page_size(std::forward<T>(x))),
286 static_cast<IndexType>(row_size(std::forward<T>(x))),
287 static_cast<IndexType>(column_size(std::forward<T>(x)))};
288 else if constexpr (N == 5)
289 return {static_cast<IndexType>(shelf_size(std::forward<T>(x))),
290 static_cast<IndexType>(book_size(std::forward<T>(x))),
291 static_cast<IndexType>(page_size(std::forward<T>(x))),
292 static_cast<IndexType>(row_size(std::forward<T>(x))),
293 static_cast<IndexType>(column_size(std::forward<T>(x)))};
294 else if constexpr (N == 4)
295 return {static_cast<IndexType>(book_size(std::forward<T>(x))),
296 static_cast<IndexType>(page_size(std::forward<T>(x))),
297 static_cast<IndexType>(row_size(std::forward<T>(x))),
298 static_cast<IndexType>(column_size(std::forward<T>(x)))};
299 else if constexpr (N == 3)
300 return {static_cast<IndexType>(page_size(std::forward<T>(x))),
301 static_cast<IndexType>(row_size(std::forward<T>(x))),
302 static_cast<IndexType>(column_size(std::forward<T>(x)))};
303 else if constexpr (N == 2)
304 return {static_cast<IndexType>(row_size(std::forward<T>(x))),
305 static_cast<IndexType>(column_size(std::forward<T>(x)))};
306 else if constexpr (N == 1) {
307 if constexpr (dim<T>() == 2) {
309 static_cast<IndexType>(std::min(column_size(std::forward<T>(x)),
310 row_size(std::forward<T>(x)))) not_eq
311 static_cast<IndexType>(1),
312 "Cannot perform vector conversion for matrix: ", x)
313 return {static_cast<IndexType>(std::max(column_size(std::forward<T>(x)),
314 row_size(std::forward<T>(x))))};
315 } else
316 return {static_cast<IndexType>(column_size(std::forward<T>(x)))};
317 }
318}
319} // namespace matpack
Checks if the type has any accepted types of books as well as previous sizes.
Checks if the type has any accepted types of columns.
A concept to state if the type is a floating point or a floating point complex.
Eigen uses cols() for column index.
Eigen uses rows() for column index.
Checks if the type has any accepted types of libraries as well as previous sizes.
A concept precluding Arts matrix objects but allowing things similar to matrices.
A concept for an Arts matrix-like type with access operations.
A concept for any of the Arts matrix types.
Checks if the type has any accepted types of pages as well as previous sizes.
Checks if the type has any accepted types of rows as well as previous sizes.
Checks if the type has any accepted types of shelves as well as previous sizes.
A concept precluding Arts types but allowing the tensor-like object.
A concept for an Arts matrix-like type with access operations.
A concept precluding Arts types but allowing the tensor-like object.
A concept for an Arts matrix-like type with access operations.
A concept precluding Arts types but allowing the tensor-like object.
A concept for an Arts matrix-like type with access operations.
A concept precluding Arts types but allowing the tensor-like object.
A concept for an Arts matrix-like type with access operations.
A concept precluding Arts types but allowing the tensor-like object.
A concept for an Arts matrix-like type with access operations.
A concept precluding Arts vector objects but allowing things similar to vectors.
A concept for an Arts vector-like type with access operations.
A concept for any of the Arts vector types.
Checks if the type has any accepted types of vitrines as well as previous sizes.
Helper macros for debugging.
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:153
constexpr std::size_t dim()
constexpr auto vitrine_size(vitrine_keeper auto &&x)
Get a vitrine size from x.
constexpr auto column_size(column_keeper auto &&x)
Get a column size from x.
constexpr auto book_size(book_keeper auto &&x)
Get a book size from x.
constexpr std::array< IndexType, N > shape(matpack_like auto &&x)
Creates a shape array (note that this might create compile time errors if N is larger than x allows f...
constexpr auto shelf_size(shelf_keeper auto &&x)
Get a shelf size from x.
constexpr auto library_size(library_keeper auto &&x)
Get a library size from x.
constexpr auto row_size(row_keeper auto &&x)
Get a row size from x.
constexpr auto page_size(page_keeper auto &&x)
Get a page size from x.
#define N
Definition: rng.cc:164
A concept overload to remove non std::complex<> from list.
#define a