@@ -60,10 +60,95 @@ template <typename T, TestCond Condition> class FPMatcher : public Matcher<T> {
6060 }
6161};
6262
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+
63143template <TestCond C, typename T> FPMatcher<T, C> getMatcher (T expectedValue) {
64144 return FPMatcher<T, C>(expectedValue);
65145}
66146
147+ template <TestCond C, typename T>
148+ CFPMatcher<T, C> getMatcherComplex (T expectedValue) {
149+ return CFPMatcher<T, C>(expectedValue);
150+ }
151+
67152template <typename T> struct FPTest : public Test {
68153 using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
69154 using StorageType = typename FPBits::StorageType;
@@ -125,6 +210,10 @@ template <typename T> struct FPTest : public Test {
125210 EXPECT_THAT (actual, LIBC_NAMESPACE::testing::getMatcher< \
126211 LIBC_NAMESPACE::testing::TestCond::EQ>(expected))
127212
213+ #define EXPECT_CFP_EQ (expected, actual ) \
214+ EXPECT_THAT (actual, LIBC_NAMESPACE::testing::getMatcherComplex< \
215+ LIBC_NAMESPACE::testing::TestCond::EQ>(expected))
216+
128217#define TEST_FP_EQ (expected, actual ) \
129218 LIBC_NAMESPACE::testing::getMatcher<LIBC_NAMESPACE::testing::TestCond::EQ>( \
130219 expected) \
0 commit comments