OpenKalman
Dimensions.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) 2022-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 
16 #ifndef OPENKALMAN_DIMENSIONS_HPP
17 #define OPENKALMAN_DIMENSIONS_HPP
18 
19 #include <cstddef>
21 #include "coordinates/interfaces/coordinate_descriptor_traits.hpp"
27 #include "Any.hpp"
28 
30 {
31  // ------------ //
32  // fixed case //
33  // ------------ //
34 
41  template<std::size_t N = stdex::dynamic_extent>
42  struct Dimensions
43  {
45  constexpr Dimensions() = default;
46 
47 
49 #ifdef __cpp_concepts
50  template<euclidean_pattern D> requires
51  (dimension_of<D>::value == N) and
52  (not std::same_as<D, Dimensions>)
53 #else
54  template<typename D, std::enable_if_t<
55  euclidean_pattern<D> and
56  values::fixed_value_compares_with<dimension_of<D>, N> and
57  not std::is_same_v<D, Dimensions>, int> = 0>
58 #endif
59  constexpr Dimensions(const D&) {}
60 
61 
62  template<typename Int>
63  explicit constexpr operator std::integral_constant<Int, N>()
64  {
65  return std::integral_constant<Int, N>{};
66  }
67 
68 
69 #ifdef __cpp_concepts
70  template<std::integral Int>
71 #else
72  template<typename Int, std::enable_if_t<std::is_integral_v<Int>, int> = 0>
73 #endif
74  explicit constexpr operator Int()
75  {
76  return N;
77  }
78 
79  }; // struct Dimensions, static case
80 
81 
82  // -------------- //
83  // dynamic case //
84  // -------------- //
85 
90  template<>
91  struct Dimensions<stdex::dynamic_extent>
92  {
94 #ifdef __cpp_concepts
95  template<euclidean_pattern D> requires (not std::same_as<D, Dimensions>)
96 #else
97  template<typename D, std::enable_if_t<euclidean_pattern<D> and (not std::is_same_v<Dimensions, D>), int> = 0>
98 #endif
99  constexpr Dimensions(const D& d) : runtime_size {get_dimension(d)}
100  {}
101 
102 
104  constexpr Dimensions(const std::size_t& d = 0) : runtime_size {static_cast<std::size_t>(d)}
105  {}
106 
107 
111 #ifdef __cpp_concepts
112  template<euclidean_pattern D> requires (not std::same_as<D, Dimensions>)
113 #else
114  template<typename D, std::enable_if_t<euclidean_pattern<D> and (not std::is_same_v<D, Dimensions>), int> = 0>
115 #endif
116  constexpr Dimensions& operator=(const D& d)
117  {
118  runtime_size = get_dimension(d);
119  return *this;
120  }
121 
122 
123 #ifdef __cpp_concepts
124  template<std::integral Int>
125 #else
126  template<typename Int, std::enable_if_t<std::is_integral_v<Int>, int> = 0>
127 #endif
128  explicit constexpr operator Int()
129  {
130  return runtime_size;
131  }
132 
133  protected:
134 
135  std::size_t runtime_size;
136 
137  friend struct interface::coordinate_descriptor_traits<Dimensions>;
138  };
139 
140 
141  // ------------------ //
142  // deduction guides //
143  // ------------------ //
144 
145 #ifdef __cpp_concepts
146  template<fixed_pattern D> requires euclidean_pattern<D>
147 #else
148  template<typename D, std::enable_if_t<fixed_pattern<D> and euclidean_pattern<D>, int> = 0>
149 #endif
151 
152 
153 #ifdef __cpp_concepts
154  template<dynamic_pattern D> requires euclidean_pattern<D>
155 #else
156  template<typename D, std::enable_if_t<dynamic_pattern<D> and euclidean_pattern<D>, int> = 0>
157 #endif
159 
160 
161  explicit Dimensions(const std::size_t&) -> Dimensions<stdex::dynamic_extent>;
162 
163 
164  // ------ //
165  // Axis //
166  // ------ //
167 
172 
173 }
174 
175 
176 namespace OpenKalman::interface
177 {
182  template<std::size_t N>
183  struct coordinate_descriptor_traits<coordinates::Dimensions<N>>
184  {
185  private:
186 
188 
189  public:
190 
191  static constexpr bool is_specialized = true;
192 
193 
194  static constexpr auto
195  dimension = [](const T& t)
196  {
197  if constexpr (N == stdex::dynamic_extent) return t.runtime_size;
198  else return std::integral_constant<std::size_t, N>{};
199  };
200 
201 
202  static constexpr auto
203  stat_dimension = [](const T& t) { return dimension(t); };
204 
205 
206  static constexpr auto
207  is_euclidean = [](const T&) { return std::true_type{}; };
208 
209 
210  static constexpr auto
211  hash_code = [](const T& t)
212  {
213  if constexpr (N == stdex::dynamic_extent)
214  return static_cast<std::size_t>(t.runtime_size);
215  else
216  return std::integral_constant<std::size_t, N>{};
217  };
218 
219  };
220 
221 }
222 
223 
224 namespace std
225 {
226  template<std::size_t M, std::size_t N>
227  struct common_type<OpenKalman::coordinates::Dimensions<M>, OpenKalman::coordinates::Dimensions<N>>
228  {
230  };
231 
232 
233  template<std::size_t N, typename T>
234  struct common_type<OpenKalman::coordinates::Dimensions<N>, T>
235  : std::conditional_t<
236  OpenKalman::coordinates::descriptor<T>,
237  std::conditional<OpenKalman::coordinates::euclidean_pattern<T>,
238  OpenKalman::coordinates::Dimensions<N == OpenKalman::coordinates::dimension_of_v<T> ? N : OpenKalman::stdex::dynamic_extent>,
239  OpenKalman::coordinates::Any<>>,
240  std::monostate> {};
241 
242 
243  template<std::size_t N, typename Scalar>
244  struct common_type<OpenKalman::coordinates::Dimensions<N>, OpenKalman::coordinates::Any<Scalar>>
245  {
247  };
248 
249 
250  template<std::size_t N, typename Scalar>
251  struct common_type<OpenKalman::coordinates::Any<Scalar>, OpenKalman::coordinates::Dimensions<N>>
252  {
254  };
255 
256 
257 #ifdef __cpp_concepts
258  template<OpenKalman::coordinates::euclidean_pattern T, std::size_t N>
259  struct common_type<T, OpenKalman::coordinates::Dimensions<N>> : common_type<OpenKalman::coordinates::Dimensions<N>, T> {};
260 #endif
261 }
262 
263 #ifndef __cpp_concepts
264 #define OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(I) \
265 namespace std \
266 { \
267  template<std::size_t N> \
268  struct common_type<I, OpenKalman::coordinates::Dimensions<N>> \
269  : common_type<OpenKalman::coordinates::Dimensions<N>, I> {}; \
270 }
271 
272 OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(unsigned char)
273 OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(unsigned short)
274 OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(unsigned int)
275 OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(unsigned long)
276 OPENKALMAN_INDEX_STD_COMMON_TYPE_SPECIALIZATION(unsigned long long)
277 
278 namespace std
279 {
280  template<typename T, auto M, std::size_t N>
281  struct common_type<std::integral_constant<T, M>, OpenKalman::coordinates::Dimensions<N>>
282  : common_type<OpenKalman::coordinates::Dimensions<N>, std::integral_constant<T, M>> {};
283 
284 
285  template<typename T, auto...M, std::size_t N>
286  struct common_type<OpenKalman::values::fixed_value<T, M...>, OpenKalman::coordinates::Dimensions<N>>
287  : common_type<OpenKalman::coordinates::Dimensions<N>, OpenKalman::values::fixed_value<T, M...>> {};
288 
289 
290  template<typename...Args, std::size_t N>
291  struct common_type<OpenKalman::values::consteval_operation<Args...>, OpenKalman::coordinates::Dimensions<N>>
292  : common_type<OpenKalman::coordinates::Dimensions<N>, OpenKalman::values::consteval_operation<Args...>> {};
293 }
294 #endif
295 
296 
297 #endif
Definition for coordinates::euclidean_pattern.
Definition: basics.hpp:41
Definition for coordinates::dynamic_pattern.
Definition for coordinates::fixed_pattern.
The size of a coordinates::pattern.
Definition: dimension_of.hpp:36
constexpr Dimensions & operator=(const D &d)
Assign from another coordinates::euclidean_pattern or dynamic_pattern.
Definition: Dimensions.hpp:116
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of coordinates::pattern Arg.
Definition: get_dimension.hpp:54
constexpr Dimensions(const D &d)
Construct from a coordinates::euclidean_pattern or dynamic_pattern.
Definition: Dimensions.hpp:99
The root namespace for OpenKalman.
Definition: basics.hpp:34
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
constexpr Dimensions(const D &)
Constructor, taking a fixed-dimension euclidean_pattern.
Definition: Dimensions.hpp:59
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: Dimensions.hpp:91
Inclusion file for collections.
constexpr Dimensions(const std::size_t &d=0)
Construct from an integral value.
Definition: Dimensions.hpp:104
Traits for coordinates::pattern objects.
Definition: coordinate_descriptor_traits.hpp:36
Definition for coordinates::get_dimension.
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
constexpr Dimensions()=default
Default constructor.
consteval_operation(const Operation &, const Args &...) -> consteval_operation< Operation, Args... >
Deduction guide.
Definition: Any.hpp:42
Definition for coordinates::dimension_of.