16 #ifndef OPENKALMAN_LINEAR_ALGEBRA_TESTS_HPP 17 #define OPENKALMAN_LINEAR_ALGEBRA_TESTS_HPP 33 template<indexible Arg1, indexible Arg2,
typename Err> requires
34 (values::value<Err> or indexible<Err>) and
35 (not collections::collection<Arg1> or not collections::collection<Arg2>)
36 struct TestComparison<Arg1, Arg2, Err>
38 template<typename Arg1, typename Arg2, typename Err>
40 indexible<Arg1> and indexible<Arg2> and
41 (values::value<Err> or indexible<Err>) and
42 (not collections::collection<Arg1> or not collections::collection<Arg2>)>>
44 : ::testing::AssertionResult
48 static_assert(not indexible<Err> or
51 static constexpr std::size_t
52 rank1 = std::decay_t<decltype(get_mdspan(std::declval<Arg1&>()))>::rank();
54 static constexpr std::size_t
55 rank2 = std::decay_t<decltype(get_mdspan(std::declval<Arg2&>()))>::rank();
58 template<
typename Indices>
62 template<
typename Indices, std::size_t i, std::size_t...is>
66 return std::string{
"("} + (std::to_string(std::get<i>(indices)) + ... + (
", " + std::to_string(std::get<is>(indices)))) +
")";
70 template<
typename Indices, std::size_t...i1, std::size_t...i2>
71 static ::testing::AssertionResult
72 compare_element(
const Arg1& arg1,
const Arg2& arg2,
const Err& e,
const Indices& indices,
75 auto indices1 = std::array {std::get<i1>(indices)...};
76 auto indices2 = std::array {std::get<i2>(indices)...};
78 if (res) return ::testing::AssertionSuccess();
79 constexpr
auto seq = std::make_index_sequence<std::max(rank1, rank2)>{};
80 return ::testing::AssertionFailure() << print_indices(indices, seq) <<
": " << res.message() << std::endl;
84 template<
typename...Ix>
85 static ::testing::AssertionResult
86 compare_mdspan(
const Arg1& arg1,
const Arg2& arg2,
const Err& err, Ix...ix)
88 constexpr std::size_t ind =
sizeof...(Ix);
89 if constexpr (ind < std::min(rank1, rank2))
91 auto dim1 = get_index_extent<ind>(arg1);
92 auto dim2 = get_index_extent<ind>(arg2);
93 if (dim1 != dim2) return ::testing::AssertionFailure() <<
"Dimensions do not match for index " <<
94 std::to_string(ind) <<
": " << std::to_string(dim1) <<
" != " << std::to_string(dim2) <<
")";
96 for (std::size_t i = 0; i < dim1; ++i) msg += compare_mdspan(arg1, arg2, err, ix..., i).message();
97 if (msg.size() == 0) return ::testing::AssertionSuccess();
98 return ::testing::AssertionFailure() << msg;
100 else if constexpr (ind < std::max(rank1, rank2))
102 auto dim = rank2 > rank1 ? get_index_extent<ind>(arg2) : get_index_extent<ind>(arg1);
103 if (dim != 1) return ::testing::AssertionFailure() <<
"Dimensions do not match for index" <<
104 std::to_string(ind) <<
" (" << (rank2 > rank1 ?
"1" : std::to_string(dim)) <<
" != " << (rank2 < rank1 ?
"1" : std::to_string(dim)) <<
")";
105 std::string msg = compare_mdspan(arg1, arg2, err, ix..., 0_uz).message();
106 if (msg.size() == 0) return ::testing::AssertionSuccess();
107 return ::testing::AssertionFailure() << msg;
111 auto indices = std::array{ix...};
112 auto e = [&]{
if constexpr (indexible<Err>)
return err[indices];
else return err; }();
113 return compare_element(arg1, arg2, e, indices, std::make_index_sequence<rank1>{}, std::make_index_sequence<rank2>{});
119 TestComparison(
const Arg1& arg1,
const Arg2& arg2,
const Err& err)
120 : ::testing::AssertionResult {compare_mdspan(arg1, arg2, err)} {};
Definition of get_index_extent function.
Inclusion file for collections.
Definition of get_mdspan function.
Definition for index_count.
Definition: trait_backports.hpp:64
constexpr bool fixed_value_compares_with
T has a fixed value that compares with N in a particular way based on parameter comp.
Definition: fixed_value_compares_with.hpp:74
Definition for indexible.
The minimum number of indices needed to access all the components of an object (i.e., the rank or order).
Definition: index_count.hpp:34
decltype(auto) constexpr get_mdspan(T &&t)
Get the mdspan associated with indexible object T.
Definition: get_mdspan.hpp:35