OpenKalman
object-traits-defined.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2023-2024 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
16 #ifndef OPENKALMAN_OBJECT_TRAITS_DEFINED_HPP
17 #define OPENKALMAN_OBJECT_TRAITS_DEFINED_HPP
18 
19 #include <type_traits>
24 
25 namespace OpenKalman::interface
26 {
27  // ------------- //
28  // scalar_type //
29  // ------------- //
30 
31 #ifdef __cpp_concepts
32  template<typename T>
33  concept scalar_type_defined_for = values::number<typename indexible_object_traits<std::decay_t<T>>::scalar_type>;
34 #else
35  namespace detail
36  {
37  template<typename T, typename = void>
38  struct scalar_type_defined_for_impl : std::false_type {};
39 
40  template<typename T>
41  struct scalar_type_defined_for_impl<T, std::enable_if_t<values::number<typename indexible_object_traits<std::decay_t<T>>::scalar_type>>>
42  : std::true_type {};
43  }
44 
45  template<typename T>
46  constexpr bool scalar_type_defined_for = detail::scalar_type_defined_for_impl<T>::value;
47 #endif
48 
49 
50  // --------------- //
51  // count_indices //
52  // --------------- //
53 
54 #ifdef __cpp_concepts
55  template<typename T>
56  concept count_indices_defined_for = requires (T t) {
58  };
59 #else
60  namespace detail
61  {
62  template<typename T, typename = void>
63  struct count_indices_defined_for_impl : std::false_type {};
64 
65  template<typename T>
66  struct count_indices_defined_for_impl<T, std::enable_if_t<
67  values::index<decltype(indexible_object_traits<std::decay_t<T>>::count_indices(std::declval<T>()))>>>
68  : std::true_type {};
69  }
70 
71  template<typename T>
72  constexpr bool count_indices_defined_for = detail::count_indices_defined_for_impl<T>::value;
73 #endif
74 
75 
76  // ----------------------------- //
77  // get_vector_space_descriptor //
78  // ----------------------------- //
79 
80 #ifdef __cpp_concepts
81  template<typename T>
82  concept get_vector_space_descriptor_defined_for = requires (T t) {
84  t, std::integral_constant<std::size_t, 0>{})} -> coordinates::coordinates::pattern;
85  };
86 #else
87  namespace detail
88  {
89  template<typename T, typename = void>
90  struct get_vector_space_descriptor_defined_for_impl : std::false_type {};
91 
92  template<typename T>
93  struct get_vector_space_descriptor_defined_for_impl<T, std::enable_if_t<coordinates::coordinates::pattern<
94  decltype(indexible_object_traits<std::decay_t<T>>::get_vector_space_descriptor(
95  std::declval<T>(), std::integral_constant<std::size_t, 0>{}))>>>
96  : std::true_type {};
97  }
98 
99  template<typename T>
100  constexpr bool get_vector_space_descriptor_defined_for = detail::get_vector_space_descriptor_defined_for_impl<T>::value;
101 #endif
102 
103 
104  // --------------- //
105  // nested_object //
106  // --------------- //
107 
108 #ifdef __cpp_concepts
109  template<typename T>
110  concept nested_object_defined_for = requires (T&& t) {
111  {indexible_object_traits<std::decay_t<T>>::nested_object(std::forward<T>(t))} -> count_indices_defined_for;
112  };
113 #else
114  namespace detail
115  {
116  template<typename T, typename = void>
117  struct nested_object_defined_for_impl : std::false_type {};
118 
119  template<typename T>
120  struct nested_object_defined_for_impl<T, std::enable_if_t<
121  count_indices_defined_for<decltype(indexible_object_traits<std::decay_t<T>>::nested_object(std::declval<T&&>()))>>>
122  : std::true_type {};
123  }
124 
125  template<typename T>
126  constexpr bool nested_object_defined_for = detail::nested_object_defined_for_impl<T>::value;
127 #endif
128 
129 
130  // -------------- //
131  // get_constant //
132  // -------------- //
133 
134 #ifdef __cpp_concepts
135  template<typename T>
136 #else
137  template<typename T, typename = void>
138 #endif
139  struct get_constant_return_type { using type = std::monostate; };
140 
141 
142 #ifdef __cpp_concepts
143  template<typename T> requires requires(T t) { {indexible_object_traits<std::decay_t<T>>::get_constant(t)}; }
144  struct get_constant_return_type<T>
145 #else
146  template<typename T>
147  struct get_constant_result_type<T, std::void_t<
148  decltype(indexible_object_traits<std::decay_t<T>>::get_constant(std::declval<T>()))>>
149 #endif
150  {
151  using type = decltype(indexible_object_traits<std::decay_t<T>>::get_constant(std::declval<T>()));
152  };
153 
154 
155  // ----------------------- //
156  // get_constant_diagonal //
157  // ----------------------- //
158 
159 #ifdef __cpp_concepts
160  template<typename T>
161 #else
162  template<typename T, typename = void>
163 #endif
164  struct get_constant_diagonal_return_type { using type = std::monostate; };
165 
166 
167 #ifdef __cpp_concepts
168  template<typename T> requires requires(T t) { {indexible_object_traits<std::decay_t<T>>::get_constant_diagonal(t)}; }
170 #else
171  template<typename T>
172  struct get_constant_diagonal_result_type<T, std::void_t<
173  decltype(indexible_object_traits<std::decay_t<T>>::get_constant_diagonal(std::declval<T>()))>>
174 #endif
175  {
176  using type = decltype(indexible_object_traits<std::decay_t<T>>::get_constant_diagonal(std::declval<T>()));
177  };
178 
179 
180  // ----------------- //
181  // one_dimensional //
182  // ----------------- //
183 
184 #ifdef __cpp_concepts
185  template<typename T, Applicability b = Applicability::guaranteed>
186  concept one_dimensional_defined_for = std::convertible_to<
187  decltype(indexible_object_traits<std::decay_t<T>>::template one_dimensional<b>), bool>;
188 #else
189  namespace detail
190  {
191  template<typename T, Applicability b, typename = void>
192  struct one_dimensional_defined_for_impl : std::false_type {};
193 
194  template<typename T, Applicability b>
195  struct one_dimensional_defined_for_impl<T, b, std::enable_if_t<std::is_convertible_v<
196  decltype(indexible_object_traits<std::decay_t<T>>::template one_dimensional<b>), bool>>>
197  : std::true_type {};
198  }
199 
200  template<typename T, Applicability b = Applicability::guaranteed>
201  constexpr bool one_dimensional_defined_for = detail::one_dimensional_defined_for_impl<T, b>::value;
202 
203 
204  template<typename T, Applicability b, typename = void>
205  struct is_explicitly_one_dimensional : std::false_type {};
206 
207  template<typename T, Applicability b>
208  struct is_explicitly_one_dimensional<T, b, std::enable_if_t<indexible_object_traits<std::decay_t<T>>::template one_dimensional<b>>>
209  : std::true_type {};
210 #endif
211 
212 
213  // ----------- //
214  // is_square //
215  // ----------- //
216 
217 #ifdef __cpp_concepts
218  template<typename T, Applicability b = Applicability::guaranteed>
219  concept is_square_defined_for = std::convertible_to<
220  decltype(indexible_object_traits<std::decay_t<T>>::template is_square<b>), bool>;
221 #else
222  namespace detail
223  {
224  template<typename T, Applicability b, typename = void>
225  struct is_square_defined_for_impl : std::false_type {};
226 
227  template<typename T, Applicability b>
228  struct is_square_defined_for_impl<T, b, std::enable_if_t<std::is_convertible_v<
229  decltype(indexible_object_traits<std::decay_t<T>>::template is_square<b>), bool>>>
230  : std::true_type {};
231  }
232 
233  template<typename T, Applicability b = Applicability::guaranteed>
234  constexpr bool is_square_defined_for = detail::is_square_defined_for_impl<T, b>::value;
235 #endif
236 
237 
238  // --------------- //
239  // is_triangular //
240  // --------------- //
241 
242 #ifdef __cpp_concepts
243  template<typename T, TriangleType t>
244  concept is_triangular_defined_for = requires { indexible_object_traits<std::decay_t<T>>::template is_triangular<t>; };
245 #else
246  namespace detail
247  {
248  template<typename T, TriangleType t, typename = void>
249  struct is_triangular_defined_for_impl : std::false_type {};
250 
251  template<typename T, TriangleType t>
252  struct is_triangular_defined_for_impl<T, t, std::void_t<decltype(indexible_object_traits<std::decay_t<T>>::template is_triangular<t>)>>
253  : std::true_type {};
254  }
255 
256  template<typename T, TriangleType t>
257  constexpr bool is_triangular_defined_for = detail::is_triangular_defined_for_impl<T, t>::value;
258 #endif
259 
260 
261  // ----------------------- //
262  // is_triangular_adapter //
263  // ----------------------- //
264 
265 #ifdef __cpp_concepts
266  template<typename T>
267  concept is_triangular_adapter_defined_for = std::convertible_to<
268  decltype(indexible_object_traits<std::decay_t<T>>::is_triangular_adapter), bool>;
269 #else
270  namespace detail
271  {
272  template<typename T, typename = void>
273  struct is_triangular_adapter_defined_for_impl : std::false_type {};
274 
275  template<typename T>
276  struct is_triangular_adapter_defined_for_impl<T, std::enable_if_t<std::is_convertible_v<
277  decltype(indexible_object_traits<std::decay_t<T>>::is_triangular_adapter), bool>>>
278  : std::true_type {};
279  }
280 
281  template<typename T>
282  constexpr bool is_triangular_adapter_defined_for = detail::is_triangular_adapter_defined_for_impl<T>::value;
283 #endif
284 
285 
286  // -------------- //
287  // is_hermitian //
288  // -------------- //
289 
290 #ifdef __cpp_concepts
291  template<typename T>
292  concept is_hermitian_defined_for = std::convertible_to<
293  decltype(indexible_object_traits<std::decay_t<T>>::is_hermitian), bool>;
294 #else
295  namespace detail
296  {
297  template<typename T, typename = void>
298  struct is_hermitian_defined_for_impl : std::false_type {};
299 
300  template<typename T>
301  struct is_hermitian_defined_for_impl<T, std::enable_if_t<std::is_convertible_v<
302  decltype(indexible_object_traits<std::decay_t<T>>::is_hermitian), bool>>>
303  : std::true_type {};
304  }
305 
306  template<typename T>
307  constexpr bool is_hermitian_defined_for = detail::is_hermitian_defined_for_impl<T>::value;
308 
309 
310  template<typename T, typename = void>
311  struct is_explicitly_hermitian : std::false_type {};
312 
313  template<typename T>
314  struct is_explicitly_hermitian<T, std::enable_if_t<indexible_object_traits<std::decay_t<T>>::is_hermitian>>
315  : std::true_type {};
316 #endif
317 
318 
319  // ------------------------ //
320  // hermitian_adapter_type //
321  // ------------------------ //
322 
323 #ifdef __cpp_concepts
324  template<typename T>
325  concept hermitian_adapter_type_defined_for = std::convertible_to<
326  decltype(indexible_object_traits<std::decay_t<T>>::hermitian_adapter_type), HermitianAdapterType>;
327 #else
328  namespace detail
329  {
330  template<typename T, typename = void>
331  struct hermitian_adapter_type_defined_for_impl : std::false_type {};
332 
333  template<typename T>
334  struct hermitian_adapter_type_defined_for_impl<T, std::enable_if_t<std::is_convertible_v<
335  decltype(indexible_object_traits<std::decay_t<T>>::hermitian_adapter_type), HermitianAdapterType>>>
336  : std::true_type {};
337  }
338 
339  template<typename T>
340  constexpr bool hermitian_adapter_type_defined_for = detail::hermitian_adapter_type_defined_for_impl<T>::value;
341 #endif
342 
343 
344  // ------------- //
345  // is_writable //
346  // ------------- //
347 
348 #ifdef __cpp_concepts
349  template<typename T>
350  concept is_writable_defined_for = std::convertible_to<
351  decltype(indexible_object_traits<std::decay_t<T>>::is_writable), bool>;
352 #else
353  namespace detail
354  {
355  template<typename T, typename = void>
356  struct is_writable_defined_for_impl : std::false_type {};
357 
358  template<typename T>
359  struct is_writable_defined_for_impl<T, std::enable_if_t<std::is_convertible_v<
360  decltype(indexible_object_traits<std::decay_t<T>>::is_writable), bool>>>
361  : std::true_type {};
362  }
363 
364  template<typename T>
365  constexpr bool is_writable_defined_for = detail::is_writable_defined_for_impl<T>::value;
366 
367 
368  template<typename T, typename = void>
369  struct is_explicitly_writable : std::false_type {};
370 
371  template<typename T>
372  struct is_explicitly_writable<T, std::enable_if_t<indexible_object_traits<std::decay_t<T>>::is_writable>> : std::true_type {};
373 #endif
374 
375 
376  // ---------- //
377  // raw_data //
378  // ---------- //
379 
380 #ifdef __cpp_concepts
381  template<typename T>
382  concept raw_data_defined_for = requires (T t) { {*indexible_object_traits<std::decay_t<T>>::raw_data(t)} -> values::value; };
383 #else
384  namespace detail
385  {
386  template<typename T, typename = void>
387  struct raw_data_defined_for_impl : std::false_type {};
388 
389  template<typename T>
390  struct raw_data_defined_for_impl<T, std::enable_if_t<
391  values::value<decltype(*indexible_object_traits<std::decay_t<T>>::raw_data(std::declval<T>()))>>>
392  : std::true_type {};
393  }
394 
395  template<typename T>
396  constexpr bool raw_data_defined_for = detail::raw_data_defined_for_impl<T>::value;
397 #endif
398 
399 
400  // -------- //
401  // layout //
402  // -------- //
403 
404 #ifdef __cpp_concepts
405  template<typename T>
406  concept layout_defined_for = requires(T t) {
407  {indexible_object_traits<std::decay_t<T>>::layout} -> std::convertible_to<const Layout>;
408  };
409 #else
410  namespace detail
411  {
412  template<typename T, typename = void>
413  struct layout_defined_for_impl : std::false_type {};
414 
415  template<typename T>
416  struct layout_defined_for_impl<T, std::enable_if_t<std::is_convertible_v<
417  std::decay_t<decltype(indexible_object_traits<std::decay_t<T>>::layout)>, const Layout>>>
418  : std::true_type {};
419  }
420 
421  template<typename T>
422  constexpr bool layout_defined_for = detail::layout_defined_for_impl<T>::value;
423 #endif
424 
425 
426  // --------- //
427  // strides //
428  // --------- //
429 
430 #ifdef __cpp_concepts
431  template<typename T>
432  concept strides_defined_for = requires (T t) { indexible_object_traits<std::decay_t<T>>::strides(t); };
433 #else
434  namespace detail
435  {
436  template<typename T, typename = void>
437  struct strides_defined_for_impl : std::false_type {};
438 
439  template<typename T>
440  struct strides_defined_for_impl<T, std::void_t<decltype(indexible_object_traits<std::decay_t<T>>::strides(std::declval<T>()))>>
441  : std::true_type {};
442  }
443 
444  template<typename T>
445  constexpr bool strides_defined_for = detail::strides_defined_for_impl<T>::value;
446 #endif
447 
448 
449 } // namespace OpenKalman::interface
450 
451 
452 #endif //OPENKALMAN_OBJECT_TRAITS_DEFINED_HPP
constexpr auto count_indices(const T &t)
Get the number of indices available to address the components of an indexible object.
Definition: count_indices.hpp:33
Definition for values::index.
Forward declaration of indexible_object_traits, which must be defined for all objects used in OpenKal...
Definition: object-traits-defined.hpp:356
Definition: indexible_object_traits.hpp:36
Definition: basics.hpp:41
Definition: object-traits-defined.hpp:139
Definition: object-traits-defined.hpp:225
Definition: tuple_reverse.hpp:103
Definition: object-traits-defined.hpp:387
HermitianAdapterType
The type of a hermitian adapter, indicating which triangle of the nested matrix is used...
Definition: global-definitions.hpp:78
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
Definition: object-traits-defined.hpp:311
Definition: object-traits-defined.hpp:249
Definition: object-traits-defined.hpp:413
Definition: object-traits-defined.hpp:205
Definition: object-traits-defined.hpp:164
constexpr bool index
T is an index value.
Definition: index.hpp:56
Definition: object-traits-defined.hpp:38
Definition: object-traits-defined.hpp:298
Definition: object-traits-defined.hpp:369
Definition for values::number.
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
Definition: object-traits-defined.hpp:117
Global definitions for OpenKalman.
Definition: object-traits-defined.hpp:437
constexpr auto get_vector_space_descriptor(const T &t, const N &n)
Get the coordinates::pattern object for index N of indexible object T.
Definition: get_vector_space_descriptor.hpp:56