]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Provide operator* overloads for mixed floating point type multiplication 1586/head
authorMatthias Maier <tamiko@43-1.org>
Sun, 13 Sep 2015 00:50:58 +0000 (19:50 -0500)
committerMatthias Maier <tamiko@43-1.org>
Sun, 13 Sep 2015 00:54:28 +0000 (19:54 -0500)
cmake/checks/check_01_cxx_features.cmake
include/deal.II/base/complex_overloads.h
include/deal.II/base/config.h.in
include/deal.II/base/template_constraints.h

index 8ce8edc256def38a106765a80844f352a3c9da6e..6d94ea758056d6771e3c9ed28a8c4814e07af143 100644 (file)
@@ -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 <complex>
+
+  int main()
+  {
+    double() * std::complex<float>();
+    std::complex<float>() * double();
+    float() * std::complex<double>();
+    std::complex<double>() * float();
+    std::complex<double>() * std::complex<float>();
+    std::complex<float>() * std::complex<double>();
+
+    return 0;
+  }
+  "
+  DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS)
+
index fa1b1f35eaa842a553a022f463085818c39cd6f9..d432fc50f630f2df90dd5f90015daa57867636d1 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
+// Forward declarations
+template <typename T> struct EnableIfScalar;
+template <typename T, typename U> struct ProductType;
+
+#ifndef DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS
 /**
- * A namespace that contains overloads of <tt>operator*</tt> for complex
- * numbers. Those overloads allow mixed floating point type multiplication
- * between complex and real valued types.
+ * Provide an <tt>operator*</tt> 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 T, typename U>
+typename ProductType<std::complex<T>, std::complex<U> >::type
+inline
+operator*(const std::complex<T> &left, const std::complex<U> &right)
 {
-  /**
-   * Provide an <tt>operator*</tt> that operates on mixed complex floating
-   * point types. Annoyingly, the standard library does not provide such an
-   * operator...
-   *
-   * @relates ProductType
-   */
-  template <typename T, typename U>
-  typename ProductType<std::complex<T>, std::complex<U> >::type
-  inline
-  operator*(const std::complex<T> &left, const std::complex<U> &right)
-  {
-    typedef typename ProductType<std::complex<T>, std::complex<U> >::type result_type;
-    return static_cast<result_type>(left) * static_cast<result_type>(right);
-  }
+  typedef typename ProductType<std::complex<T>, std::complex<U> >::type result_type;
+  return static_cast<result_type>(left) * static_cast<result_type>(right);
+}
 
 
-  /**
  * Provide an <tt>operator*</tt> 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 T, typename U>
-  typename ProductType<std::complex<T>, typename EnableIfScalar<U>::type>::type
-  inline
-  operator*(const std::complex<T> &left, const U &right)
-  {
-    typedef typename ProductType<std::complex<T>, U>::type result_type;
-    return static_cast<result_type>(left) * static_cast<result_type>(right);
-  }
+/**
+ * Provide an <tt>operator*</tt> 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 T, typename U>
+typename ProductType<std::complex<T>, typename EnableIfScalar<U>::type>::type
+inline
+operator*(const std::complex<T> &left, const U &right)
+{
+  typedef typename ProductType<std::complex<T>, U>::type result_type;
+  return static_cast<result_type>(left) * static_cast<result_type>(right);
+}
 
 
-  /**
  * Provide an <tt>operator*</tt> 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 T, typename U>
-  typename ProductType<typename EnableIfScalar<T>::type, std::complex<U> >::type
-  inline
-  operator*(const T &left, const std::complex<U> &right)
-  {
-    typedef typename ProductType<std::complex<T>, U>::type result_type;
-    return static_cast<result_type>(left) * static_cast<result_type>(right);
-  }
-} /* namespace ComplexOverloads */
+/**
+ * Provide an <tt>operator*</tt> 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 T, typename U>
+typename ProductType<typename EnableIfScalar<T>::type, std::complex<U> >::type
+inline
+operator*(const T &left, const std::complex<U> &right)
+{
+  typedef typename ProductType<std::complex<T>, U>::type result_type;
+  return static_cast<result_type>(left) * static_cast<result_type>(right);
+}
+#endif /* DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS */
 
 DEAL_II_NAMESPACE_CLOSE
 
index 72863f63b24505d1fad826780260a9e98968d332..297782d727d42388c7858764d6271cacab710530 100644 (file)
 #cmakedefine DEAL_II_HAVE_UNDERSCORE_ISNAN
 #cmakedefine DEAL_II_HAVE_ISFINITE
 #cmakedefine DEAL_II_HAVE_FP_EXCEPTIONS
+#cmakedefine DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS
 
 
 /***********************************************************************
index 3a24b1109388e92067959c10ba8ef04b006e1196..acdc8d3066cefecb3f38d15ce15c3d91809024cf 100644 (file)
@@ -18,6 +18,7 @@
 
 
 #include <deal.II/base/config.h>
+#include <deal.II/base/complex_overloads.h>
 
 #include <complex>
 #include <utility>
@@ -460,13 +461,6 @@ struct ProductType<unsigned int,float>
   typedef float type;
 };
 
-
-#endif
-
-
-// Annoyingly, there is no std::complex<T>::operator*(U) for scalars U
-// other than T. Consequently, even with C++11, we need the following
-// specializations:
 template <typename T>
 struct ProductType<std::complex<T>,std::complex<T> >
 {
@@ -504,6 +498,7 @@ struct ProductType<std::complex<T>,float>
   typedef std::complex<typename ProductType<T,float>::type> type;
 };
 
+#endif
 
 
 /**
@@ -598,9 +593,6 @@ template <typename T> struct EnableIfScalar<std::complex<T> >
 };
 
 
-
-
-
 // --------------- inline functions -----------------
 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.