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  struct Op
33  {
34  constexpr auto
35  operator()(std::size_t a, std::size_t b) const { return std::min(a, b); }
36  };
37 
38  if constexpr (sized<Lhs> and sized<Rhs>)
39  return values::operation(Op{}, get_size(lhs), get_size(rhs));
40  else if constexpr (sized<Lhs>)
41  return get_size(lhs);
42  else
43  return get_size(rhs);
44  }
45 
46 
47  template<typename Lhs, typename Rhs>
48  constexpr std::size_t
49  get_fixed_size()
50  {
51  constexpr bool fixed_lhs = values::fixed_value_compares_with<size_of<Lhs>, stdex::dynamic_extent, &stdex::is_neq>;
52  constexpr bool fixed_rhs = values::fixed_value_compares_with<size_of<Rhs>, stdex::dynamic_extent, &stdex::is_neq>;
53  if constexpr (fixed_lhs and fixed_rhs)
54  return std::min(size_of_v<Lhs>, size_of_v<Rhs>);
55  else if constexpr (fixed_lhs)
56  return size_of_v<Lhs>;
57  else if constexpr (fixed_rhs)
58  return size_of_v<Rhs>;
59  else
60  return stdex::dynamic_extent;
61  }
62 
63 
64  template<auto comp>
66  {
67  template<typename A, typename B>
68  constexpr auto operator()(const A& a, const B& b) const
69  {
70  return stdex::invoke(comp, stdex::compare_three_way{}(a, b));
71  }
72  };
73 
74 
75  template<auto comp, std::size_t fsz, std::size_t i = 0, typename Lhs, typename Rhs, typename Sz>
76  constexpr auto
77  compare_indices_fixed(const Lhs& lhs, const Rhs& rhs, const Sz& sz)
78  {
79  using ix = std::integral_constant<std::size_t, i>;
80 
81  if constexpr (values::size_compares_with<ix, Sz, &stdex::is_lt>)
82  return values::operation(
83  std::logical_and{},
84  values::operation(compare_indices_fixed_op<comp>{}, collections::get<i>(lhs), collections::get<i>(rhs)),
85  compare_indices_fixed<comp, fsz, i + 1>(lhs, rhs, sz));
86  else if constexpr (values::size_compares_with<ix, Sz, &stdex::is_gteq> or i >= fsz)
87  return std::true_type {};
88  else
89  {
90  if (i < sz)
91  return compare_indices_fixed_op<comp>{}(collections::get<i>(lhs), collections::get<i>(rhs)) and
92  compare_indices_fixed<comp, fsz, i + 1>(lhs, rhs, sz);
93  else
94  return true;
95  }
96  }
97 
98  }
99 
100 
106 #ifdef __cpp_concepts
107  template<auto comp = &stdex::is_eq, index Lhs, index Rhs> requires sized<Lhs> or sized<Rhs>
108  constexpr OpenKalman::internal::boolean_testable auto
109 #else
110  template<auto comp = &stdex::is_eq, typename Lhs, typename Rhs, std::enable_if_t<
111  index<Lhs> and index<Rhs> and (sized<Lhs> or sized<Rhs>), int> = 0>
112  constexpr auto
113 #endif
114  compare_indices(const Lhs& lhs, const Rhs& rhs)
115  {
116  auto sz = detail::get_min_size(lhs, rhs);
117  constexpr std::size_t fsz = detail::get_fixed_size<Lhs, Rhs>();
118 
119  if constexpr (fsz != stdex::dynamic_extent)
120  {
121  return detail::compare_indices_fixed<comp, fsz>(lhs, rhs, sz);
122  }
123  else
124  {
125  for (std::size_t i = 0; i < sz; ++i)
126  {
127  if (not stdex::invoke(comp, stdex::compare_three_way{}(collections::get_element(lhs, i), collections::get_element(rhs, i))))
128  return false;
129  }
130  return true;
131  }
132  }
133 
134 
135 }
136 
137 #endif
Namespace for collections.
Definition: collections.hpp:27
Definition for collections::get.
constexpr auto get_size(Arg &&arg)
Get the size of a sized object (e.g, a collection)
Definition: get_size.hpp:224
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:114
decltype(auto) constexpr get_element(Arg &&arg, I i)
A generalization of std::get and the range subscript operator.
Definition: get_element.hpp:124
Definition for collections::index.
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98