Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
gtest.hpp
Go to the documentation of this file.
1#pragma once
2
46
47#include "floating_eq.hpp"
48#include "trace.hpp"
49#include <gtest/gtest.h>
51
52namespace uni20::check::detail
53{
54template <class T> std::string floating_operand_text(T const& value) { return uni20::format_scalar(value); }
55
56#if UNI20_HAS_MPREAL
57inline std::string floating_operand_text(mpreal const& value)
58{
59 if (!value.initialized()) return "<unset>";
60 auto text = value.to_string();
61 return value.is_exact() ? text + " [exact]" : text + " [" + std::to_string(value.precision().bit_count()) + " bits]";
62}
63#endif
64
65template <UlpComparable T>
66::testing::AssertionResult floating_eq_assertion(char const* name, char const* left, char const* right, T const& a,
67 T const& b, std::int64_t ulps)
68{
69 if (ulps < 0) return ::testing::AssertionFailure() << name << " requires non-negative ULP tolerance, got " << ulps;
70 if (FloatingULP<T>::eq(a, b, ulps)) return ::testing::AssertionSuccess();
71
72 auto result = ::testing::AssertionFailure();
73 result << name << " failed\n " << left << " = " << floating_operand_text(a) << "\n " << right << " = "
74 << floating_operand_text(b) << "\n allowed tolerance: " << ulps << " ULP\n actual distance: ";
75 auto const distance = float_abs_distance(a, b);
76 if (distance == std::numeric_limits<long long>::max())
77 result << "unrepresentable or exceeds diagnostic range";
78 else
79 result << distance;
80#if UNI20_HAS_MPREAL
81 if constexpr (std::same_as<T, mpreal>)
82 if (auto reason = compare_mpreal(a, b, ulps).reason) result << "\n reason: " << reason;
83#endif
84 return result;
85}
86} // namespace uni20::check::detail
87
88#define EXPECT_FLOATING_EQ(a, b, ...) \
89 do \
90 { \
91 auto va = (a); \
92 auto vb = (b); \
93 auto ulps = ::trace::detail::get_ulps(va, vb __VA_OPT__(, __VA_ARGS__)); \
94 auto result = ::uni20::check::detail::floating_eq_assertion("EXPECT_FLOATING_EQ", #a, #b, va, vb, ulps); \
95 if (!result) \
96 { \
97 ADD_FAILURE() << result.message(); \
98 } \
99 } \
100 while (0)
101
102#define ASSERT_FLOATING_EQ(a, b, ...) \
103 do \
104 { \
105 auto va = (a); \
106 auto vb = (b); \
107 auto ulps = ::trace::detail::get_ulps(va, vb __VA_OPT__(, __VA_ARGS__)); \
108 auto result = ::uni20::check::detail::floating_eq_assertion("ASSERT_FLOATING_EQ", #a, #b, va, vb, ulps); \
109 if (!result) \
110 { \
111 FAIL() << result.message(); \
112 } \
113 } \
114 while (0)
locale_t value
Definition data_table.cpp:49
presentation::styled_text text
Definition display.cpp:141
std::string format_scalar(T const &value, scalar_format_options const &options={})
Format any Uni20 real or complex scalar.
Definition scalar_io.hpp:367
long long float_abs_distance(T a, T b)
Return the absolute diagnostic ULP distance between two real scalars.
Definition floating_eq.hpp:225