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 <[email protected]>
* include/std/complex (__complex_exp, pow): Specify the template
parameter in calls to std::polar, for expression templates.
--
Marc GlisseIndex: 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;