OpenKalman
get_descriptor_collection_element.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) 2025 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 
17 #ifndef OPENKALMAN_COORDINATES_GET_DESCRIPTOR_COLLECTION_ELEMENT_HPP
18 #define OPENKALMAN_COORDINATES_GET_DESCRIPTOR_COLLECTION_ELEMENT_HPP
19 
20 #include <type_traits>
21 #include "linear-algebra/coordinates/interfaces/coordinate_descriptor_traits.hpp"
25 
27 {
28 #ifdef __cpp_concepts
29  template<values::number Scalar>
30 #else
31  template<typename Scalar>
32 #endif
33  struct Any;
34 }
35 
36 
38 {
39  namespace detail
40  {
41  template<typename T1, typename T2>
43 
44  template<typename Scalar1, typename Scalar2>
46 
47  template<typename Scalar, typename T>
48  struct common_descriptor_type<Any<Scalar>, T> { using type = Any<Scalar>; };
49 
50  template<typename T, typename Scalar>
51  struct common_descriptor_type<T, Any<Scalar>> { using type = Any<Scalar>; };
52 
53 
54 #ifdef __cpp_concepts
55  template<typename T1, typename T2>
56 #else
57  template<typename T1, typename T2, typename = void>
58 #endif
60 
61 #ifdef __cpp_concepts
62  template<typename T1, std::common_with<T1> T2>
64 #else
65  template<typename T1, typename T2>
66  struct common_descriptor_tuple_element_impl<T1, T2, std::void_t<typename std::common_type<T1, T2>::type>>
67 #endif
68  : std::common_type<T1, T2> {};
69 
70 
71 #ifdef __cpp_concepts
72  template<typename Tup, std::size_t i = 0>
73 #else
74  template<typename Tup, std::size_t i = 0, typename = void>
75 #endif
77 
78 #ifdef __cpp_concepts
79  template<typename Tup, std::size_t i> requires (i + 1 == std::tuple_size_v<Tup>)
80  struct common_descriptor_tuple_element<Tup, i>
81 #else
82  template<typename Tup, std::size_t i>
83  struct common_descriptor_tuple_element<Tup, i, std::enable_if_t<(i + 1 == std::tuple_size_v<Tup>)>>
84 #endif
85  {
86  using type = std::decay_t<std::tuple_element_t<i, Tup>>;
87  };
88 
89 #ifdef __cpp_concepts
90  template<typename Tup, std::size_t i> requires (i + 1 < std::tuple_size_v<Tup>)
91  struct common_descriptor_tuple_element<Tup, i>
92 #else
93  template<typename Tup, std::size_t i>
94  struct common_descriptor_tuple_element<Tup, i, std::enable_if_t<(i + 1 < std::tuple_size_v<Tup>)>>
95 #endif
96  {
97  using type = typename common_descriptor_tuple_element_impl<std::tuple_element_t<i, Tup>,
98  typename common_descriptor_tuple_element<Tup, i + 1>::type>::type;
99  };
100  } // namespace detail
101 
102 
108 #ifdef __cpp_concepts
109  template<descriptor_collection Arg, values::index I>
110 #else
111  template<typename Arg, typename I, std::enable_if_t<descriptor_collection<Arg> and values::index<I>, int> = 0>
112 #endif
113  constexpr auto
114  get_descriptor_collection_element(Arg&& arg, const I i)
115  {
116  if constexpr (collections::sized_random_access_range<Arg>)
117  {
118  return collections::get(std::forward<Arg>(arg), std::move(i));
119  }
120  else if constexpr (std::tuple_size_v<std::decay_t<Arg>> == 0)
121  {
122  return std::integral_constant<std::size_t, 0>{};
123  }
124  else if constexpr (std::tuple_size_v<std::decay_t<Arg>> == 1)
125  {
126  return collections::get(std::forward<Arg>(arg), std::move(i));
127  }
128  else //if constexpr (descriptor_tuple<Arg> and std::tuple_size_v<std::decay_t<Arg>> >= 2)
129  {
130  using Common = typename detail::common_descriptor_tuple_element<std::decay_t<Arg>>::type;
131  return collections::get(static_cast<Common>(std::forward<Arg>(arg)), std::move(i));
132  }
133  };
134 
135 
136 } // namespace OpenKalman::coordinates::internal
137 
138 #endif //OPENKALMAN_COORDINATES_GET_DESCRIPTOR_COLLECTION_ELEMENT_HPP
Definition: get_component_start_indices.hpp:29
Definition: tuple_reverse.hpp:103
Definition: get_descriptor_collection_element.hpp:42
Definition: get_descriptor_collection_element.hpp:76
Definition for coordinates::descriptor.
Definition: compares_with.hpp:28
Definition for pattern_range.
Definition: Any.hpp:41
Definition for coordinates::descriptor_collection.