OpenKalman
compare_indices.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 
16 #ifndef OPENKALMAN_COLLECTION_COMPARE_INDICES_HPP
17 #define OPENKALMAN_COLLECTION_COMPARE_INDICES_HPP
18 
19 #include "values/values.hpp"
23 
25 {
26  namespace detail
27  {
28  template<typename Lhs, typename Rhs>
29  constexpr auto
30  get_min_size(const Lhs& lhs, const Rhs& rhs)
31  {
32  if constexpr (sized<Lhs> and sized<Rhs>)
33  return values::operation([](const auto& a, const auto& b){ return std::min(a, b); }, get_size(lhs), get_size(rhs));
34  else if constexpr (sized<Lhs>)
35  return get_size(lhs);
36  else
37  return get_size(rhs);
38  }
39 
40 
41  template<typename Lhs, typename Rhs>
42  constexpr std::size_t
43  get_fixed_size()
44  {
45  constexpr bool fixed_lhs = values::fixed_value_compares_with<size_of<Lhs>, stdex::dynamic_extent, &stdex::is_neq>;
46  constexpr bool fixed_rhs = values::fixed_value_compares_with<size_of<Rhs>, stdex::dynamic_extent, &stdex::is_neq>;
47  if constexpr (fixed_lhs and fixed_rhs)
48  return std::min(size_of_v<Lhs>, size_of_v<Rhs>);
49  else if constexpr (fixed_lhs)
50  return size_of_v<Lhs>;
51  else if constexpr (fixed_rhs)
52  return size_of_v<Rhs>;
53  else
54  return stdex::dynamic_extent;
55  }
56 
57 
58  template<auto comp, std::size_t fsz, std::size_t i = 0, typename Lhs, typename Rhs, typename Sz>
59  constexpr auto
60  compare_indices_fixed(const Lhs& lhs, const Rhs& rhs, const Sz& sz)
61  {
62  using ix = std::integral_constant<std::size_t, i>;
63  auto c = [](const auto& a, const auto& b){ return stdex::invoke(comp, stdex::compare_three_way{}(a, b)); };
64 
65  if constexpr (values::size_compares_with<ix, Sz, &stdex::is_lt>)
66  return values::operation(
67  std::logical_and{},
68  values::operation(c, collections::get<i>(lhs), collections::get<i>(rhs)),
69  compare_indices_fixed<comp, fsz, i + 1>(lhs, rhs, sz));
70  else if constexpr (values::size_compares_with<ix, Sz, &stdex::is_gteq> or i >= fsz)
71  return std::true_type {};
72  else
73  {
74  if (i < sz)
75  return c(collections::get<i>(lhs), collections::get<i>(rhs)) and
76  compare_indices_fixed<comp, fsz, i + 1>(lhs, rhs, sz);
77  else
78  return true;
79  }
80  }
81 
82  }
83 
84 
90 #ifdef __cpp_concepts
91  template<auto comp = &stdex::is_eq, index Lhs, index Rhs> requires sized<Lhs> or sized<Rhs>
92  constexpr OpenKalman::internal::boolean_testable auto
93 #else
94  template<auto comp = &stdex::is_eq, typename Lhs, typename Rhs, std::enable_if_t<
95  index<Lhs> and index<Rhs> and (sized<Lhs> or sized<Rhs>), int> = 0>
96  constexpr auto
97 #endif
98  compare_indices(const Lhs& lhs, const Rhs& rhs)
99  {
100  auto sz = detail::get_min_size(lhs, rhs);
101  constexpr std::size_t fsz = detail::get_fixed_size<Lhs, Rhs>();
102 
103  if constexpr (fsz != stdex::dynamic_extent)
104  {
105  return detail::compare_indices_fixed<comp, fsz>(lhs, rhs, sz);
106  }
107  else
108  {
109  for (std::size_t i = 0; i < sz; ++i)
110  {
111  if (not stdex::invoke(comp, stdex::compare_three_way{}(collections::get_element(lhs, i), collections::get_element(rhs, i))))
112  return false;
113  }
114  return true;
115  }
116  }
117 
118 
119 }
120 
121 #endif
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
Header file for code relating to values (e.g., scalars and indices)
Definition: comparison.hpp:176
Definition for collections::size_of.
constexpr auto compare_indices(const Lhs &lhs, const Rhs &rhs)
Performs an element-by-element comparison of two index collections.
Definition: compare_indices.hpp:98
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 compare_three_way(A &&a, B &&b, const Comparison &c={})
Compare two coordinates::pattern objects lexicographically.
Definition: compare_three_way.hpp:142
Definition for collections::index.
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:188
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98