OpenKalman
compare_pattern_collections.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 b 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 
16 #ifndef OPENKALMAN_COORDINATES_COMPARE_PATTERN_COLLECTIONS_HPP
17 #define OPENKALMAN_COORDINATES_COMPARE_PATTERN_COLLECTIONS_HPP
18 
24 
26 {
27  namespace detail
28  {
29  template<auto comp, std::size_t i = 0_uz, typename A, typename B>
30  constexpr auto
31  compare_pattern_collections_a_tail(const A& a, const B& b)
32  {
33  constexpr auto ix = std::integral_constant<std::size_t, i>{};
34  if constexpr (i < collections::size_of_v<A>)
35  return compare<comp>(collections::get<ix>(a), Dimensions<1>{}) and
36  compare_pattern_collections_a_tail<comp, i + 1>(a, b);
37  else
38  return std::true_type {};
39  }
40 
41 
42  template<auto comp, std::size_t i = 0_uz, typename A, typename B>
43  constexpr auto
44  compare_pattern_collections_b_tail(const A& a, const B& b)
45  {
46  if constexpr (i < collections::size_of_v<B>)
47  return compare<comp>(Dimensions<1>{}, collections::get<i>(b)) and
48  compare_pattern_collections_b_tail<comp, i + 1>(a, b);
49  else
50  return std::true_type {};
51  }
52 
53 
54  template<auto comp, std::size_t i = 0_uz, typename A, typename B>
55  constexpr auto
56  compare_pattern_collections_iter_a(const A& a, const B& b)
57  {
58  std::size_t size_b = collections::get_size(b);
59  if constexpr (i < collections::size_of_v<A>)
60  {
61  if (i < size_b)
62  return compare<comp>(collections::get<i>(a), collections::get<i>(b)) and
63  compare_pattern_collections_iter_a<comp, i + 1>(a, b);
64  else
65  return compare_pattern_collections_a_tail<comp, i>(a, b);
66  }
67  else
68  {
69  for (std::size_t j = i; j < size_b; ++j)
70  if (not compare<comp>(Dimensions<1>{}, collections::get_element(b, j))) return false;
71  return true;
72  }
73  }
74 
75 
76  template<auto comp, std::size_t i = 0_uz, typename A, typename B>
77  constexpr auto
78  compare_pattern_collections_iter_b(const A& a, const B& b)
79  {
80  constexpr auto ix = std::integral_constant<std::size_t, i>{};
81  std::size_t size_a = collections::get_size(a);
82  if constexpr (i < collections::size_of_v<B>)
83  {
84  if (i < size_a)
85  return compare<comp>(collections::get_element(a, ix), collections::get_element(b, ix)) and
86  compare_pattern_collections_iter_b<comp, i + 1>(a, b);
87  else
88  return compare_pattern_collections_b_tail<comp, i>(a, b);
89  }
90  else
91  {
92  for (std::size_t j = i; j < size_a; ++j)
93  if (not compare<comp>(collections::get_element(a, j), Dimensions<1>{})) return false;
94  return true;
95  }
96  }
97 
98 
99  template<auto comp, std::size_t i = 0_uz, typename A, typename B>
100  constexpr auto
101  compare_pattern_collections_iter(const A& a, const B& b)
102  {
103  constexpr auto ix = std::integral_constant<std::size_t, i>{};
104  if constexpr (i < collections::size_of_v<A>)
105  {
106  if constexpr (i < collections::size_of_v<B>)
107  return compare<comp>(collections::get_element(a, ix), collections::get_element(b, ix)) and
108  compare_pattern_collections_iter<comp, i + 1>(a, b);
109  else
110  return compare_pattern_collections_a_tail<comp, i>(a, b);
111  }
112  else
113  {
114  return compare_pattern_collections_b_tail<comp, i>(a, b);
115  }
116  }
117 
118  }
119 
120 
127 #ifdef __cpp_concepts
128  template<auto comp = &stdex::is_eq, pattern_collection A, pattern_collection B> requires
129  std::is_invocable_r_v<bool, decltype(comp), stdex::partial_ordering>
130  constexpr OpenKalman::internal::boolean_testable auto
131 #else
132  template<auto comp = &stdex::is_eq, typename A, typename B, std::enable_if_t<
133  pattern_collection<A> and pattern_collection<B> and
134  std::is_invocable_r_v<bool, decltype(comp), stdex::partial_ordering>, int> = 0>
135 constexpr auto
136 #endif
137  compare_pattern_collections(const A& a, const B& b)
138  {
139  if constexpr (pattern_collection_compares_with<A, B, comp, applicability::guaranteed>)
140  {
141  return std::true_type {};
142  }
143  else if constexpr (not pattern_collection_compares_with<A, B, comp, applicability::permitted> or
144  not collections::sized<A> or not collections::sized<B>)
145  {
146  return std::false_type {};
147  }
148  else if constexpr (collections::size_of_v<A> == stdex::dynamic_extent and collections::size_of_v<B> == stdex::dynamic_extent)
149  {
150  std::size_t size_a = collections::get_size(a);
151  std::size_t size_b = collections::get_size(b);
152  std::size_t i = 0;
153  for (; i < size_a and i < size_b; ++i)
154  if (not compare<comp>(collections::get_element(a, i), collections::get_element(b, i))) return false;
155  for (; i < size_a; ++i)
156  if (not compare<comp>(collections::get_element(a, i), Dimensions<1>{})) return false;
157  for (; i < size_b; ++i)
158  if (not compare<comp>(Dimensions<1>{}, collections::get_element(b, i))) return false;
159  return true;
160  }
161  else if constexpr (collections::size_of_v<B> == stdex::dynamic_extent)
162  {
163  return detail::compare_pattern_collections_iter_a<comp>(a, b);
164  }
165  else if constexpr (collections::size_of_v<A> == stdex::dynamic_extent)
166  {
167  return detail::compare_pattern_collections_iter_b<comp>(a, b);
168  }
169  else
170  {
171  return detail::compare_pattern_collections_iter<comp>(a, b);
172  }
173  }
174 
175 }
176 
177 #endif
Definition for pattern_collection.
Definition of the Dimensions class.
Definition for pattern_collection_compares_with.
Definition of coordinates::compare.
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Inclusion file for collections.
constexpr auto compare_pattern_collections(const A &a, const B &b)
Compare each element of two pattern_collection objects lexicographically.
Definition: compare_pattern_collections.hpp:137
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:122
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:188