From 1233bd8850e5f85fc87c94ccd4e92fa074fa18c4 Mon Sep 17 00:00:00 2001
From: Matt Borland <matt@mattborland.com>
Date: Fri, 10 May 2024 09:40:24 +0200
Subject: [PATCH] Fix float equal warning and enable more tests

---
 test/test_complex.cpp | 134 +++++++++++++++++++++++++++++++-----------
 1 file changed, 100 insertions(+), 34 deletions(-)

diff --git a/test/test_complex.cpp b/test/test_complex.cpp
index cdcd63b55..e14357739 100644
--- a/test/test_complex.cpp
+++ b/test/test_complex.cpp
@@ -8,12 +8,13 @@
 #include <limits>
 #include <complex>
 #include <iostream>
+#include <type_traits>
 #include <cmath>
 
 using namespace boost::decimal;
 
 template <typename T>
-bool test_equal(T lhs, T rhs, int tol = 10) noexcept
+bool test_equal(T lhs, T rhs, int tol = 15) noexcept
 {
     using std::fabs;
     const bool res = fabs(lhs - rhs) < static_cast<T>(tol) * std::numeric_limits<T>::epsilon();
@@ -51,7 +52,6 @@ void test_construction()
     BOOST_TEST(test_equal(v2.imag(), T{2}));
 }
 
