OpenKalman
compare_collection_patterns_with_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_COMPARE_COLLECTION_PATTERNS_WITH_DIMENSION_HPP
17 #define OPENKALMAN_PATTERNS_COMPARE_COLLECTION_PATTERNS_WITH_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 has_fixed_patt_dim : std::false_type {};
34 
35  template<typename T>
36  struct has_fixed_patt_dim<T, std::enable_if_t<fixed_pattern<typename T::type>>>
37  : std::true_type {};
38 #endif
39 
40 
41  template<auto comp>
42  constexpr auto
43  do_compare = [](const auto& a, const auto& b) {
44  return stdex::invoke(comp, stdex::compare_three_way{}(a, b));
45  };
46 
47 
48  template<std::size_t n, auto comp, std::size_t i = 0, typename T, typename D>
49  constexpr auto
50  compare_collection_patterns_with_dimension_impl(const T& t, const D& d)
51  {
52  if constexpr (i < n)
53  return values::operation(
54  std::logical_and{},
55  values::operation(do_compare<comp>, get_dimension(get_pattern<i>(t)), d),
56  compare_collection_patterns_with_dimension_impl<n, comp, i + 1>(t, d));
57  else
58  return std::true_type {};
59  }
60 
61  }
62 
63 
70 #ifdef __cpp_concepts
71  template<auto comp = &stdex::is_eq, auto N = values::unbounded_size, pattern_collection T, values::index D> requires
72  (values::integral<decltype(N)> or stdex::same_as<std::decay_t<decltype(N)>, values::unbounded_size_t>) and
73  (not values::integral<decltype(N)> or N > 0)
74  constexpr OpenKalman::internal::boolean_testable auto
75 #else
76  template<auto comp = &stdex::is_eq, std::size_t N = values::unbounded_size, typename T, typename D, std::enable_if_t<
77  (N == values::unbounded_size or N > 0) and pattern_collection<T> and values::index<D>, int> = 0>
78  constexpr auto
79 #endif
81  {
82  constexpr bool has_fixed_common =
83 #ifdef __cpp_concepts
84  requires { requires fixed_pattern<collections::common_collection_type_t<T>>; };
85 #else
87 #endif
88 
89  if constexpr (collections::sized<T>)
90  {
91  // n is the true number of elements that will be compared.
92  auto n = [](const T& t){
93 #ifdef __cpp_concepts
94  if constexpr (stdex::same_as<std::decay_t<decltype(N)>, values::unbounded_size_t>)
95 #else
96  if constexpr (N == std::size_t(values::unbounded_size))
97 #endif
98  return collections::get_size(t);
99  else
100  return std::integral_constant<std::size_t, N>{};
101  }(t);
102  using n_type = decltype(n);
103 
104  if constexpr (values::fixed<n_type>)
105  {
106  if constexpr (has_fixed_common and values::size_compares_with<n_type, collections::size_of<T>, &stdex::is_lteq>)
107  return values::operation(detail::do_compare<comp>, dimension_of<collections::common_collection_type_t<T>>{}, d);
108  else
109  return detail::compare_collection_patterns_with_dimension_impl<values::fixed_value_of_v<n_type>, comp>(t, d);
110  }
111  else
112  {
113  for (std::size_t i = 0; i < n; ++i)
114  if (not detail::do_compare<comp>(get_dimension(get_pattern(t, i)), values::to_value_type(d))) return false;
115  return true;
116  }
117  }
118  else if constexpr (has_fixed_common)
119  {
120  return values::operation(detail::do_compare<comp>, dimension_of<collections::common_collection_type_t<T>>{}, d);
121  }
122  else
123  {
124  return std::false_type {};
125  }
126 
127  }
128 
129 
133 #ifdef __cpp_concepts
134 template<std::size_t dim, auto comp = &stdex::is_eq, auto N = values::unbounded_size, pattern_collection T> requires
135  (values::integral<decltype(N)> or stdex::same_as<std::decay_t<decltype(N)>, values::unbounded_size_t>) and
136  (not values::integral<decltype(N)> or N > 0)
137 constexpr OpenKalman::internal::boolean_testable auto
138 #else
139 template<std::size_t dim, auto comp = &stdex::is_eq, std::size_t N = values::unbounded_size, typename T, std::enable_if_t<
140  (N == values::unbounded_size or N > 0) and pattern_collection<T>, int> = 0>
141 constexpr auto
142 #endif
144  {
145  return compare_collection_patterns_with_dimension<comp, N>(t, std::integral_constant<std::size_t, dim>{});
146  }
147 
148 
149 }
150 
151 #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: comparison.hpp:176
typename common_collection_type< T >::type common_collection_type_t
Helper template for common_collection_type.
Definition: common_collection_type.hpp:81
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 compare_collection_patterns_with_dimension(const T &t, const D &d)
Compares the dimensions of the first N elements of a pattern_collection with a particular value...
Definition: compare_collection_patterns_with_dimension.hpp:80
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
Definition: compare_collection_patterns_with_dimension.hpp:33
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of patterns::pattern Arg.
Definition: get_dimension.hpp:53
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98
Definition for patterns::dimension_of.