Hello,

looking at this question:
http://stackoverflow.com/q/21737186/1918193
I was surprised to see that libstdc++'s std::complex basically just works with user-defined types, even weird expression template ones, although that's not a supported use afaik.

The only functions that fail seem to be exp and pow, both because they call polar with two arguments that have different (expression) types.

I am not proposing to make this a supported use, but the cost of this small patch seems very low, and if it makes a couple users happy...

Regtested with no problem on x86_64-linux-gnu, ok for stage 1?

2014-02-23  Marc Glisse  <marc.gli...@inria.fr>

        * include/std/complex (__complex_exp, pow): Specify the template
        parameter in calls to std::polar, for expression templates.

--
Marc Glisse
Index: libstdc++-v3/include/std/complex
===================================================================
--- libstdc++-v3/include/std/complex    (revision 208045)
+++ libstdc++-v3/include/std/complex    (working copy)
@@ -728,21 +728,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
   template<typename _Tp>
     inline complex<_Tp>
     cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); }
 #endif
 
   // 26.2.8/3 exp(__z): Returns the complex base e exponential of x
   template<typename _Tp>
     inline complex<_Tp>
     __complex_exp(const complex<_Tp>& __z)
-    { return std::polar(exp(__z.real()), __z.imag()); }
+    { return std::polar<_Tp>(exp(__z.real()), __z.imag()); }
 
 #if _GLIBCXX_USE_C99_COMPLEX
   inline __complex__ float
   __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); }
 
   inline __complex__ double
   __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); }
 
   inline __complex__ long double
   __complex_exp(const __complex__ long double& __z)
@@ -988,21 +988,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     pow(const complex<_Tp>& __x, const _Tp& __y)
     {
 #ifndef _GLIBCXX_USE_C99_COMPLEX
       if (__x == _Tp())
        return _Tp();
 #endif
       if (__x.imag() == _Tp() && __x.real() > _Tp())
         return pow(__x.real(), __y);
 
       complex<_Tp> __t = std::log(__x);
-      return std::polar(exp(__y * __t.real()), __y * __t.imag());
+      return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag());
     }
 
   template<typename _Tp>
     inline complex<_Tp>
     __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
     { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); }
 
 #if _GLIBCXX_USE_C99_COMPLEX
   inline __complex__ float
   __complex_pow(__complex__ float __x, __complex__ float __y)
@@ -1025,22 +1025,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     inline complex<_Tp>
     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
     { return __complex_pow(__x, __y); }
 #endif
 
   template<typename _Tp>
     inline complex<_Tp>
     pow(const _Tp& __x, const complex<_Tp>& __y)
     {
-      return __x > _Tp() ? std::polar(pow(__x, __y.real()),
-                                     __y.imag() * log(__x))
+      return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()),
+                                          __y.imag() * log(__x))
                         : std::pow(complex<_Tp>(__x), __y);
     }
 
   /// 26.2.3  complex specializations
   /// complex<float> specialization
   template<>
     struct complex<float>
     {
       typedef float value_type;
       typedef __complex__ float _ComplexT;

Reply via email to