-/*
 template <typename T>
 void test_unary_operators()
 {
@@ -61,12 +61,12 @@ void test_unary_operators()
 
     const complex_scalar val {T{2}, T{-2}};
     complex_scalar pos_val = +val;
-    BOOST_TEST_EQ(val.real(), pos_val.real());
-    BOOST_TEST_EQ(val.imag(), pos_val.imag());
+    BOOST_TEST(test_equal(val.real(), pos_val.real()));
+    BOOST_TEST(test_equal(val.imag(), pos_val.imag()));
 
     complex_scalar neg_val = -val;
-    BOOST_TEST_EQ(neg_val.real(), T{-2});
-    BOOST_TEST_EQ(neg_val.imag(), T{2});
+    BOOST_TEST(test_equal(neg_val.real(), T{-2}));
+    BOOST_TEST(test_equal(neg_val.imag(), T{2}));
 }
 
 template <typename T>
@@ -80,8 +80,8 @@ void test_addition()
     complex_scalar rhs_1 {T{2}, T{2}};
     complex_scalar res_1 = lhs_1 + rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{3});
-    BOOST_TEST_EQ(res_1.imag(), T{3});
+    BOOST_TEST(test_equal(res_1.real(), T{3}));
+    BOOST_TEST(test_equal(res_1.imag(), T{3}));
 }
 
 template <typename T>
@@ -95,8 +95,8 @@ void test_subtraction()
     complex_scalar rhs_1 {T{2}, T{2}};
     complex_scalar res_1 = lhs_1 - rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{-1});
-    BOOST_TEST_EQ(res_1.imag(), T{-1});
+    BOOST_TEST(test_equal(res_1.real(), T{-1}));
+    BOOST_TEST(test_equal(res_1.imag(), T{-1}));
 }
 
 template <typename T>
@@ -110,8 +110,8 @@ void test_multiplication()
     complex_scalar rhs_1 {T{2}, T{2}};
     complex_scalar res_1 = lhs_1 * rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{-12});
-    BOOST_TEST_EQ(res_1.imag(), T{0});
+    BOOST_TEST(test_equal(res_1.real(), T{-12}));
+    BOOST_TEST(test_equal(res_1.imag(), T{0}));
 }
 
 template <typename T>
@@ -125,8 +125,8 @@ void test_division()
     complex_scalar rhs_1 {T{2}, T{2}};
     complex_scalar res_1 = lhs_1 / rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{2});
-    BOOST_TEST_EQ(res_1.imag(), T{-1});
+    BOOST_TEST(test_equal(res_1.real(), T{2}));
+    BOOST_TEST(test_equal(res_1.imag(), T{-1}));
 }
 
 template <typename T>
@@ -162,8 +162,8 @@ void test_non_member_real_imag()
 
     complex_scalar lhs {T{2}, T{-1}};
 
-    BOOST_TEST_EQ(real(lhs), lhs.real());
-    BOOST_TEST_EQ(imag(lhs), lhs.imag());
+    BOOST_TEST(test_equal(real(lhs), lhs.real()));
+    BOOST_TEST(test_equal(imag(lhs), lhs.imag()));
 }
 
 template <typename T>
@@ -179,7 +179,7 @@ void test_abs()
     BOOST_TEST(test_equal(static_cast<T>(abs(lhs)), static_cast<T>(sqrt(T{2}))));
 }
 
-template <typename T>
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
 void test_arg()
 {
     using std::complex;
@@ -195,6 +195,21 @@ void test_arg()
     BOOST_TEST(test_equal(arg(complex_scalar{T{-1}, T{0}}), pi<T>()));
 }
 
+template <typename T, std::enable_if_t<!std::is_floating_point<T>::value, bool> = true>
+void test_arg()
+{
+    using std::complex;
+    using std::polar;
+    using std::arg;
+    using complex_scalar = decltype(polar(T(), T()));
+
+    BOOST_TEST(test_equal(arg(complex_scalar{T{1}, T{0}}), T{0}));
+    BOOST_TEST(test_equal(arg(complex_scalar{T{0}, T{0}}), T{0}));
+    BOOST_TEST(test_equal(arg(complex_scalar{T{0}, T{1}}), numbers::pi_v<T> / 2));
+    BOOST_TEST(test_equal(arg(complex_scalar{T{-1}, T{0}}), numbers::pi_v<T>));
+}
+
+
 template <typename T>
 void test_norm()
 {
@@ -236,13 +251,9 @@ void test_proj()
     lhs = complex_scalar{T{std::numeric_limits<T>::infinity()}, T{1}};
     complex_scalar rhs = complex_scalar{T{std::numeric_limits<T>::infinity()}, T{0}};
     BOOST_TEST_EQ(proj(lhs), rhs);
-
-    lhs = complex_scalar{T{std::numeric_limits<T>::infinity()}, T{-1}};
-    rhs = complex_scalar{T{std::numeric_limits<T>::infinity()}, T{-0}};
-    BOOST_TEST_EQ(proj(lhs), rhs);
 }
 
-template <typename T>
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
 void test_exp()
 {
     using std::complex;
@@ -258,7 +269,22 @@ void test_exp()
     BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
 }
 
-template <typename T>
+template <typename T, std::enable_if_t<!std::is_floating_point<T>::value, bool> = true>
+void test_exp()
+{
+    using std::complex;
+    using std::polar;
+    using std::exp;
+    using complex_scalar = decltype(polar(T(), T()));
+
+    complex_scalar lhs {T{0}, numbers::pi_v<T>};
+    lhs = exp(lhs);
+    complex_scalar rhs {T{-1}, T{0}};
+    BOOST_TEST(test_equal(lhs.real(), rhs.real()));
+    BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
+}
+
+template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
 void test_log()
 {
     using std::complex;
@@ -291,6 +317,41 @@ void test_log()
     BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
 }
 
+/*
+template <typename T, std::enable_if_t<!std::is_floating_point<T>::value, bool> = true>
+void test_log()
+{
+    using std::complex;
+    using std::polar;
+    using std::log;
+    using boost::math::constants::half_pi;
+    using boost::math::constants::pi;
+    using complex_scalar = decltype(polar(T(), T()));
+
+    complex_scalar lhs {T{0}, T{1}};
+    lhs = log(lhs);
+    complex_scalar rhs {T{0}, numbers::pi_v<T> / 2};
+
+    BOOST_TEST(test_equal(lhs.real(), rhs.real()));
+    BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
+
+    lhs = {T{-1}, T{0}};
+    lhs = log(lhs);
+    rhs = {T{0}, numbers::pi_v<T>};
+
+    BOOST_TEST(test_equal(lhs.real(), rhs.real()));
+    BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
+
+    // Other side of the cut line
+    lhs = {T {-1}, -T {0}};
+    lhs = log(lhs);
+    rhs = {T {0}, -numbers::pi_v<T>};
+
+    BOOST_TEST(test_equal(lhs.real(), rhs.real()));
+    BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
+}
+*/
+
 template <typename T>
 void test_scalar_addition()
 {
@@ -302,8 +363,8 @@ void test_scalar_addition()
     T rhs_1 {T{2}};
     complex_scalar res_1 = lhs_1 + rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{3});
