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>
21 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void>
22 describeValue(const char *label, ValType value,
23               testutils::StreamWrapper &stream);
24 
25 template <typename T, __llvm_libc::testing::TestCondition Condition>
26 class FPMatcher : public __llvm_libc::testing::Matcher<T> {
27   static_assert(__llvm_libc::cpp::IsFloatingPointType<T>::Value,
28                 "FPMatcher can only be used with floating point values.");
29   static_assert(Condition == __llvm_libc::testing::Cond_EQ ||
30                     Condition == __llvm_libc::testing::Cond_NE,
31                 "Unsupported FPMathcer test condition.");
32 
33   T expected;
34   T actual;
35 
36 public:
37   FPMatcher(T expectedValue) : expected(expectedValue) {}
38 
39   bool match(T actualValue) {
40     actual = actualValue;
41     fputil::FPBits<T> actualBits(actual), expectedBits(expected);
42     if (Condition == __llvm_libc::testing::Cond_EQ)
43       return (actualBits.isNaN() && expectedBits.isNaN()) ||
44              (actualBits.uintval() == expectedBits.uintval());
45 
46     // If condition == Cond_NE.
47     if (actualBits.isNaN())
48       return !expectedBits.isNaN();
49     return expectedBits.isNaN() ||
50            (actualBits.uintval() != expectedBits.uintval());
51   }
52 
53   void explainError(testutils::StreamWrapper &stream) override {
54     describeValue("Expected floating point value: ", expected, stream);
55     describeValue("  Actual floating point value: ", actual, stream);
56   }
57 };
58 
59 template <__llvm_libc::testing::TestCondition C, typename T>
60 FPMatcher<T, C> getMatcher(T expectedValue) {
61   return FPMatcher<T, C>(expectedValue);
62 }
63 
64 } // namespace testing
65 } // namespace fputil
66 } // namespace __llvm_libc
67 
68 #define DECLARE_SPECIAL_CONSTANTS(T)                                           \
69   using FPBits = __llvm_libc::fputil::FPBits<T>;                               \
70   using UIntType = typename FPBits::UIntType;                                  \
71   const T zero = T(FPBits::zero());                                            \
72   const T negZero = T(FPBits::negZero());                                      \
73   const T aNaN = T(FPBits::buildNaN(1));                                       \
74   const T inf = T(FPBits::inf());                                              \
75   const T negInf = T(FPBits::negInf());
76 
77 #define EXPECT_FP_EQ(expected, actual)                                         \
78   EXPECT_THAT(                                                                 \
79       actual,                                                                  \
80       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_EQ>( \
81           expected))
82 
83 #define ASSERT_FP_EQ(expected, actual)                                         \
84   ASSERT_THAT(                                                                 \
85       actual,                                                                  \
86       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_EQ>( \
87           expected))
88 
89 #define EXPECT_FP_NE(expected, actual)                                         \
90   EXPECT_THAT(                                                                 \
91       actual,                                                                  \
92       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
93           expected))
94 
95 #define ASSERT_FP_NE(expected, actual)                                         \
96   ASSERT_THAT(                                                                 \
97       actual,                                                                  \
98       __llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
99           expected))
100 
101 #endif // LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
102