gcc/libstdc++-v3/include/std/complex
Jonathan Wakely 4f75543dc4 PR libstdc++/61761 fix std::proj for targets without C99 cproj
The current generic implementation of __complex_proj used when cproj is
not available calculates the wrong projection, giving a different result
than given by C99's cproj.

When C99 cproj is not available but isinf and copysign are, use those to
give correct results for float, double and long double. Otherwise, and
for other specializations of std::complex, just use a generic version
that returns its argument, and so doesn't support infinities.

We might want to consider adding additional overloads of __complex_proj
to support extended types such as _Float64x, _Float128 etc.

	PR libstdc++/61761
	* include/std/complex (__complex_proj): Return parameter unchanged.
	[_GLIBCXX_USE_C99_COMPLEX] (__complex_proj): Change overloads for
	floating-point types to take std::complex arguments.
	[_GLIBCXX_USE_C99_MATH_TR1] (__complex_proj): Add overloads for
	floating-point types.
	* testsuite/26_numerics/complex/proj.cc: New test.

From-SVN: r270759
2019-05-01 01:08:36 +01:00

2015 lines
55 KiB
C++

// The template and inlines for the -*- C++ -*- complex number classes.
// Copyright (C) 1997-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/complex
* This is a Standard C++ Library header.
*/
//
// ISO C++ 14882: 26.2 Complex Numbers
// Note: this is not a conforming implementation.
// Initially implemented by Ulrich Drepper <drepper@cygnus.com>
// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
//
#ifndef _GLIBCXX_COMPLEX
#define _GLIBCXX_COMPLEX 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
#include <cmath>
#include <sstream>
// Get rid of a macro possibly defined in <complex.h>
#undef complex
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup complex_numbers Complex Numbers
* @ingroup numerics
*
* Classes and functions for complex numbers.
* @{
*/
// Forward declarations.
template<typename _Tp> class complex;
template<> class complex<float>;
template<> class complex<double>;
template<> class complex<long double>;
/// Return magnitude of @a z.
template<typename _Tp> _Tp abs(const complex<_Tp>&);
/// Return phase angle of @a z.
template<typename _Tp> _Tp arg(const complex<_Tp>&);
/// Return @a z magnitude squared.
template<typename _Tp> _Tp _GLIBCXX20_CONSTEXPR norm(const complex<_Tp>&);
/// Return complex conjugate of @a z.
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&);
/// Return complex with magnitude @a rho and angle @a theta.
template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
// Transcendentals:
/// Return complex cosine of @a z.
template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
/// Return complex hyperbolic cosine of @a z.
template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
/// Return complex base e exponential of @a z.
template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
/// Return complex natural logarithm of @a z.
template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
/// Return complex base 10 logarithm of @a z.
template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
/// Return @a x to the @a y'th power.
template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
/// Return @a x to the @a y'th power.
template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
/// Return @a x to the @a y'th power.
template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&,
const complex<_Tp>&);
/// Return @a x to the @a y'th power.
template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
/// Return complex sine of @a z.
template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
/// Return complex hyperbolic sine of @a z.
template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
/// Return complex square root of @a z.
template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
/// Return complex tangent of @a z.
template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
/// Return complex hyperbolic tangent of @a z.
template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
// 26.2.2 Primary template class complex
/**
* Template to represent complex numbers.
*
* Specializations for float, double, and long double are part of the
* library. Results with any other type are not guaranteed.
*
* @param Tp Type of real and imaginary values.
*/
template<typename _Tp>
struct complex
{
/// Value typedef.
typedef _Tp value_type;
/// Default constructor. First parameter is x, second parameter is y.
/// Unspecified parameters default to 0.
_GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp())
: _M_real(__r), _M_imag(__i) { }
// Let the compiler synthesize the copy constructor
#if __cplusplus >= 201103L
constexpr complex(const complex&) = default;
#endif
/// Converting constructor.
template<typename _Up>
_GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z)
: _M_real(__z.real()), _M_imag(__z.imag()) { }
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
_GLIBCXX_ABI_TAG_CXX11
constexpr _Tp
real() const { return _M_real; }
_GLIBCXX_ABI_TAG_CXX11
constexpr _Tp
imag() const { return _M_imag; }
#else
/// Return real part of complex number.
_Tp&
real() { return _M_real; }
/// Return real part of complex number.
const _Tp&
real() const { return _M_real; }
/// Return imaginary part of complex number.
_Tp&
imag() { return _M_imag; }
/// Return imaginary part of complex number.
const _Tp&
imag() const { return _M_imag; }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
_GLIBCXX20_CONSTEXPR void
real(_Tp __val) { _M_real = __val; }
_GLIBCXX20_CONSTEXPR void
imag(_Tp __val) { _M_imag = __val; }
/// Assign a scalar to this complex number.
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const _Tp&);
/// Add a scalar to this complex number.
// 26.2.5/1
_GLIBCXX20_CONSTEXPR complex<_Tp>&
operator+=(const _Tp& __t)
{
_M_real += __t;
return *this;
}
/// Subtract a scalar from this complex number.
// 26.2.5/3
_GLIBCXX20_CONSTEXPR complex<_Tp>&
operator-=(const _Tp& __t)
{
_M_real -= __t;
return *this;
}
/// Multiply this complex number by a scalar.
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const _Tp&);
/// Divide this complex number by a scalar.
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const _Tp&);
// Let the compiler synthesize the copy assignment operator
#if __cplusplus >= 201103L
_GLIBCXX20_CONSTEXPR complex& operator=(const complex&) = default;
#endif
/// Assign another complex number to this one.
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const complex<_Up>&);
/// Add another complex number to this one.
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const complex<_Up>&);
/// Subtract another complex number from this one.
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const complex<_Up>&);
/// Multiply this complex number by another.
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const complex<_Up>&);
/// Divide this complex number by another.
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const complex<_Up>&);
_GLIBCXX_CONSTEXPR complex __rep() const
{ return *this; }
private:
_Tp _M_real;
_Tp _M_imag;
};
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator=(const _Tp& __t)
{
_M_real = __t;
_M_imag = _Tp();
return *this;
}
// 26.2.5/5
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator*=(const _Tp& __t)
{
_M_real *= __t;
_M_imag *= __t;
return *this;
}
// 26.2.5/7
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator/=(const _Tp& __t)
{
_M_real /= __t;
_M_imag /= __t;
return *this;
}
template<typename _Tp>
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator=(const complex<_Up>& __z)
{
_M_real = __z.real();
_M_imag = __z.imag();
return *this;
}
// 26.2.5/9
template<typename _Tp>
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator+=(const complex<_Up>& __z)
{
_M_real += __z.real();
_M_imag += __z.imag();
return *this;
}
// 26.2.5/11
template<typename _Tp>
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator-=(const complex<_Up>& __z)
{
_M_real -= __z.real();
_M_imag -= __z.imag();
return *this;
}
// 26.2.5/13
// XXX: This is a grammar school implementation.
template<typename _Tp>
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator*=(const complex<_Up>& __z)
{
const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
_M_imag = _M_real * __z.imag() + _M_imag * __z.real();
_M_real = __r;
return *this;
}
// 26.2.5/15
// XXX: This is a grammar school implementation.
template<typename _Tp>
template<typename _Up>
_GLIBCXX20_CONSTEXPR complex<_Tp>&
complex<_Tp>::operator/=(const complex<_Up>& __z)
{
const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag();
const _Tp __n = std::norm(__z);
_M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
_M_real = __r / __n;
return *this;
}
// Operators:
//@{
/// Return new complex value @a x plus @a y.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
__r += __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
__r += __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __y;
__r += __x;
return __r;
}
//@}
//@{
/// Return new complex value @a x minus @a y.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
__r -= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator-(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
__r -= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator-(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = -__y;
__r += __x;
return __r;
}
//@}
//@{
/// Return new complex value @a x times @a y.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
__r *= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator*(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
__r *= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator*(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __y;
__r *= __x;
return __r;
}
//@}
//@{
/// Return new complex value @a x divided by @a y.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
__r /= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator/(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
__r /= __y;
return __r;
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator/(const _Tp& __x, const complex<_Tp>& __y)
{
complex<_Tp> __r = __x;
__r /= __y;
return __r;
}
//@}
/// Return @a x.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator+(const complex<_Tp>& __x)
{ return __x; }
/// Return complex negation of @a x.
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
operator-(const complex<_Tp>& __x)
{ return complex<_Tp>(-__x.real(), -__x.imag()); }
//@{
/// Return true if @a x is equal to @a y.
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
{ return __x.real() == __y.real() && __x.imag() == __y.imag(); }
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator==(const complex<_Tp>& __x, const _Tp& __y)
{ return __x.real() == __y && __x.imag() == _Tp(); }
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator==(const _Tp& __x, const complex<_Tp>& __y)
{ return __x == __y.real() && _Tp() == __y.imag(); }
//@}
//@{
/// Return false if @a x is equal to @a y.
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
{ return __x.real() != __y.real() || __x.imag() != __y.imag(); }
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator!=(const complex<_Tp>& __x, const _Tp& __y)
{ return __x.real() != __y || __x.imag() != _Tp(); }
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR bool
operator!=(const _Tp& __x, const complex<_Tp>& __y)
{ return __x != __y.real() || _Tp() != __y.imag(); }
//@}
/// Extraction operator for complex values.
template<typename _Tp, typename _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
{
bool __fail = true;
_CharT __ch;
if (__is >> __ch)
{
if (_Traits::eq(__ch, __is.widen('(')))
{
_Tp __u;
if (__is >> __u >> __ch)
{
const _CharT __rparen = __is.widen(')');
if (_Traits::eq(__ch, __rparen))
{
__x = __u;
__fail = false;
}
else if (_Traits::eq(__ch, __is.widen(',')))
{
_Tp __v;
if (__is >> __v >> __ch)
{
if (_Traits::eq(__ch, __rparen))
{
__x = complex<_Tp>(__u, __v);
__fail = false;
}
else
__is.putback(__ch);
}
}
else
__is.putback(__ch);
}
}
else
{
__is.putback(__ch);
_Tp __u;
if (__is >> __u)
{
__x = __u;
__fail = false;
}
}
}
if (__fail)
__is.setstate(ios_base::failbit);
return __is;
}
/// Insertion operator for complex values.
template<typename _Tp, typename _CharT, class _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
{
basic_ostringstream<_CharT, _Traits> __s;
__s.flags(__os.flags());
__s.imbue(__os.getloc());
__s.precision(__os.precision());
__s << '(' << __x.real() << ',' << __x.imag() << ')';
return __os << __s.str();
}
// Values
#if __cplusplus >= 201103L
template<typename _Tp>
constexpr _Tp
real(const complex<_Tp>& __z)
{ return __z.real(); }
template<typename _Tp>
constexpr _Tp
imag(const complex<_Tp>& __z)
{ return __z.imag(); }
#else
template<typename _Tp>
inline _Tp&
real(complex<_Tp>& __z)
{ return __z.real(); }
template<typename _Tp>
inline const _Tp&
real(const complex<_Tp>& __z)
{ return __z.real(); }
template<typename _Tp>
inline _Tp&
imag(complex<_Tp>& __z)
{ return __z.imag(); }
template<typename _Tp>
inline const _Tp&
imag(const complex<_Tp>& __z)
{ return __z.imag(); }
#endif
// 26.2.7/3 abs(__z): Returns the magnitude of __z.
template<typename _Tp>
inline _Tp
__complex_abs(const complex<_Tp>& __z)
{
_Tp __x = __z.real();
_Tp __y = __z.imag();
const _Tp __s = std::max(abs(__x), abs(__y));
if (__s == _Tp()) // well ...
return __s;
__x /= __s;
__y /= __s;
return __s * sqrt(__x * __x + __y * __y);
}
#if _GLIBCXX_USE_C99_COMPLEX
inline float
__complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); }
inline double
__complex_abs(__complex__ double __z) { return __builtin_cabs(__z); }
inline long double
__complex_abs(const __complex__ long double& __z)
{ return __builtin_cabsl(__z); }
template<typename _Tp>
inline _Tp
abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); }
#else
template<typename _Tp>
inline _Tp
abs(const complex<_Tp>& __z) { return __complex_abs(__z); }
#endif
// 26.2.7/4: arg(__z): Returns the phase angle of __z.
template<typename _Tp>
inline _Tp
__complex_arg(const complex<_Tp>& __z)
{ return atan2(__z.imag(), __z.real()); }
#if _GLIBCXX_USE_C99_COMPLEX
inline float
__complex_arg(__complex__ float __z) { return __builtin_cargf(__z); }
inline double
__complex_arg(__complex__ double __z) { return __builtin_carg(__z); }
inline long double
__complex_arg(const __complex__ long double& __z)
{ return __builtin_cargl(__z); }
template<typename _Tp>
inline _Tp
arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); }
#else
template<typename _Tp>
inline _Tp
arg(const complex<_Tp>& __z) { return __complex_arg(__z); }
#endif
// 26.2.7/5: norm(__z) returns the squared magnitude of __z.
// As defined, norm() is -not- a norm is the common mathematical
// sense used in numerics. The helper class _Norm_helper<> tries to
// distinguish between builtin floating point and the rest, so as
// to deliver an answer as close as possible to the real value.
template<bool>
struct _Norm_helper
{
template<typename _Tp>
static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z)
{
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return __x * __x + __y * __y;
}
};
template<>
struct _Norm_helper<true>
{
template<typename _Tp>
static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z)
{
//_Tp __res = std::abs(__z);
//return __res * __res;
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return __x * __x + __y * __y;
}
};
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR _Tp
norm(const complex<_Tp>& __z)
{
return _Norm_helper<__is_floating<_Tp>::__value
&& !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
}
template<typename _Tp>
inline complex<_Tp>
polar(const _Tp& __rho, const _Tp& __theta)
{
__glibcxx_assert( __rho >= 0 );
return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta));
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR complex<_Tp>
conj(const complex<_Tp>& __z)
{ return complex<_Tp>(__z.real(), -__z.imag()); }
// Transcendentals
// 26.2.8/1 cos(__z): Returns the cosine of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_cos(const complex<_Tp>& __z)
{
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
}
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); }
inline __complex__ double
__complex_cos(__complex__ double __z) { return __builtin_ccos(__z); }
inline __complex__ long double
__complex_cos(const __complex__ long double& __z)
{ return __builtin_ccosl(__z); }
template<typename _Tp>
inline complex<_Tp>
cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
cos(const complex<_Tp>& __z) { return __complex_cos(__z); }
#endif
// 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_cosh(const complex<_Tp>& __z)
{
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
}
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); }
inline __complex__ double
__complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); }
inline __complex__ long double
__complex_cosh(const __complex__ long double& __z)
{ return __builtin_ccoshl(__z); }
template<typename _Tp>
inline complex<_Tp>
cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); }
#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<_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)
{ return __builtin_cexpl(__z); }
template<typename _Tp>
inline complex<_Tp>
exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
exp(const complex<_Tp>& __z) { return __complex_exp(__z); }
#endif
// 26.2.8/5 log(__z): Returns the natural complex logarithm of __z.
// The branch cut is along the negative axis.
template<typename _Tp>
inline complex<_Tp>
__complex_log(const complex<_Tp>& __z)
{ return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_log(__complex__ float __z) { return __builtin_clogf(__z); }
inline __complex__ double
__complex_log(__complex__ double __z) { return __builtin_clog(__z); }
inline __complex__ long double
__complex_log(const __complex__ long double& __z)
{ return __builtin_clogl(__z); }
template<typename _Tp>
inline complex<_Tp>
log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
log(const complex<_Tp>& __z) { return __complex_log(__z); }
#endif
template<typename _Tp>
inline complex<_Tp>
log10(const complex<_Tp>& __z)
{ return std::log(__z) / log(_Tp(10.0)); }
// 26.2.8/10 sin(__z): Returns the sine of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_sin(const complex<_Tp>& __z)
{
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y));
}
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_sin(__complex__ float __z) { return __builtin_csinf(__z); }
inline __complex__ double
__complex_sin(__complex__ double __z) { return __builtin_csin(__z); }
inline __complex__ long double
__complex_sin(const __complex__ long double& __z)
{ return __builtin_csinl(__z); }
template<typename _Tp>
inline complex<_Tp>
sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
sin(const complex<_Tp>& __z) { return __complex_sin(__z); }
#endif
// 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_sinh(const complex<_Tp>& __z)
{
const _Tp __x = __z.real();
const _Tp __y = __z.imag();
return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
}
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); }
inline __complex__ double
__complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); }
inline __complex__ long double
__complex_sinh(const __complex__ long double& __z)
{ return __builtin_csinhl(__z); }
template<typename _Tp>
inline complex<_Tp>
sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); }
#endif
// 26.2.8/13 sqrt(__z): Returns the complex square root of __z.
// The branch cut is on the negative axis.
template<typename _Tp>
complex<_Tp>
__complex_sqrt(const complex<_Tp>& __z)
{
_Tp __x = __z.real();
_Tp __y = __z.imag();
if (__x == _Tp())
{
_Tp __t = sqrt(abs(__y) / 2);
return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
}
else
{
_Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
_Tp __u = __t / 2;
return __x > _Tp()
? complex<_Tp>(__u, __y / __t)
: complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
}
}
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); }
inline __complex__ double
__complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); }
inline __complex__ long double
__complex_sqrt(const __complex__ long double& __z)
{ return __builtin_csqrtl(__z); }
template<typename _Tp>
inline complex<_Tp>
sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); }
#endif
// 26.2.8/14 tan(__z): Return the complex tangent of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_tan(const complex<_Tp>& __z)
{ return std::sin(__z) / std::cos(__z); }
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); }
inline __complex__ double
__complex_tan(__complex__ double __z) { return __builtin_ctan(__z); }
inline __complex__ long double
__complex_tan(const __complex__ long double& __z)
{ return __builtin_ctanl(__z); }
template<typename _Tp>
inline complex<_Tp>
tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
tan(const complex<_Tp>& __z) { return __complex_tan(__z); }
#endif
// 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z.
template<typename _Tp>
inline complex<_Tp>
__complex_tanh(const complex<_Tp>& __z)
{ return std::sinh(__z) / std::cosh(__z); }
#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); }
inline __complex__ double
__complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); }
inline __complex__ long double
__complex_tanh(const __complex__ long double& __z)
{ return __builtin_ctanhl(__z); }
template<typename _Tp>
inline complex<_Tp>
tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); }
#else
template<typename _Tp>
inline complex<_Tp>
tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); }
#endif
// 26.2.8/9 pow(__x, __y): Returns the complex power base of __x
// raised to the __y-th power. The branch
// cut is on the negative axis.
template<typename _Tp>
complex<_Tp>
__complex_pow_unsigned(complex<_Tp> __x, unsigned __n)
{
complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1);
while (__n >>= 1)
{
__x *= __x;
if (__n % 2)
__y *= __x;
}
return __y;
}
// In C++11 mode we used to implement the resolution of
// DR 844. complex pow return type is ambiguous.
// thus the following overload was disabled in that mode. However, doing
// that causes all sorts of issues, see, for example:
// http://gcc.gnu.org/ml/libstdc++/2013-01/msg00058.html
// and also PR57974.
template<typename _Tp>
inline complex<_Tp>
pow(const complex<_Tp>& __z, int __n)
{
return __n < 0
? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n)
: std::__complex_pow_unsigned(__z, __n);
}
template<typename _Tp>
complex<_Tp>
pow(const complex<_Tp>& __x, const _Tp& __y)
{
#if ! _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<_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)
{ return __builtin_cpowf(__x, __y); }
inline __complex__ double
__complex_pow(__complex__ double __x, __complex__ double __y)
{ return __builtin_cpow(__x, __y); }
inline __complex__ long double
__complex_pow(const __complex__ long double& __x,
const __complex__ long double& __y)
{ return __builtin_cpowl(__x, __y); }
template<typename _Tp>
inline complex<_Tp>
pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
{ return __complex_pow(__x.__rep(), __y.__rep()); }
#else
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<_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;
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
_GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f)
#if __cplusplus >= 201103L
: _M_value{ __r, __i } { }
#else
{
__real__ _M_value = __r;
__imag__ _M_value = __i;
}
#endif
explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&);
explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
__attribute ((__abi_tag__ ("cxx11")))
constexpr float
real() const { return __real__ _M_value; }
__attribute ((__abi_tag__ ("cxx11")))
constexpr float
imag() const { return __imag__ _M_value; }
#else
float&
real() { return __real__ _M_value; }
const float&
real() const { return __real__ _M_value; }
float&
imag() { return __imag__ _M_value; }
const float&
imag() const { return __imag__ _M_value; }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
_GLIBCXX20_CONSTEXPR void
real(float __val) { __real__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR void
imag(float __val) { __imag__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR complex&
operator=(float __f)
{
_M_value = __f;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator+=(float __f)
{
_M_value += __f;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator-=(float __f)
{
_M_value -= __f;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator*=(float __f)
{
_M_value *= __f;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator/=(float __f)
{
_M_value /= __f;
return *this;
}
// Let the compiler synthesize the copy and assignment
// operator. It always does a pretty good job.
#if __cplusplus >= 201103L
_GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default;
#endif
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator=(const complex<_Tp>& __z)
{
__real__ _M_value = __z.real();
__imag__ _M_value = __z.imag();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator+=(const complex<_Tp>& __z)
{
_M_value += __z.__rep();
return *this;
}
template<class _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator-=(const complex<_Tp>& __z)
{
_M_value -= __z.__rep();
return *this;
}
template<class _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator*=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value *= __t;
return *this;
}
template<class _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator/=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value /= __t;
return *this;
}
_GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; }
private:
_ComplexT _M_value;
};
/// 26.2.3 complex specializations
/// complex<double> specialization
template<>
struct complex<double>
{
typedef double value_type;
typedef __complex__ double _ComplexT;
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
_GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0)
#if __cplusplus >= 201103L
: _M_value{ __r, __i } { }
#else
{
__real__ _M_value = __r;
__imag__ _M_value = __i;
}
#endif
_GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
: _M_value(__z.__rep()) { }
explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
__attribute ((__abi_tag__ ("cxx11")))
constexpr double
real() const { return __real__ _M_value; }
__attribute ((__abi_tag__ ("cxx11")))
constexpr double
imag() const { return __imag__ _M_value; }
#else
double&
real() { return __real__ _M_value; }
const double&
real() const { return __real__ _M_value; }
double&
imag() { return __imag__ _M_value; }
const double&
imag() const { return __imag__ _M_value; }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
_GLIBCXX20_CONSTEXPR void
real(double __val) { __real__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR void
imag(double __val) { __imag__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR complex&
operator=(double __d)
{
_M_value = __d;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator+=(double __d)
{
_M_value += __d;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator-=(double __d)
{
_M_value -= __d;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator*=(double __d)
{
_M_value *= __d;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator/=(double __d)
{
_M_value /= __d;
return *this;
}
// The compiler will synthesize this, efficiently.
#if __cplusplus >= 201103L
_GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default;
#endif
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator=(const complex<_Tp>& __z)
{
_M_value = __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator+=(const complex<_Tp>& __z)
{
_M_value += __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator-=(const complex<_Tp>& __z)
{
_M_value -= __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator*=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value *= __t;
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator/=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value /= __t;
return *this;
}
_GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; }
private:
_ComplexT _M_value;
};
/// 26.2.3 complex specializations
/// complex<long double> specialization
template<>
struct complex<long double>
{
typedef long double value_type;
typedef __complex__ long double _ComplexT;
_GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
_GLIBCXX_CONSTEXPR complex(long double __r = 0.0L,
long double __i = 0.0L)
#if __cplusplus >= 201103L
: _M_value{ __r, __i } { }
#else
{
__real__ _M_value = __r;
__imag__ _M_value = __i;
}
#endif
_GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
: _M_value(__z.__rep()) { }
_GLIBCXX_CONSTEXPR complex(const complex<double>& __z)
: _M_value(__z.__rep()) { }
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
__attribute ((__abi_tag__ ("cxx11")))
constexpr long double
real() const { return __real__ _M_value; }
__attribute ((__abi_tag__ ("cxx11")))
constexpr long double
imag() const { return __imag__ _M_value; }
#else
long double&
real() { return __real__ _M_value; }
const long double&
real() const { return __real__ _M_value; }
long double&
imag() { return __imag__ _M_value; }
const long double&
imag() const { return __imag__ _M_value; }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 387. std::complex over-encapsulated.
_GLIBCXX20_CONSTEXPR void
real(long double __val) { __real__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR void
imag(long double __val) { __imag__ _M_value = __val; }
_GLIBCXX20_CONSTEXPR complex&
operator=(long double __r)
{
_M_value = __r;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator+=(long double __r)
{
_M_value += __r;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator-=(long double __r)
{
_M_value -= __r;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator*=(long double __r)
{
_M_value *= __r;
return *this;
}
_GLIBCXX20_CONSTEXPR complex&
operator/=(long double __r)
{
_M_value /= __r;
return *this;
}
// The compiler knows how to do this efficiently
#if __cplusplus >= 201103L
_GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default;
#endif
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator=(const complex<_Tp>& __z)
{
_M_value = __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator+=(const complex<_Tp>& __z)
{
_M_value += __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator-=(const complex<_Tp>& __z)
{
_M_value -= __z.__rep();
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator*=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value *= __t;
return *this;
}
template<typename _Tp>
_GLIBCXX20_CONSTEXPR complex&
operator/=(const complex<_Tp>& __z)
{
const _ComplexT __t = __z.__rep();
_M_value /= __t;
return *this;
}
_GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; }
private:
_ComplexT _M_value;
};
// These bits have to be at the end of this file, so that the
// specializations have all been defined.
inline _GLIBCXX_CONSTEXPR
complex<float>::complex(const complex<double>& __z)
: _M_value(__z.__rep()) { }
inline _GLIBCXX_CONSTEXPR
complex<float>::complex(const complex<long double>& __z)
: _M_value(__z.__rep()) { }
inline _GLIBCXX_CONSTEXPR
complex<double>::complex(const complex<long double>& __z)
: _M_value(__z.__rep()) { }
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template istream& operator>>(istream&, complex<float>&);
extern template ostream& operator<<(ostream&, const complex<float>&);
extern template istream& operator>>(istream&, complex<double>&);
extern template ostream& operator<<(ostream&, const complex<double>&);
extern template istream& operator>>(istream&, complex<long double>&);
extern template ostream& operator<<(ostream&, const complex<long double>&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template wistream& operator>>(wistream&, complex<float>&);
extern template wostream& operator<<(wostream&, const complex<float>&);
extern template wistream& operator>>(wistream&, complex<double>&);
extern template wostream& operator<<(wostream&, const complex<double>&);
extern template wistream& operator>>(wistream&, complex<long double>&);
extern template wostream& operator<<(wostream&, const complex<long double>&);
#endif
#endif
// @} group complex_numbers
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// See ext/type_traits.h for the primary template.
template<typename _Tp, typename _Up>
struct __promote_2<std::complex<_Tp>, _Up>
{
public:
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
};
template<typename _Tp, typename _Up>
struct __promote_2<_Tp, std::complex<_Up> >
{
public:
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
};
template<typename _Tp, typename _Up>
struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
{
public:
typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Forward declarations.
template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
// DR 595.
template<typename _Tp> _Tp fabs(const std::complex<_Tp>&);
template<typename _Tp>
inline std::complex<_Tp>
__complex_acos(const std::complex<_Tp>& __z)
{
const std::complex<_Tp> __t = std::asin(__z);
const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_acos(__complex__ float __z)
{ return __builtin_cacosf(__z); }
inline __complex__ double
__complex_acos(__complex__ double __z)
{ return __builtin_cacos(__z); }
inline __complex__ long double
__complex_acos(const __complex__ long double& __z)
{ return __builtin_cacosl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
acos(const std::complex<_Tp>& __z)
{ return __complex_acos(__z.__rep()); }
#else
/// acos(__z) [8.1.2].
// Effects: Behaves the same as C99 function cacos, defined
// in subclause 7.3.5.1.
template<typename _Tp>
inline std::complex<_Tp>
acos(const std::complex<_Tp>& __z)
{ return __complex_acos(__z); }
#endif
template<typename _Tp>
inline std::complex<_Tp>
__complex_asin(const std::complex<_Tp>& __z)
{
std::complex<_Tp> __t(-__z.imag(), __z.real());
__t = std::asinh(__t);
return std::complex<_Tp>(__t.imag(), -__t.real());
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_asin(__complex__ float __z)
{ return __builtin_casinf(__z); }
inline __complex__ double
__complex_asin(__complex__ double __z)
{ return __builtin_casin(__z); }
inline __complex__ long double
__complex_asin(const __complex__ long double& __z)
{ return __builtin_casinl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
asin(const std::complex<_Tp>& __z)
{ return __complex_asin(__z.__rep()); }
#else
/// asin(__z) [8.1.3].
// Effects: Behaves the same as C99 function casin, defined
// in subclause 7.3.5.2.
template<typename _Tp>
inline std::complex<_Tp>
asin(const std::complex<_Tp>& __z)
{ return __complex_asin(__z); }
#endif
template<typename _Tp>
std::complex<_Tp>
__complex_atan(const std::complex<_Tp>& __z)
{
const _Tp __r2 = __z.real() * __z.real();
const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
_Tp __num = __z.imag() + _Tp(1.0);
_Tp __den = __z.imag() - _Tp(1.0);
__num = __r2 + __num * __num;
__den = __r2 + __den * __den;
return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
_Tp(0.25) * log(__num / __den));
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_atan(__complex__ float __z)
{ return __builtin_catanf(__z); }
inline __complex__ double
__complex_atan(__complex__ double __z)
{ return __builtin_catan(__z); }
inline __complex__ long double
__complex_atan(const __complex__ long double& __z)
{ return __builtin_catanl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
atan(const std::complex<_Tp>& __z)
{ return __complex_atan(__z.__rep()); }
#else
/// atan(__z) [8.1.4].
// Effects: Behaves the same as C99 function catan, defined
// in subclause 7.3.5.3.
template<typename _Tp>
inline std::complex<_Tp>
atan(const std::complex<_Tp>& __z)
{ return __complex_atan(__z); }
#endif
template<typename _Tp>
std::complex<_Tp>
__complex_acosh(const std::complex<_Tp>& __z)
{
// Kahan's formula.
return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
+ std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_acosh(__complex__ float __z)
{ return __builtin_cacoshf(__z); }
inline __complex__ double
__complex_acosh(__complex__ double __z)
{ return __builtin_cacosh(__z); }
inline __complex__ long double
__complex_acosh(const __complex__ long double& __z)
{ return __builtin_cacoshl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
acosh(const std::complex<_Tp>& __z)
{ return __complex_acosh(__z.__rep()); }
#else
/// acosh(__z) [8.1.5].
// Effects: Behaves the same as C99 function cacosh, defined
// in subclause 7.3.6.1.
template<typename _Tp>
inline std::complex<_Tp>
acosh(const std::complex<_Tp>& __z)
{ return __complex_acosh(__z); }
#endif
template<typename _Tp>
std::complex<_Tp>
__complex_asinh(const std::complex<_Tp>& __z)
{
std::complex<_Tp> __t((__z.real() - __z.imag())
* (__z.real() + __z.imag()) + _Tp(1.0),
_Tp(2.0) * __z.real() * __z.imag());
__t = std::sqrt(__t);
return std::log(__t + __z);
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_asinh(__complex__ float __z)
{ return __builtin_casinhf(__z); }
inline __complex__ double
__complex_asinh(__complex__ double __z)
{ return __builtin_casinh(__z); }
inline __complex__ long double
__complex_asinh(const __complex__ long double& __z)
{ return __builtin_casinhl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
asinh(const std::complex<_Tp>& __z)
{ return __complex_asinh(__z.__rep()); }
#else
/// asinh(__z) [8.1.6].
// Effects: Behaves the same as C99 function casin, defined
// in subclause 7.3.6.2.
template<typename _Tp>
inline std::complex<_Tp>
asinh(const std::complex<_Tp>& __z)
{ return __complex_asinh(__z); }
#endif
template<typename _Tp>
std::complex<_Tp>
__complex_atanh(const std::complex<_Tp>& __z)
{
const _Tp __i2 = __z.imag() * __z.imag();
const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
_Tp __num = _Tp(1.0) + __z.real();
_Tp __den = _Tp(1.0) - __z.real();
__num = __i2 + __num * __num;
__den = __i2 + __den * __den;
return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
_Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
}
#if _GLIBCXX_USE_C99_COMPLEX_TR1
inline __complex__ float
__complex_atanh(__complex__ float __z)
{ return __builtin_catanhf(__z); }
inline __complex__ double
__complex_atanh(__complex__ double __z)
{ return __builtin_catanh(__z); }
inline __complex__ long double
__complex_atanh(const __complex__ long double& __z)
{ return __builtin_catanhl(__z); }
template<typename _Tp>
inline std::complex<_Tp>
atanh(const std::complex<_Tp>& __z)
{ return __complex_atanh(__z.__rep()); }
#else
/// atanh(__z) [8.1.7].
// Effects: Behaves the same as C99 function catanh, defined
// in subclause 7.3.6.3.
template<typename _Tp>
inline std::complex<_Tp>
atanh(const std::complex<_Tp>& __z)
{ return __complex_atanh(__z); }
#endif
template<typename _Tp>
inline _Tp
/// fabs(__z) [8.1.8].
// Effects: Behaves the same as C99 function cabs, defined
// in subclause 7.3.8.1.
fabs(const std::complex<_Tp>& __z)
{ return std::abs(__z); }
/// Additional overloads [8.1.9].
template<typename _Tp>
inline typename __gnu_cxx::__promote<_Tp>::__type
arg(_Tp __x)
{
typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
#if (_GLIBCXX11_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
: __type();
#else
return std::arg(std::complex<__type>(__x));
#endif
}
template<typename _Tp>
_GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type
imag(_Tp)
{ return _Tp(); }
template<typename _Tp>
_GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type
norm(_Tp __x)
{
typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
return __type(__x) * __type(__x);
}
template<typename _Tp>
_GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type
real(_Tp __x)
{ return __x; }
template<typename _Tp, typename _Up>
inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
pow(const std::complex<_Tp>& __x, const _Up& __y)
{
typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
return std::pow(std::complex<__type>(__x), __type(__y));
}
template<typename _Tp, typename _Up>
inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
pow(const _Tp& __x, const std::complex<_Up>& __y)
{
typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
return std::pow(__type(__x), std::complex<__type>(__y));
}
template<typename _Tp, typename _Up>
inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
{
typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
return std::pow(std::complex<__type>(__x),
std::complex<__type>(__y));
}
// Forward declarations.
// DR 781.
template<typename _Tp>
std::complex<_Tp> proj(const std::complex<_Tp>&);
// Generic implementation of std::proj, does not work for infinities.
template<typename _Tp>
inline std::complex<_Tp>
__complex_proj(const std::complex<_Tp>& __z)
{ return __z; }
#if _GLIBCXX_USE_C99_COMPLEX
inline complex<float>
__complex_proj(const complex<float>& __z)
{ return __builtin_cprojf(__z.__rep()); }
inline complex<double>
__complex_proj(const complex<double>& __z)
{ return __builtin_cproj(__z.__rep()); }
inline complex<long double>
__complex_proj(const complex<long double>& __z)
{ return __builtin_cprojl(__z.__rep()); }
#elif defined _GLIBCXX_USE_C99_MATH_TR1
inline complex<float>
__complex_proj(const complex<float>& __z)
{
if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag()))
return complex<float>(__builtin_inff(),
__builtin_copysignf(0.0f, __z.imag()));
return __z;
}
inline complex<double>
__complex_proj(const complex<double>& __z)
{
if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag()))
return complex<double>(__builtin_inf(),
__builtin_copysign(0.0, __z.imag()));
return __z;
}
inline complex<long double>
__complex_proj(const complex<long double>& __z)
{
if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag()))
return complex<long double>(__builtin_infl(),
__builtin_copysignl(0.0l, __z.imag()));
return __z;
}
#endif
template<typename _Tp>
inline std::complex<_Tp>
proj(const std::complex<_Tp>& __z)
{ return __complex_proj(__z); }
// Overload for scalars
template<typename _Tp>
inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
proj(_Tp __x)
{
typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
return std::proj(std::complex<__type>(__x));
}
template<typename _Tp>
inline _GLIBCXX20_CONSTEXPR
std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
conj(_Tp __x)
{
typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
return std::complex<__type>(__x, -__type());
}
#if __cplusplus > 201103L
inline namespace literals {
inline namespace complex_literals {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wliteral-suffix"
#define __cpp_lib_complex_udls 201309
constexpr std::complex<float>
operator""if(long double __num)
{ return std::complex<float>{0.0F, static_cast<float>(__num)}; }
constexpr std::complex<float>
operator""if(unsigned long long __num)
{ return std::complex<float>{0.0F, static_cast<float>(__num)}; }
constexpr std::complex<double>
operator""i(long double __num)
{ return std::complex<double>{0.0, static_cast<double>(__num)}; }
constexpr std::complex<double>
operator""i(unsigned long long __num)
{ return std::complex<double>{0.0, static_cast<double>(__num)}; }
constexpr std::complex<long double>
operator""il(long double __num)
{ return std::complex<long double>{0.0L, __num}; }
constexpr std::complex<long double>
operator""il(unsigned long long __num)
{ return std::complex<long double>{0.0L, static_cast<long double>(__num)}; }
#pragma GCC diagnostic pop
} // inline namespace complex_literals
} // inline namespace literals
#endif // C++14
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif /* _GLIBCXX_COMPLEX */