1 //===-- MPFRUtils.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_TESTUTILS_MPFRUTILS_H
10 #define LLVM_LIBC_UTILS_TESTUTILS_MPFRUTILS_H
11 
12 #include "utils/CPP/TypeTraits.h"
13 #include "utils/UnitTest/Test.h"
14 
15 #include <stdint.h>
16 
17 namespace __llvm_libc {
18 namespace testing {
19 namespace mpfr {
20 
21 enum class Operation : int {
22   Abs,
23   Ceil,
24   Cos,
25   Exp,
26   Exp2,
27   Floor,
28   Round,
29   Sin,
30   Sqrt,
31   Trunc
32 };
33 
34 namespace internal {
35 
36 template <typename T>
37 bool compare(Operation op, T input, T libcOutput, double t);
38 
39 template <typename T> class MPFRMatcher : public testing::Matcher<T> {
40   static_assert(__llvm_libc::cpp::IsFloatingPointType<T>::Value,
41                 "MPFRMatcher can only be used with floating point values.");
42 
43   Operation operation;
44   T input;
45   T matchValue;
46   double ulpTolerance;
47 
48 public:
49   MPFRMatcher(Operation op, T testInput, double ulpTolerance)
50       : operation(op), input(testInput), ulpTolerance(ulpTolerance) {}
51 
52   bool match(T libcResult) {
53     matchValue = libcResult;
54     return internal::compare(operation, input, libcResult, ulpTolerance);
55   }
56 
57   void explainError(testutils::StreamWrapper &OS) override;
58 };
59 
60 } // namespace internal
61 
62 template <typename T, typename U>
63 __attribute__((no_sanitize("address")))
64 typename cpp::EnableIfType<cpp::IsSameV<U, double>, internal::MPFRMatcher<T>>
65 getMPFRMatcher(Operation op, T input, U t) {
66   static_assert(
67       __llvm_libc::cpp::IsFloatingPointType<T>::Value,
68       "getMPFRMatcher can only be used to match floating point results.");
69   return internal::MPFRMatcher<T>(op, input, t);
70 }
71 
72 } // namespace mpfr
73 } // namespace testing
74 } // namespace __llvm_libc
75 
76 #define EXPECT_MPFR_MATCH(op, input, matchValue, tolerance)                    \
77   EXPECT_THAT(matchValue, __llvm_libc::testing::mpfr::getMPFRMatcher(          \
78                               op, input, tolerance))
79 
80 #define ASSERT_MPFR_MATCH(op, input, matchValue, tolerance)                    \
81   ASSERT_THAT(matchValue, __llvm_libc::testing::mpfr::getMPFRMatcher(          \
82                               op, input, tolerance))
83 
84 #endif // LLVM_LIBC_UTILS_TESTUTILS_MPFRUTILS_H
85