From 58d1dd6baa79e90340a501c78a58cd6fbf16943c Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Sat, 12 Sep 2015 19:50:58 -0500 Subject: [PATCH] Provide operator* overloads for mixed floating point type multiplication --- cmake/checks/check_01_cxx_features.cmake | 26 +++++ include/deal.II/base/complex_overloads.h | 104 +++++++++----------- include/deal.II/base/config.h.in | 1 + include/deal.II/base/template_constraints.h | 12 +-- 4 files changed, 78 insertions(+), 65 deletions(-) diff --git a/cmake/checks/check_01_cxx_features.cmake b/cmake/checks/check_01_cxx_features.cmake index 8ce8edc256..6d94ea7580 100644 --- a/cmake/checks/check_01_cxx_features.cmake +++ b/cmake/checks/check_01_cxx_features.cmake @@ -26,6 +26,7 @@ # DEAL_II_HAVE_UNDERSCORE_ISNAN # DEAL_II_HAVE_ISFINITE # DEAL_II_HAVE_FP_EXCEPTIONS +# DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS # @@ -522,3 +523,28 @@ IF(DEAL_II_WITH_CXX11) ELSE() SET(DEAL_II_HAVE_FP_EXCEPTIONS FALSE) ENDIF() + +# +# Check whether the standard library provides operator* overloads for mixed +# floating point multiplication of complex and real valued numbers. +# +# - Matthias Maier, 2015 +# +CHECK_CXX_SOURCE_COMPILES( + " + #include + + int main() + { + double() * std::complex(); + std::complex() * double(); + float() * std::complex(); + std::complex() * float(); + std::complex() * std::complex(); + std::complex() * std::complex(); + + return 0; + } + " + DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS) + diff --git a/include/deal.II/base/complex_overloads.h b/include/deal.II/base/complex_overloads.h index fa1b1f35ea..d432fc50f6 100644 --- a/include/deal.II/base/complex_overloads.h +++ b/include/deal.II/base/complex_overloads.h @@ -21,69 +21,63 @@ DEAL_II_NAMESPACE_OPEN +// Forward declarations +template struct EnableIfScalar; +template struct ProductType; + +#ifndef DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS /** - * A namespace that contains overloads of operator* for complex - * numbers. Those overloads allow mixed floating point type multiplication - * between complex and real valued types. + * Provide an operator* that operates on mixed complex floating + * point types. Annoyingly, the standard library does not provide such an + * operator... * - * Unfortunately, the standard library does not provide those function - * overloads (neither C++98, C++11, C++14, nor C++17), so we provide a - * namespace with them. + * @relates ProductType */ -namespace ComplexOverloads +template +typename ProductType, std::complex >::type +inline +operator*(const std::complex &left, const std::complex &right) { - /** - * Provide an operator* that operates on mixed complex floating - * point types. Annoyingly, the standard library does not provide such an - * operator... - * - * @relates ProductType - */ - template - typename ProductType, std::complex >::type - inline - operator*(const std::complex &left, const std::complex &right) - { - typedef typename ProductType, std::complex >::type result_type; - return static_cast(left) * static_cast(right); - } + typedef typename ProductType, std::complex >::type result_type; + return static_cast(left) * static_cast(right); +} - /** - * Provide an operator* for a scalar multiplication of a complex - * floating point type with a different real floating point type. - * Annoyingly, the standard library does not provide such an operator... - * - * @relates EnableIfScalar - * @relates ProductType - */ - template - typename ProductType, typename EnableIfScalar::type>::type - inline - operator*(const std::complex &left, const U &right) - { - typedef typename ProductType, U>::type result_type; - return static_cast(left) * static_cast(right); - } +/** + * Provide an operator* for a scalar multiplication of a complex + * floating point type with a different real floating point type. + * Annoyingly, the standard library does not provide such an operator... + * + * @relates EnableIfScalar + * @relates ProductType + */ +template +typename ProductType, typename EnableIfScalar::type>::type +inline +operator*(const std::complex &left, const U &right) +{ + typedef typename ProductType, U>::type result_type; + return static_cast(left) * static_cast(right); +} - /** - * Provide an operator* for a scalar multiplication of a real - * floating point type with a different complex floating point type. - * Annoyingly, the standard library does not provide such an operator... - * - * @relates EnableIfScalar - * @relates ProductType - */ - template - typename ProductType::type, std::complex >::type - inline - operator*(const T &left, const std::complex &right) - { - typedef typename ProductType, U>::type result_type; - return static_cast(left) * static_cast(right); - } -} /* namespace ComplexOverloads */ +/** + * Provide an operator* for a scalar multiplication of a real + * floating point type with a different complex floating point type. + * Annoyingly, the standard library does not provide such an operator... + * + * @relates EnableIfScalar + * @relates ProductType + */ +template +typename ProductType::type, std::complex >::type +inline +operator*(const T &left, const std::complex &right) +{ + typedef typename ProductType, U>::type result_type; + return static_cast(left) * static_cast(right); +} +#endif /* DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS */ DEAL_II_NAMESPACE_CLOSE diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index 72863f63b2..297782d727 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -112,6 +112,7 @@ #cmakedefine DEAL_II_HAVE_UNDERSCORE_ISNAN #cmakedefine DEAL_II_HAVE_ISFINITE #cmakedefine DEAL_II_HAVE_FP_EXCEPTIONS +#cmakedefine DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS /*********************************************************************** diff --git a/include/deal.II/base/template_constraints.h b/include/deal.II/base/template_constraints.h index 3a24b11093..acdc8d3066 100644 --- a/include/deal.II/base/template_constraints.h +++ b/include/deal.II/base/template_constraints.h @@ -18,6 +18,7 @@ #include +#include #include #include @@ -460,13 +461,6 @@ struct ProductType typedef float type; }; - -#endif - - -// Annoyingly, there is no std::complex::operator*(U) for scalars U -// other than T. Consequently, even with C++11, we need the following -// specializations: template struct ProductType,std::complex > { @@ -504,6 +498,7 @@ struct ProductType,float> typedef std::complex::type> type; }; +#endif /** @@ -598,9 +593,6 @@ template struct EnableIfScalar > }; - - - // --------------- inline functions ----------------- -- 2.39.5