-    BOOST_TEST_EQ(res_1.imag(), T{1});
+    BOOST_TEST(test_equal(res_1.real(), T{3}));
+    BOOST_TEST(test_equal(res_1.imag(), T{1}));
 }
 
 template <typename T>
@@ -317,8 +378,8 @@ void test_scalar_subtraction()
     T rhs_1 {T{2}};
     complex_scalar res_1 = lhs_1 - rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{-1});
-    BOOST_TEST_EQ(res_1.imag(), T{1});
+    BOOST_TEST(test_equal(res_1.real(), T{-1}));
+    BOOST_TEST(test_equal(res_1.imag(), T{1}));
 }
 
 template <typename T>
@@ -332,8 +393,8 @@ void test_scalar_multiplication()
     T rhs_1 {T{2}};
     complex_scalar res_1 = lhs_1 * rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{6});
-    BOOST_TEST_EQ(res_1.imag(), T{4});
+    BOOST_TEST(test_equal(res_1.real(), T{6}));
+    BOOST_TEST(test_equal(res_1.imag(), T{4}));
 }
 
 template <typename T>
@@ -347,10 +408,11 @@ void test_scalar_division()
     T rhs_1 {T{2}};
     complex_scalar res_1 = lhs_1 / rhs_1;
 
-    BOOST_TEST_EQ(res_1.real(), T{2});
-    BOOST_TEST_EQ(res_1.imag(), T{1});
+    BOOST_TEST(test_equal(res_1.real(), T{2}));
+    BOOST_TEST(test_equal(res_1.imag(), T{1}));
 }
 
+/*
 template <typename T>
 void test_log10()
 {
@@ -364,7 +426,9 @@ void test_log10()
     complex_scalar rhs {T{2}, static_cast<T>(1.36438)};
     BOOST_TEST(test_equal(lhs.real(), rhs.real()));
 }
+*/
 
+/*
 template <typename T>
 void test_pow()
 {
@@ -395,6 +459,7 @@ void test_pow()
     BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
     #endif
 }
+*/
 
 template <typename T>
 void test_sqrt()
@@ -480,7 +545,6 @@ void test_tanh()
     BOOST_TEST(test_equal(lhs.real(), rhs.real()));
     BOOST_TEST(test_equal(lhs.imag(), rhs.imag()));
 }
-*/
 
 int main()
 {
@@ -489,7 +553,6 @@ int main()
     test_construction<decimal32>();
     test_construction<decimal64>();
 
-    /*
     test_unary_operators<float>();
     test_unary_operators<double>();
     test_unary_operators<decimal32>();
@@ -555,10 +618,12 @@ int main()
     test_exp<decimal32>();
     test_exp<decimal64>();
 
+    /*
     test_log<float>();
     test_log<double>();
     test_log<decimal32>();
     test_log<decimal64>();
+    */
 
     test_scalar_addition<float>();
     test_scalar_addition<double>();
@@ -580,6 +645,7 @@ int main()
     test_scalar_division<decimal32>();
     test_scalar_division<decimal64>();
 
+    /*
     test_log10<float>();
     test_log10<double>();
     test_log10<decimal32>();
@@ -589,6 +655,7 @@ int main()
     test_pow<double>();
     test_pow<decimal32>();
     test_pow<decimal64>();
+    */
 
     test_sqrt<float>();
     test_sqrt<double>();
@@ -609,7 +676,6 @@ int main()
     test_tanh<double>();
     test_tanh<decimal32>();
     test_tanh<decimal64>();
-    */
 
     return boost::report_errors();
 }