1 //===-- TestMatchers.h ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
10 #define LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
11 
12 #include "src/__support/FPUtil/FPBits.h"
13 
14 #include "utils/UnitTest/Test.h"
15 
16 namespace __llvm_libc {
17 namespace fputil {
18 namespace testing {
19 
20 template <typename ValType, typename StreamType>
21 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void>
22 describeValue(const char *label, ValType value, StreamType &stream);
23 
24 template <typename T, __llvm_libc::testing::TestCondition Condition>
25 class FPMatcher : public __llvm_libc::testing::Matcher<T> {
26   static_assert(__llvm_libc::cpp::IsFloatingPointType<T>::Value,
27                 "FPMatcher can only be used with floating point values.");
28   static_assert(Condition == __llvm_libc::testing::Cond_EQ ||
29                     Condition == __llvm_libc::testing::Cond_NE,
30                 "Unsupported FPMathcer test condition.");
31 
32   T expected;
33   T actual;
34 
35 public:
36   FPMatcher(T expectedValue) : expected(expectedValue) {}
37 
38   bool match(T actualValue) {
39     actual = actualValue;
40     fputil::FPBits<T> actualBits(actual), expectedBits(expected);
41     if (Condition == __llvm_libc::testing::Cond_EQ)
42       return (actualBits.is_nan() && expectedBits.is_nan()) ||
43              (actualBits.uintval() == expectedBits.uintval());
44 
45     // If condition == Cond_NE.
46     if (actualBits.is_nan())
47       return !expectedBits.is_nan();
48     return expectedBits.is_nan() ||
49            (actualBits.uintval() != expectedBits.uintval());
50   }
51 
52   void explainError(testutils::StreamWrapper &stream) override {
53     describeValue("Expected floating point value: ", expected, stream);
54     describeValue("  Actual floating point value: ", actual, stream);
55   }
56 };
57 
58 template <__llvm_libc::testing::TestCondition C, typename T>
59 FPMatcher<T, C> getMatcher(T expectedValue) {
60   return FPMatcher<T, C>(expectedValue);
61 }
62 
63 } // namespace testing
64 } // namespace fputil
65 } // namespace __llvm_libc
66 
67 #define DECLARE_SPECIAL_CONSTANTS(T)                                           \
68   using FPBits = __llvm_libc::fputil::FPBits<T>;                               \
69   using UIntType = typename FPBits::UIntType;                                  \
70   const T zero = T(FPBits::zero());                                            \
71   const T neg_zero = T(FPBits::neg_zero());                                    \
72   const T aNaN = T(FPBits::build_nan(1));                                      \
73   const T inf = T(FPBits::inf());                                              \
74   const T neg_inf = T(FPBits::neg_inf());
75 
76 #define EXPECT_FP_EQ(expected, actual)                                         \
77   EXPECT_THAT(                                                                 \
78       actual,                                                                  \
79       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_EQ>( \
80           expected))
81 
82 #define ASSERT_FP_EQ(expected, actual)                                         \
83   ASSERT_THAT(                                                                 \
84       actual,                                                                  \
85       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_EQ>( \
86           expected))
87 
88 #define EXPECT_FP_NE(expected, actual)                                         \
89   EXPECT_THAT(                                                                 \
90       actual,                                                                  \
91       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
92           expected))
93 
94 #define ASSERT_FP_NE(expected, actual)                                         \
95   ASSERT_THAT(                                                                 \
96       actual,                                                                  \
97       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
98           expected))
99 
100 #endif // LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
101