OpenKalman
tests.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) 2017-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_LINEAR_ALGEBRA_TESTS_HPP
17 #define OPENKALMAN_LINEAR_ALGEBRA_TESTS_HPP
18 
25 
26 namespace OpenKalman::test
27 {
28  // ------------------- //
29  // indexible objects //
30  // ------------------- //
31 
32 #ifdef __cpp_concepts
33  template<indexible Arg1, indexible Arg2, typename Err> requires
34  (index_count_v<Arg1> == index_count_v<Arg2>) and
35  (values::value<Err> or (indexible<Err> and index_count_v<Err> == index_count_v<Arg1>)) and
36  (not collections::collection<Arg1> or not collections::collection<Arg2>)
37  struct TestComparison<Arg1, Arg2, Err>
38 #else
39  template<typename Arg1, typename Arg2, typename Err>
40  struct TestComparison<Arg1, Arg2, Err, std::enable_if_t<
41  indexible<Arg1> and indexible<Arg2> and
42  (index_count<Arg1>::value == index_count<Arg2>::value) and
43  (values::value<Err> or indexible<Err>) and
44  (not collections::collection<Arg1> or not collections::collection<Arg2>)>>
45 #endif
46  : ::testing::AssertionResult
47  {
48  private:
49 
50  static constexpr auto
51  print_indices() { return std::string{"()"}; }
52 
53  template<typename I, typename...Is>
54  static constexpr auto
55  print_indices(I i, Is...is) { return std::string{"("} + (std::to_string(i) + ... + (", " + std::to_string(is))) + ")"; }
56 
57 
58  template<typename...Ix>
59  static ::testing::AssertionResult
60  compare_mdspan(const Arg1& arg1, const Arg2& arg2, const Err& err, Ix...ix)
61  {
62  constexpr std::size_t ind = sizeof...(Ix);
63  if constexpr (ind < index_count_v<Arg1>)
64  {
65  auto dim1 = get_index_extent<ind>(arg1);
66  auto dim2 = get_index_extent<ind>(arg2);
67  if (dim1 != dim2) return ::testing::AssertionFailure() << "Dimensions do not match for index" <<
68  std::to_string(ind) << " (" << std::to_string(dim1) << " != " << std::to_string(dim2) << ")";
69  std::string msg = "";
70  for (std::size_t i = 0; i < get_index_extent<ind>(arg1); ++i)
71  msg += compare_mdspan(arg1, arg2, err, ix..., i).message();
72  if (msg.size() == 0) return ::testing::AssertionSuccess();
73  return ::testing::AssertionFailure() << msg;
74  }
75  else
76  {
77  auto indices = std::array{ix...};
78  auto e = [&]{ if constexpr (indexible<Err>) return err[indices]; else return err; }();
79  auto res = test::TestComparison {get_mdspan(arg1)[indices], get_mdspan(arg2)[indices], e};
80  if (res) return ::testing::AssertionSuccess();
81  return ::testing::AssertionFailure() << print_indices(ix...) << ": " << res.message() << std::endl;
82  }
83  }
84 
85  public:
86 
87  TestComparison(const Arg1& arg1, const Arg2& arg2, const Err& err)
88  : ::testing::AssertionResult {compare_mdspan(arg1, arg2, err)} {};
89 
90  };
91 
92 
93 }
94 
95 
96 #endif
constexpr auto get_mdspan(T &t)
Get the coordinates::pattern_collection associated with indexible object T.
Definition: get_mdspan.hpp:35
Definition of get_index_extent function.
Definition: tests.hpp:36
Definition: tests.hpp:22
Inclusion file for collections.
Definition of get_mdspan function.
Definition for index_count.
Definition for indexible.