@@ -60,10 +60,95 @@ template <typename T, TestCond Condition> class FPMatcher : public Matcher<T> {
60
60
}
61
61
};
62
62
63
+ template <typename T, TestCond Condition> class CFPMatcher : public Matcher <T> {
64
+ static_assert (
65
+ cpp::is_complex_v<T>,
66
+ " CFPMatcher can only be used with complex floating point values." );
67
+ static_assert (Condition == TestCond::EQ || Condition == TestCond::NE,
68
+ " Unsupported CFPMatcher test condition." );
69
+
70
+ T expected;
71
+ T actual;
72
+
73
+ public:
74
+ CFPMatcher (T expectedValue) : expected(expectedValue) {}
75
+
76
+ template <typename CFT> bool matchComplex () {
77
+ CFT *actualCmplxPtr = reinterpret_cast <CFT *>(&actual);
78
+ CFT *expectedCmplxPtr = reinterpret_cast <CFT *>(&expected);
79
+ CFT actualReal = actualCmplxPtr[0 ];
80
+ CFT actualImag = actualCmplxPtr[1 ];
81
+ CFT expectedReal = expectedCmplxPtr[0 ];
82
+ CFT expectedImag = expectedCmplxPtr[1 ];
83
+ fputil::FPBits<CFT> actualRealBits (actualReal),
84
+ expectedRealBits (expectedReal);
85
+ fputil::FPBits<CFT> actualImagBits (actualImag),
86
+ expectedImagBits (expectedImag);
87
+ if (Condition == TestCond::EQ)
88
+ return ((actualRealBits.is_nan () && expectedRealBits.is_nan ()) ||
89
+ (actualRealBits.uintval () == expectedRealBits.uintval ())) &&
90
+ ((actualImagBits.is_nan () && expectedImagBits.is_nan ()) ||
91
+ (actualImagBits.uintval () == expectedImagBits.uintval ()));
92
+
93
+ // If condition == TestCond::NE.
94
+ if (actualRealBits.is_nan () && expectedRealBits.is_nan ())
95
+ return !expectedRealBits.is_nan () && !expectedImagBits.is_nan ();
96
+ if (actualRealBits.is_nan ())
97
+ return !expectedRealBits.is_nan ();
98
+ if (actualImagBits.is_nan ())
99
+ return !expectedImagBits.is_nan ();
100
+ return (expectedRealBits.is_nan () ||
101
+ actualRealBits.uintval () != expectedRealBits.uintval ()) &&
102
+ (expectedImagBits.is_nan () ||
103
+ actualImagBits.uintval () != expectedImagBits.uintval ());
104
+ }
105
+
106
+ template <typename CFT> void explainErrorComplex () {
107
+ CFT *actualCmplxPtr = reinterpret_cast <CFT *>(&actual);
108
+ CFT *expectedCmplxPtr = reinterpret_cast <CFT *>(&expected);
109
+ CFT actualReal = actualCmplxPtr[0 ];
110
+ CFT actualImag = actualCmplxPtr[1 ];
111
+ CFT expectedReal = expectedCmplxPtr[0 ];
112
+ CFT expectedImag = expectedCmplxPtr[1 ];
113
+ tlog << " Expected complex floating point value: "
114
+ << str (fputil::FPBits<CFT>(expectedReal)) + " + " +
115
+ str (fputil::FPBits<CFT>(expectedImag)) + " i"
116
+ << ' \n ' ;
117
+ tlog << " Actual complex floating point value: "
118
+ << str (fputil::FPBits<CFT>(actualReal)) + " + " +
119
+ str (fputil::FPBits<CFT>(actualImag)) + " i"
120
+ << ' \n ' ;
121
+ }
122
+
123
+ bool match (T actualValue) {
124
+ actual = actualValue;
125
+ if (cpp::is_complex_type_same<T, _Complex float >())
126
+ return matchComplex<float >();
127
+ else if (cpp::is_complex_type_same<T, _Complex double >())
128
+ return matchComplex<double >();
129
+ else if (cpp::is_complex_type_same<T, _Complex long double >())
130
+ return matchComplex<long double >();
131
+ }
132
+
133
+ void explainError () override {
134
+ if (cpp::is_complex_type_same<T, _Complex float >())
135
+ return explainErrorComplex<float >();
136
+ else if (cpp::is_complex_type_same<T, _Complex double >())
137
+ return explainErrorComplex<double >();
138
+ else if (cpp::is_complex_type_same<T, _Complex long double >())
139
+ return explainErrorComplex<long double >();
140
+ }
141
+ };
142
+
63
143
template <TestCond C, typename T> FPMatcher<T, C> getMatcher (T expectedValue) {
64
144
return FPMatcher<T, C>(expectedValue);
65
145
}
66
146
147
+ template <TestCond C, typename T>
148
+ CFPMatcher<T, C> getMatcherComplex (T expectedValue) {
149
+ return CFPMatcher<T, C>(expectedValue);
150
+ }
151
+
67
152
template <typename T> struct FPTest : public Test {
68
153
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
69
154
using StorageType = typename FPBits::StorageType;
@@ -125,6 +210,10 @@ template <typename T> struct FPTest : public Test {
125
210
EXPECT_THAT (actual, LIBC_NAMESPACE::testing::getMatcher< \
126
211
LIBC_NAMESPACE::testing::TestCond::EQ>(expected))
127
212
213
+ #define EXPECT_CFP_EQ (expected, actual ) \
214
+ EXPECT_THAT (actual, LIBC_NAMESPACE::testing::getMatcherComplex< \
215
+ LIBC_NAMESPACE::testing::TestCond::EQ>(expected))
216
+
128
217
#define TEST_FP_EQ (expected, actual ) \
129
218
LIBC_NAMESPACE::testing::getMatcher<LIBC_NAMESPACE::testing::TestCond::EQ>( \
130
219
expected) \
0 commit comments