OpenKalman
get_common_pattern_collection_dimension.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-2026 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_PATTERNS_GET_COMMON_PATTERN_COLLECTION_DIMENSION_HPP
17 #define OPENKALMAN_PATTERNS_GET_COMMON_PATTERN_COLLECTION_DIMENSION_HPP
18 
19 #include <optional>
26 
27 namespace OpenKalman::patterns
28 {
29  namespace detail
30  {
31 #ifndef __cpp_concepts
32  template<typename T, typename = void>
33  struct patt_dim_is_fixed : std::false_type {};
34 
35  template<typename T>
36  struct patt_dim_is_fixed<T, std::enable_if_t<fixed_pattern<typename T::type>>>
37  : std::true_type {};
38 #endif
39 
40 
41  template<std::size_t n, std::size_t i = 0, typename T>
42  constexpr auto
43  collection_patterns_have_same_dimension_impl(const T& t)
44  {
45  auto d0 = get_dimension(get_pattern<i>(t));
46  if constexpr (i + 1 < n)
47  {
48  auto tail = collection_patterns_have_same_dimension_impl<n, i + 1>(t);
49  using tail_type = typename decltype(tail)::value_type;
50 
51  if constexpr (values::size_compares_with<decltype(d0), tail_type>)
52  return std::optional {d0};
53  else if (tail and *tail == values::to_value_type(d0))
54  return std::optional<std::size_t> {d0};
55  else
56  return std::optional<std::size_t> {};
57  }
58  else return std::optional {d0};
59  }
60 
61  }
62 
63 
72 #ifdef __cpp_concepts
73  template<auto N = values::unbounded_size, pattern_collection T> requires
74  (values::integral<decltype(N)> or stdex::same_as<std::decay_t<decltype(N)>, values::unbounded_size_t>) and
75  (not values::integral<decltype(N)> or N > 0)
76 #else
77  template<std::size_t N = values::unbounded_size, typename T, std::enable_if_t<
78  (N == values::unbounded_size or N > 0) and pattern_collection<T>, int> = 0>
79 #endif
80  constexpr auto
82  {
83  constexpr bool has_fixed_common =
84 #ifdef __cpp_concepts
85  requires { requires fixed_pattern<collections::common_collection_type_t<T>>; };
86 #else
88 #endif
89 
90  if constexpr (collections::sized<T>)
91  {
92  // n is the true number of elements that will be compared.
93  auto n = [](const T& t){
94 #ifdef __cpp_concepts
95  if constexpr (stdex::same_as<std::decay_t<decltype(N)>, values::unbounded_size_t>)
96 #else
97  if constexpr (N == std::size_t(values::unbounded_size))
98 #endif
99  return collections::get_size(t);
100  else
101  return std::integral_constant<std::size_t, N>{};
102  }(t);
103  using n_type = decltype(n);
104 
105  if constexpr (values::fixed<n_type>)
106  {
107  if constexpr (has_fixed_common and values::size_compares_with<n_type, collections::size_of<T>, &stdex::is_lteq>)
109  else
110  return detail::collection_patterns_have_same_dimension_impl<values::fixed_value_of_v<n_type>>(t);
111  }
112  else
113  {
114  using Op = std::optional<std::size_t>;
115  std::size_t d = get_dimension(get_pattern<0>(t));
116  for (std::size_t i = 1; i < n; ++i) if (get_dimension(get_pattern(t, i)) != d) return Op{};
117  return Op{d};
118  }
119  }
120  else
121  {
122  if constexpr (has_fixed_common)
124  else
125  return std::optional<std::size_t> {};
126  }
127 
128  }
129 
130 
131 }
132 
133 #endif
Definition for pattern_collection.
The size of a patterns::pattern.
Definition: dimension_of.hpp:36
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:224
decltype(auto) constexpr get_pattern(P &&p, I i)
Get a pattern within a pattern_collection.
Definition: get_pattern.hpp:39
Definition: get_common_pattern_collection_dimension.hpp:33
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
Definition for patterns::get_pattern.
Definition for patterns::fixed_pattern.
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
The namespace for features relating to patterns::pattern object.
Definition: collection_compares_with.hpp:24
constexpr auto get_common_pattern_collection_dimension(const T &t)
Queries whether the first N elements of a pattern_collection have the same dimensions.
Definition: get_common_pattern_collection_dimension.hpp:81
Inclusion file for collections.
A type reflecting an unbound size.
Definition: size.hpp:27
constexpr bool size_compares_with
T and U are sizes that compare in a particular way based on parameter comp.
Definition: size_compares_with.hpp:98
constexpr bool integral
T is an integral value.
Definition: integral.hpp:47
Definition for patterns::get_dimension.
constexpr unbounded_size_t unbounded_size
An instance of unbounded_size_t;.
Definition: size.hpp:60
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of patterns::pattern Arg.
Definition: get_dimension.hpp:53
Definition for patterns::dimension_of.