14fee23f9Smrg// The template and inlines for the -*- C++ -*- complex number classes. 24fee23f9Smrg 3e9e6e0f6Smrg// Copyright (C) 1997-2022 Free Software Foundation, Inc. 44fee23f9Smrg// 54fee23f9Smrg// This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg// software; you can redistribute it and/or modify it under the 74fee23f9Smrg// terms of the GNU General Public License as published by the 84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg// any later version. 104fee23f9Smrg 114fee23f9Smrg// This library is distributed in the hope that it will be useful, 124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg// GNU General Public License for more details. 154fee23f9Smrg 164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg// 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg// You should have received a copy of the GNU General Public License and 214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg// <http://www.gnu.org/licenses/>. 244fee23f9Smrg 254fee23f9Smrg/** @file include/complex 264fee23f9Smrg * This is a Standard C++ Library header. 274fee23f9Smrg */ 284fee23f9Smrg 294fee23f9Smrg// 304fee23f9Smrg// ISO C++ 14882: 26.2 Complex Numbers 314fee23f9Smrg// Note: this is not a conforming implementation. 324fee23f9Smrg// Initially implemented by Ulrich Drepper <drepper@cygnus.com> 334fee23f9Smrg// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 344fee23f9Smrg// 354fee23f9Smrg 364fee23f9Smrg#ifndef _GLIBCXX_COMPLEX 374fee23f9Smrg#define _GLIBCXX_COMPLEX 1 384fee23f9Smrg 394fee23f9Smrg#pragma GCC system_header 404fee23f9Smrg 414fee23f9Smrg#include <bits/c++config.h> 424fee23f9Smrg#include <bits/cpp_type_traits.h> 434fee23f9Smrg#include <ext/type_traits.h> 444fee23f9Smrg#include <cmath> 454fee23f9Smrg#include <sstream> 464fee23f9Smrg 473965f5d7Schristos#if _GLIBCXX_USE_C99_COMPLEX 4840fc864aSwiz// This is disgusting; we can't include ccomplex because that requires c++11 493965f5d7Schristos// and we can't use the builtins because those point to the wrong 503965f5d7Schristos// ABI-wise cabs/cabsf so we manually declare those here and use 513965f5d7Schristos// them directly. 523965f5d7Schristosextern "C" float __c99_cabsf(_Complex float); 533965f5d7Schristosextern "C" double __c99_cabs(_Complex double); 543965f5d7Schristosextern "C" long double __c99_cabsl(_Complex long double); 553965f5d7Schristos#endif 563965f5d7Schristos 5748fb7bfaSmrg// Get rid of a macro possibly defined in <complex.h> 5848fb7bfaSmrg#undef complex 5948fb7bfaSmrg 6043265c03Smrg#if __cplusplus > 201703L 6143265c03Smrg# define __cpp_lib_constexpr_complex 201711L 6243265c03Smrg#endif 6343265c03Smrg 6448fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default) 6548fb7bfaSmrg{ 6648fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 674fee23f9Smrg 684fee23f9Smrg /** 694fee23f9Smrg * @defgroup complex_numbers Complex Numbers 704fee23f9Smrg * @ingroup numerics 714fee23f9Smrg * 724fee23f9Smrg * Classes and functions for complex numbers. 734fee23f9Smrg * @{ 744fee23f9Smrg */ 754fee23f9Smrg 764fee23f9Smrg // Forward declarations. 774fee23f9Smrg template<typename _Tp> class complex; 784fee23f9Smrg template<> class complex<float>; 794fee23f9Smrg template<> class complex<double>; 804fee23f9Smrg template<> class complex<long double>; 814fee23f9Smrg 824fee23f9Smrg /// Return magnitude of @a z. 834fee23f9Smrg template<typename _Tp> _Tp abs(const complex<_Tp>&); 844fee23f9Smrg /// Return phase angle of @a z. 854fee23f9Smrg template<typename _Tp> _Tp arg(const complex<_Tp>&); 864fee23f9Smrg /// Return @a z magnitude squared. 87654d12c0Smrg template<typename _Tp> _Tp _GLIBCXX20_CONSTEXPR norm(const complex<_Tp>&); 884fee23f9Smrg 894fee23f9Smrg /// Return complex conjugate of @a z. 90654d12c0Smrg template<typename _Tp> 91654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&); 924fee23f9Smrg /// Return complex with magnitude @a rho and angle @a theta. 934fee23f9Smrg template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 944fee23f9Smrg 954fee23f9Smrg // Transcendentals: 964fee23f9Smrg /// Return complex cosine of @a z. 974fee23f9Smrg template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 984fee23f9Smrg /// Return complex hyperbolic cosine of @a z. 994fee23f9Smrg template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 1004fee23f9Smrg /// Return complex base e exponential of @a z. 1014fee23f9Smrg template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 1024fee23f9Smrg /// Return complex natural logarithm of @a z. 1034fee23f9Smrg template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 1044fee23f9Smrg /// Return complex base 10 logarithm of @a z. 1054fee23f9Smrg template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 1064fee23f9Smrg /// Return @a x to the @a y'th power. 1074fee23f9Smrg template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 1084fee23f9Smrg /// Return @a x to the @a y'th power. 1094fee23f9Smrg template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 1104fee23f9Smrg /// Return @a x to the @a y'th power. 1114fee23f9Smrg template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 1124fee23f9Smrg const complex<_Tp>&); 1134fee23f9Smrg /// Return @a x to the @a y'th power. 1144fee23f9Smrg template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 1154fee23f9Smrg /// Return complex sine of @a z. 1164fee23f9Smrg template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 1174fee23f9Smrg /// Return complex hyperbolic sine of @a z. 1184fee23f9Smrg template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 1194fee23f9Smrg /// Return complex square root of @a z. 1204fee23f9Smrg template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 1214fee23f9Smrg /// Return complex tangent of @a z. 1224fee23f9Smrg template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 1234fee23f9Smrg /// Return complex hyperbolic tangent of @a z. 1244fee23f9Smrg template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 1254fee23f9Smrg 1264fee23f9Smrg 1274fee23f9Smrg // 26.2.2 Primary template class complex 1284fee23f9Smrg /** 1294fee23f9Smrg * Template to represent complex numbers. 1304fee23f9Smrg * 1314fee23f9Smrg * Specializations for float, double, and long double are part of the 1324fee23f9Smrg * library. Results with any other type are not guaranteed. 1334fee23f9Smrg * 1344fee23f9Smrg * @param Tp Type of real and imaginary values. 1354fee23f9Smrg */ 1364fee23f9Smrg template<typename _Tp> 137e9e6e0f6Smrg class complex 1384fee23f9Smrg { 139e9e6e0f6Smrg public: 1404fee23f9Smrg /// Value typedef. 1414fee23f9Smrg typedef _Tp value_type; 1424fee23f9Smrg 1434fee23f9Smrg /// Default constructor. First parameter is x, second parameter is y. 1444fee23f9Smrg /// Unspecified parameters default to 0. 14548fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp()) 1464fee23f9Smrg : _M_real(__r), _M_imag(__i) { } 1474fee23f9Smrg 148d35849d0Smrg // Let the compiler synthesize the copy constructor 149d35849d0Smrg#if __cplusplus >= 201103L 150d35849d0Smrg constexpr complex(const complex&) = default; 151d35849d0Smrg#endif 152d35849d0Smrg 153d35849d0Smrg /// Converting constructor. 1544fee23f9Smrg template<typename _Up> 15548fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z) 1564fee23f9Smrg : _M_real(__z.real()), _M_imag(__z.imag()) { } 1574fee23f9Smrg 15848fb7bfaSmrg#if __cplusplus >= 201103L 1594fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1604fee23f9Smrg // DR 387. std::complex over-encapsulated. 16148fb7bfaSmrg _GLIBCXX_ABI_TAG_CXX11 16248fb7bfaSmrg constexpr _Tp 163d35849d0Smrg real() const { return _M_real; } 1644fee23f9Smrg 16548fb7bfaSmrg _GLIBCXX_ABI_TAG_CXX11 16648fb7bfaSmrg constexpr _Tp 167d35849d0Smrg imag() const { return _M_imag; } 1684fee23f9Smrg#else 1694fee23f9Smrg /// Return real part of complex number. 17048fb7bfaSmrg _Tp& 17148fb7bfaSmrg real() { return _M_real; } 1724fee23f9Smrg 1734fee23f9Smrg /// Return real part of complex number. 17448fb7bfaSmrg const _Tp& 17548fb7bfaSmrg real() const { return _M_real; } 1764fee23f9Smrg 1774fee23f9Smrg /// Return imaginary part of complex number. 17848fb7bfaSmrg _Tp& 17948fb7bfaSmrg imag() { return _M_imag; } 1804fee23f9Smrg 1814fee23f9Smrg /// Return imaginary part of complex number. 18248fb7bfaSmrg const _Tp& 18348fb7bfaSmrg imag() const { return _M_imag; } 1844fee23f9Smrg#endif 1854fee23f9Smrg 1864fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1874fee23f9Smrg // DR 387. std::complex over-encapsulated. 188654d12c0Smrg _GLIBCXX20_CONSTEXPR void 18948fb7bfaSmrg real(_Tp __val) { _M_real = __val; } 1904fee23f9Smrg 191654d12c0Smrg _GLIBCXX20_CONSTEXPR void 19248fb7bfaSmrg imag(_Tp __val) { _M_imag = __val; } 1934fee23f9Smrg 194d35849d0Smrg /// Assign a scalar to this complex number. 195654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const _Tp&); 1964fee23f9Smrg 197d35849d0Smrg /// Add a scalar to this complex number. 1984fee23f9Smrg // 26.2.5/1 199654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2004fee23f9Smrg operator+=(const _Tp& __t) 2014fee23f9Smrg { 2024fee23f9Smrg _M_real += __t; 2034fee23f9Smrg return *this; 2044fee23f9Smrg } 2054fee23f9Smrg 206d35849d0Smrg /// Subtract a scalar from this complex number. 2074fee23f9Smrg // 26.2.5/3 208654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2094fee23f9Smrg operator-=(const _Tp& __t) 2104fee23f9Smrg { 2114fee23f9Smrg _M_real -= __t; 2124fee23f9Smrg return *this; 2134fee23f9Smrg } 2144fee23f9Smrg 215d35849d0Smrg /// Multiply this complex number by a scalar. 216654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const _Tp&); 217d35849d0Smrg /// Divide this complex number by a scalar. 218654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const _Tp&); 2194fee23f9Smrg 220d35849d0Smrg // Let the compiler synthesize the copy assignment operator 221d35849d0Smrg#if __cplusplus >= 201103L 222654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& operator=(const complex&) = default; 223d35849d0Smrg#endif 224d35849d0Smrg 225d35849d0Smrg /// Assign another complex number to this one. 2264fee23f9Smrg template<typename _Up> 227654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const complex<_Up>&); 228d35849d0Smrg /// Add another complex number to this one. 2294fee23f9Smrg template<typename _Up> 230654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const complex<_Up>&); 231d35849d0Smrg /// Subtract another complex number from this one. 2324fee23f9Smrg template<typename _Up> 233654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const complex<_Up>&); 234d35849d0Smrg /// Multiply this complex number by another. 2354fee23f9Smrg template<typename _Up> 236654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const complex<_Up>&); 237d35849d0Smrg /// Divide this complex number by another. 2384fee23f9Smrg template<typename _Up> 239654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const complex<_Up>&); 2404fee23f9Smrg 241d35849d0Smrg _GLIBCXX_CONSTEXPR complex __rep() const 2424fee23f9Smrg { return *this; } 2434fee23f9Smrg 2444fee23f9Smrg private: 2454fee23f9Smrg _Tp _M_real; 2464fee23f9Smrg _Tp _M_imag; 2474fee23f9Smrg }; 2484fee23f9Smrg 2494fee23f9Smrg template<typename _Tp> 250654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2514fee23f9Smrg complex<_Tp>::operator=(const _Tp& __t) 2524fee23f9Smrg { 2534fee23f9Smrg _M_real = __t; 2544fee23f9Smrg _M_imag = _Tp(); 2554fee23f9Smrg return *this; 2564fee23f9Smrg } 2574fee23f9Smrg 2584fee23f9Smrg // 26.2.5/5 2594fee23f9Smrg template<typename _Tp> 260654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2614fee23f9Smrg complex<_Tp>::operator*=(const _Tp& __t) 2624fee23f9Smrg { 2634fee23f9Smrg _M_real *= __t; 2644fee23f9Smrg _M_imag *= __t; 2654fee23f9Smrg return *this; 2664fee23f9Smrg } 2674fee23f9Smrg 2684fee23f9Smrg // 26.2.5/7 2694fee23f9Smrg template<typename _Tp> 270654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2714fee23f9Smrg complex<_Tp>::operator/=(const _Tp& __t) 2724fee23f9Smrg { 2734fee23f9Smrg _M_real /= __t; 2744fee23f9Smrg _M_imag /= __t; 2754fee23f9Smrg return *this; 2764fee23f9Smrg } 2774fee23f9Smrg 2784fee23f9Smrg template<typename _Tp> 2794fee23f9Smrg template<typename _Up> 280654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2814fee23f9Smrg complex<_Tp>::operator=(const complex<_Up>& __z) 2824fee23f9Smrg { 2834fee23f9Smrg _M_real = __z.real(); 2844fee23f9Smrg _M_imag = __z.imag(); 2854fee23f9Smrg return *this; 2864fee23f9Smrg } 2874fee23f9Smrg 2884fee23f9Smrg // 26.2.5/9 2894fee23f9Smrg template<typename _Tp> 2904fee23f9Smrg template<typename _Up> 291654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 2924fee23f9Smrg complex<_Tp>::operator+=(const complex<_Up>& __z) 2934fee23f9Smrg { 2944fee23f9Smrg _M_real += __z.real(); 2954fee23f9Smrg _M_imag += __z.imag(); 2964fee23f9Smrg return *this; 2974fee23f9Smrg } 2984fee23f9Smrg 2994fee23f9Smrg // 26.2.5/11 3004fee23f9Smrg template<typename _Tp> 3014fee23f9Smrg template<typename _Up> 302654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 3034fee23f9Smrg complex<_Tp>::operator-=(const complex<_Up>& __z) 3044fee23f9Smrg { 3054fee23f9Smrg _M_real -= __z.real(); 3064fee23f9Smrg _M_imag -= __z.imag(); 3074fee23f9Smrg return *this; 3084fee23f9Smrg } 3094fee23f9Smrg 3104fee23f9Smrg // 26.2.5/13 3114fee23f9Smrg // XXX: This is a grammar school implementation. 3124fee23f9Smrg template<typename _Tp> 3134fee23f9Smrg template<typename _Up> 314654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 3154fee23f9Smrg complex<_Tp>::operator*=(const complex<_Up>& __z) 3164fee23f9Smrg { 3174fee23f9Smrg const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 3184fee23f9Smrg _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 3194fee23f9Smrg _M_real = __r; 3204fee23f9Smrg return *this; 3214fee23f9Smrg } 3224fee23f9Smrg 3234fee23f9Smrg // 26.2.5/15 3244fee23f9Smrg // XXX: This is a grammar school implementation. 3254fee23f9Smrg template<typename _Tp> 3264fee23f9Smrg template<typename _Up> 327654d12c0Smrg _GLIBCXX20_CONSTEXPR complex<_Tp>& 3284fee23f9Smrg complex<_Tp>::operator/=(const complex<_Up>& __z) 3294fee23f9Smrg { 3304fee23f9Smrg const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 3314fee23f9Smrg const _Tp __n = std::norm(__z); 3324fee23f9Smrg _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 3334fee23f9Smrg _M_real = __r / __n; 3344fee23f9Smrg return *this; 3354fee23f9Smrg } 3364fee23f9Smrg 3374fee23f9Smrg // Operators: 3389f30ce74Smrg ///@{ 3394fee23f9Smrg /// Return new complex value @a x plus @a y. 3404fee23f9Smrg template<typename _Tp> 341654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3424fee23f9Smrg operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 3434fee23f9Smrg { 3444fee23f9Smrg complex<_Tp> __r = __x; 3454fee23f9Smrg __r += __y; 3464fee23f9Smrg return __r; 3474fee23f9Smrg } 3484fee23f9Smrg 3494fee23f9Smrg template<typename _Tp> 350654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3514fee23f9Smrg operator+(const complex<_Tp>& __x, const _Tp& __y) 3524fee23f9Smrg { 3534fee23f9Smrg complex<_Tp> __r = __x; 3544fee23f9Smrg __r += __y; 3554fee23f9Smrg return __r; 3564fee23f9Smrg } 3574fee23f9Smrg 3584fee23f9Smrg template<typename _Tp> 359654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3604fee23f9Smrg operator+(const _Tp& __x, const complex<_Tp>& __y) 3614fee23f9Smrg { 3624fee23f9Smrg complex<_Tp> __r = __y; 3634fee23f9Smrg __r += __x; 3644fee23f9Smrg return __r; 3654fee23f9Smrg } 3669f30ce74Smrg ///@} 3674fee23f9Smrg 3689f30ce74Smrg ///@{ 3694fee23f9Smrg /// Return new complex value @a x minus @a y. 3704fee23f9Smrg template<typename _Tp> 371654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3724fee23f9Smrg operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 3734fee23f9Smrg { 3744fee23f9Smrg complex<_Tp> __r = __x; 3754fee23f9Smrg __r -= __y; 3764fee23f9Smrg return __r; 3774fee23f9Smrg } 3784fee23f9Smrg 3794fee23f9Smrg template<typename _Tp> 380654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3814fee23f9Smrg operator-(const complex<_Tp>& __x, const _Tp& __y) 3824fee23f9Smrg { 3834fee23f9Smrg complex<_Tp> __r = __x; 3844fee23f9Smrg __r -= __y; 3854fee23f9Smrg return __r; 3864fee23f9Smrg } 3874fee23f9Smrg 3884fee23f9Smrg template<typename _Tp> 389654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 3904fee23f9Smrg operator-(const _Tp& __x, const complex<_Tp>& __y) 3914fee23f9Smrg { 392654d12c0Smrg complex<_Tp> __r = -__y; 393654d12c0Smrg __r += __x; 3944fee23f9Smrg return __r; 3954fee23f9Smrg } 3969f30ce74Smrg ///@} 3974fee23f9Smrg 3989f30ce74Smrg ///@{ 3994fee23f9Smrg /// Return new complex value @a x times @a y. 4004fee23f9Smrg template<typename _Tp> 401654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4024fee23f9Smrg operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 4034fee23f9Smrg { 4044fee23f9Smrg complex<_Tp> __r = __x; 4054fee23f9Smrg __r *= __y; 4064fee23f9Smrg return __r; 4074fee23f9Smrg } 4084fee23f9Smrg 4094fee23f9Smrg template<typename _Tp> 410654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4114fee23f9Smrg operator*(const complex<_Tp>& __x, const _Tp& __y) 4124fee23f9Smrg { 4134fee23f9Smrg complex<_Tp> __r = __x; 4144fee23f9Smrg __r *= __y; 4154fee23f9Smrg return __r; 4164fee23f9Smrg } 4174fee23f9Smrg 4184fee23f9Smrg template<typename _Tp> 419654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4204fee23f9Smrg operator*(const _Tp& __x, const complex<_Tp>& __y) 4214fee23f9Smrg { 4224fee23f9Smrg complex<_Tp> __r = __y; 4234fee23f9Smrg __r *= __x; 4244fee23f9Smrg return __r; 4254fee23f9Smrg } 4269f30ce74Smrg ///@} 4274fee23f9Smrg 4289f30ce74Smrg ///@{ 4294fee23f9Smrg /// Return new complex value @a x divided by @a y. 4304fee23f9Smrg template<typename _Tp> 431654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4324fee23f9Smrg operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 4334fee23f9Smrg { 4344fee23f9Smrg complex<_Tp> __r = __x; 4354fee23f9Smrg __r /= __y; 4364fee23f9Smrg return __r; 4374fee23f9Smrg } 4384fee23f9Smrg 4394fee23f9Smrg template<typename _Tp> 440654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4414fee23f9Smrg operator/(const complex<_Tp>& __x, const _Tp& __y) 4424fee23f9Smrg { 4434fee23f9Smrg complex<_Tp> __r = __x; 4444fee23f9Smrg __r /= __y; 4454fee23f9Smrg return __r; 4464fee23f9Smrg } 4474fee23f9Smrg 4484fee23f9Smrg template<typename _Tp> 449654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4504fee23f9Smrg operator/(const _Tp& __x, const complex<_Tp>& __y) 4514fee23f9Smrg { 4524fee23f9Smrg complex<_Tp> __r = __x; 4534fee23f9Smrg __r /= __y; 4544fee23f9Smrg return __r; 4554fee23f9Smrg } 4569f30ce74Smrg ///@} 4574fee23f9Smrg 4584fee23f9Smrg /// Return @a x. 4594fee23f9Smrg template<typename _Tp> 460654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4614fee23f9Smrg operator+(const complex<_Tp>& __x) 4624fee23f9Smrg { return __x; } 4634fee23f9Smrg 4644fee23f9Smrg /// Return complex negation of @a x. 4654fee23f9Smrg template<typename _Tp> 466654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 4674fee23f9Smrg operator-(const complex<_Tp>& __x) 4684fee23f9Smrg { return complex<_Tp>(-__x.real(), -__x.imag()); } 4694fee23f9Smrg 4709f30ce74Smrg ///@{ 4714fee23f9Smrg /// Return true if @a x is equal to @a y. 4724fee23f9Smrg template<typename _Tp> 47348fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 4744fee23f9Smrg operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 4754fee23f9Smrg { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 4764fee23f9Smrg 4774fee23f9Smrg template<typename _Tp> 47848fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 4794fee23f9Smrg operator==(const complex<_Tp>& __x, const _Tp& __y) 4804fee23f9Smrg { return __x.real() == __y && __x.imag() == _Tp(); } 4814fee23f9Smrg 48243265c03Smrg#if !(__cpp_impl_three_way_comparison >= 201907L) 4834fee23f9Smrg template<typename _Tp> 48448fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 4854fee23f9Smrg operator==(const _Tp& __x, const complex<_Tp>& __y) 4864fee23f9Smrg { return __x == __y.real() && _Tp() == __y.imag(); } 4879f30ce74Smrg ///@} 4884fee23f9Smrg 4899f30ce74Smrg ///@{ 4904fee23f9Smrg /// Return false if @a x is equal to @a y. 4914fee23f9Smrg template<typename _Tp> 49248fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 4934fee23f9Smrg operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 4944fee23f9Smrg { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 4954fee23f9Smrg 4964fee23f9Smrg template<typename _Tp> 49748fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 4984fee23f9Smrg operator!=(const complex<_Tp>& __x, const _Tp& __y) 4994fee23f9Smrg { return __x.real() != __y || __x.imag() != _Tp(); } 5004fee23f9Smrg 5014fee23f9Smrg template<typename _Tp> 50248fb7bfaSmrg inline _GLIBCXX_CONSTEXPR bool 5034fee23f9Smrg operator!=(const _Tp& __x, const complex<_Tp>& __y) 5044fee23f9Smrg { return __x != __y.real() || _Tp() != __y.imag(); } 50543265c03Smrg#endif 5069f30ce74Smrg ///@} 5074fee23f9Smrg 5084fee23f9Smrg /// Extraction operator for complex values. 5094fee23f9Smrg template<typename _Tp, typename _CharT, class _Traits> 5104fee23f9Smrg basic_istream<_CharT, _Traits>& 5114fee23f9Smrg operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 5124fee23f9Smrg { 5133f8cba22Smrg bool __fail = true; 5143f8cba22Smrg _CharT __ch; 5153f8cba22Smrg if (__is >> __ch) 5164fee23f9Smrg { 5173f8cba22Smrg if (_Traits::eq(__ch, __is.widen('('))) 5184fee23f9Smrg { 5193f8cba22Smrg _Tp __u; 5203f8cba22Smrg if (__is >> __u >> __ch) 5213f8cba22Smrg { 5223f8cba22Smrg const _CharT __rparen = __is.widen(')'); 5233f8cba22Smrg if (_Traits::eq(__ch, __rparen)) 5243f8cba22Smrg { 5253f8cba22Smrg __x = __u; 5263f8cba22Smrg __fail = false; 5274fee23f9Smrg } 5283f8cba22Smrg else if (_Traits::eq(__ch, __is.widen(','))) 5293f8cba22Smrg { 5303f8cba22Smrg _Tp __v; 5313f8cba22Smrg if (__is >> __v >> __ch) 5323f8cba22Smrg { 5333f8cba22Smrg if (_Traits::eq(__ch, __rparen)) 5343f8cba22Smrg { 5353f8cba22Smrg __x = complex<_Tp>(__u, __v); 5363f8cba22Smrg __fail = false; 5374fee23f9Smrg } 5383f8cba22Smrg else 5393f8cba22Smrg __is.putback(__ch); 5403f8cba22Smrg } 5413f8cba22Smrg } 5423f8cba22Smrg else 5433f8cba22Smrg __is.putback(__ch); 5443f8cba22Smrg } 5453f8cba22Smrg } 5463f8cba22Smrg else 5474fee23f9Smrg { 5484fee23f9Smrg __is.putback(__ch); 5493f8cba22Smrg _Tp __u; 5503f8cba22Smrg if (__is >> __u) 5513f8cba22Smrg { 5523f8cba22Smrg __x = __u; 5533f8cba22Smrg __fail = false; 5544fee23f9Smrg } 5553f8cba22Smrg } 5563f8cba22Smrg } 5573f8cba22Smrg if (__fail) 5583f8cba22Smrg __is.setstate(ios_base::failbit); 5594fee23f9Smrg return __is; 5604fee23f9Smrg } 5614fee23f9Smrg 5624fee23f9Smrg /// Insertion operator for complex values. 5634fee23f9Smrg template<typename _Tp, typename _CharT, class _Traits> 5644fee23f9Smrg basic_ostream<_CharT, _Traits>& 5654fee23f9Smrg operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 5664fee23f9Smrg { 5674fee23f9Smrg basic_ostringstream<_CharT, _Traits> __s; 5684fee23f9Smrg __s.flags(__os.flags()); 5694fee23f9Smrg __s.imbue(__os.getloc()); 5704fee23f9Smrg __s.precision(__os.precision()); 5714fee23f9Smrg __s << '(' << __x.real() << ',' << __x.imag() << ')'; 5724fee23f9Smrg return __os << __s.str(); 5734fee23f9Smrg } 5744fee23f9Smrg 5754fee23f9Smrg // Values 57648fb7bfaSmrg#if __cplusplus >= 201103L 5774fee23f9Smrg template<typename _Tp> 57848fb7bfaSmrg constexpr _Tp 5794fee23f9Smrg real(const complex<_Tp>& __z) 5804fee23f9Smrg { return __z.real(); } 5814fee23f9Smrg 5824fee23f9Smrg template<typename _Tp> 58348fb7bfaSmrg constexpr _Tp 5844fee23f9Smrg imag(const complex<_Tp>& __z) 5854fee23f9Smrg { return __z.imag(); } 5864fee23f9Smrg#else 5874fee23f9Smrg template<typename _Tp> 5884fee23f9Smrg inline _Tp& 5894fee23f9Smrg real(complex<_Tp>& __z) 5904fee23f9Smrg { return __z.real(); } 5914fee23f9Smrg 5924fee23f9Smrg template<typename _Tp> 5934fee23f9Smrg inline const _Tp& 5944fee23f9Smrg real(const complex<_Tp>& __z) 5954fee23f9Smrg { return __z.real(); } 5964fee23f9Smrg 5974fee23f9Smrg template<typename _Tp> 5984fee23f9Smrg inline _Tp& 5994fee23f9Smrg imag(complex<_Tp>& __z) 6004fee23f9Smrg { return __z.imag(); } 6014fee23f9Smrg 6024fee23f9Smrg template<typename _Tp> 6034fee23f9Smrg inline const _Tp& 6044fee23f9Smrg imag(const complex<_Tp>& __z) 6054fee23f9Smrg { return __z.imag(); } 6064fee23f9Smrg#endif 6074fee23f9Smrg 6084fee23f9Smrg // 26.2.7/3 abs(__z): Returns the magnitude of __z. 6094fee23f9Smrg template<typename _Tp> 6104fee23f9Smrg inline _Tp 6114fee23f9Smrg __complex_abs(const complex<_Tp>& __z) 6124fee23f9Smrg { 6134fee23f9Smrg _Tp __x = __z.real(); 6144fee23f9Smrg _Tp __y = __z.imag(); 6154fee23f9Smrg const _Tp __s = std::max(abs(__x), abs(__y)); 6164fee23f9Smrg if (__s == _Tp()) // well ... 6174fee23f9Smrg return __s; 6184fee23f9Smrg __x /= __s; 6194fee23f9Smrg __y /= __s; 6204fee23f9Smrg return __s * sqrt(__x * __x + __y * __y); 6214fee23f9Smrg } 6224fee23f9Smrg 6234fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 6243965f5d7Schristos // XXX: We can't use __builtin_cabs* because they are broken 6254fee23f9Smrg inline float 6263965f5d7Schristos __complex_abs(__complex__ float __z) { return __c99_cabsf(__z); } 6274fee23f9Smrg 6284fee23f9Smrg inline double 6293965f5d7Schristos __complex_abs(__complex__ double __z) { return __c99_cabs(__z); } 6304fee23f9Smrg 6314fee23f9Smrg inline long double 6324fee23f9Smrg __complex_abs(const __complex__ long double& __z) 6333965f5d7Schristos { return __c99_cabsl(__z); } 6344fee23f9Smrg 6354fee23f9Smrg template<typename _Tp> 6364fee23f9Smrg inline _Tp 6374fee23f9Smrg abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } 6384fee23f9Smrg#else 6394fee23f9Smrg template<typename _Tp> 6404fee23f9Smrg inline _Tp 6414fee23f9Smrg abs(const complex<_Tp>& __z) { return __complex_abs(__z); } 6424fee23f9Smrg#endif 6434fee23f9Smrg 6444fee23f9Smrg 6454fee23f9Smrg // 26.2.7/4: arg(__z): Returns the phase angle of __z. 6464fee23f9Smrg template<typename _Tp> 6474fee23f9Smrg inline _Tp 6484fee23f9Smrg __complex_arg(const complex<_Tp>& __z) 6494fee23f9Smrg { return atan2(__z.imag(), __z.real()); } 6504fee23f9Smrg 6514fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 6524fee23f9Smrg inline float 6534fee23f9Smrg __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } 6544fee23f9Smrg 6554fee23f9Smrg inline double 6564fee23f9Smrg __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } 6574fee23f9Smrg 6584fee23f9Smrg inline long double 6594fee23f9Smrg __complex_arg(const __complex__ long double& __z) 6604fee23f9Smrg { return __builtin_cargl(__z); } 6614fee23f9Smrg 6624fee23f9Smrg template<typename _Tp> 6634fee23f9Smrg inline _Tp 6644fee23f9Smrg arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } 6654fee23f9Smrg#else 6664fee23f9Smrg template<typename _Tp> 6674fee23f9Smrg inline _Tp 6684fee23f9Smrg arg(const complex<_Tp>& __z) { return __complex_arg(__z); } 6694fee23f9Smrg#endif 6704fee23f9Smrg 6714fee23f9Smrg // 26.2.7/5: norm(__z) returns the squared magnitude of __z. 6724fee23f9Smrg // As defined, norm() is -not- a norm is the common mathematical 673d35849d0Smrg // sense used in numerics. The helper class _Norm_helper<> tries to 6744fee23f9Smrg // distinguish between builtin floating point and the rest, so as 6754fee23f9Smrg // to deliver an answer as close as possible to the real value. 6764fee23f9Smrg template<bool> 6774fee23f9Smrg struct _Norm_helper 6784fee23f9Smrg { 6794fee23f9Smrg template<typename _Tp> 680654d12c0Smrg static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) 6814fee23f9Smrg { 6824fee23f9Smrg const _Tp __x = __z.real(); 6834fee23f9Smrg const _Tp __y = __z.imag(); 6844fee23f9Smrg return __x * __x + __y * __y; 6854fee23f9Smrg } 6864fee23f9Smrg }; 6874fee23f9Smrg 6884fee23f9Smrg template<> 6894fee23f9Smrg struct _Norm_helper<true> 6904fee23f9Smrg { 6914fee23f9Smrg template<typename _Tp> 692654d12c0Smrg static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) 6934fee23f9Smrg { 694654d12c0Smrg //_Tp __res = std::abs(__z); 695654d12c0Smrg //return __res * __res; 696654d12c0Smrg const _Tp __x = __z.real(); 697654d12c0Smrg const _Tp __y = __z.imag(); 698654d12c0Smrg return __x * __x + __y * __y; 6994fee23f9Smrg } 7004fee23f9Smrg }; 7014fee23f9Smrg 7024fee23f9Smrg template<typename _Tp> 703654d12c0Smrg inline _GLIBCXX20_CONSTEXPR _Tp 7044fee23f9Smrg norm(const complex<_Tp>& __z) 7054fee23f9Smrg { 7064fee23f9Smrg return _Norm_helper<__is_floating<_Tp>::__value 7074fee23f9Smrg && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); 7084fee23f9Smrg } 7094fee23f9Smrg 7104fee23f9Smrg template<typename _Tp> 7114fee23f9Smrg inline complex<_Tp> 7124fee23f9Smrg polar(const _Tp& __rho, const _Tp& __theta) 713cdbfa754Smrg { 714cdbfa754Smrg __glibcxx_assert( __rho >= 0 ); 715cdbfa754Smrg return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); 716cdbfa754Smrg } 7174fee23f9Smrg 7184fee23f9Smrg template<typename _Tp> 719654d12c0Smrg inline _GLIBCXX20_CONSTEXPR complex<_Tp> 7204fee23f9Smrg conj(const complex<_Tp>& __z) 7214fee23f9Smrg { return complex<_Tp>(__z.real(), -__z.imag()); } 7224fee23f9Smrg 7234fee23f9Smrg // Transcendentals 7244fee23f9Smrg 7254fee23f9Smrg // 26.2.8/1 cos(__z): Returns the cosine of __z. 7264fee23f9Smrg template<typename _Tp> 7274fee23f9Smrg inline complex<_Tp> 7284fee23f9Smrg __complex_cos(const complex<_Tp>& __z) 7294fee23f9Smrg { 7304fee23f9Smrg const _Tp __x = __z.real(); 7314fee23f9Smrg const _Tp __y = __z.imag(); 7324fee23f9Smrg return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 7334fee23f9Smrg } 7344fee23f9Smrg 7354fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 7364fee23f9Smrg inline __complex__ float 7374fee23f9Smrg __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } 7384fee23f9Smrg 7394fee23f9Smrg inline __complex__ double 7404fee23f9Smrg __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } 7414fee23f9Smrg 7424fee23f9Smrg inline __complex__ long double 7434fee23f9Smrg __complex_cos(const __complex__ long double& __z) 7444fee23f9Smrg { return __builtin_ccosl(__z); } 7454fee23f9Smrg 7464fee23f9Smrg template<typename _Tp> 7474fee23f9Smrg inline complex<_Tp> 7484fee23f9Smrg cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } 7494fee23f9Smrg#else 7504fee23f9Smrg template<typename _Tp> 7514fee23f9Smrg inline complex<_Tp> 7524fee23f9Smrg cos(const complex<_Tp>& __z) { return __complex_cos(__z); } 7534fee23f9Smrg#endif 7544fee23f9Smrg 7554fee23f9Smrg // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. 7564fee23f9Smrg template<typename _Tp> 7574fee23f9Smrg inline complex<_Tp> 7584fee23f9Smrg __complex_cosh(const complex<_Tp>& __z) 7594fee23f9Smrg { 7604fee23f9Smrg const _Tp __x = __z.real(); 7614fee23f9Smrg const _Tp __y = __z.imag(); 7624fee23f9Smrg return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 7634fee23f9Smrg } 7644fee23f9Smrg 7654fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 7664fee23f9Smrg inline __complex__ float 7674fee23f9Smrg __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } 7684fee23f9Smrg 7694fee23f9Smrg inline __complex__ double 7704fee23f9Smrg __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } 7714fee23f9Smrg 7724fee23f9Smrg inline __complex__ long double 7734fee23f9Smrg __complex_cosh(const __complex__ long double& __z) 7744fee23f9Smrg { return __builtin_ccoshl(__z); } 7754fee23f9Smrg 7764fee23f9Smrg template<typename _Tp> 7774fee23f9Smrg inline complex<_Tp> 7784fee23f9Smrg cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } 7794fee23f9Smrg#else 7804fee23f9Smrg template<typename _Tp> 7814fee23f9Smrg inline complex<_Tp> 7824fee23f9Smrg cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } 7834fee23f9Smrg#endif 7844fee23f9Smrg 7854fee23f9Smrg // 26.2.8/3 exp(__z): Returns the complex base e exponential of x 7864fee23f9Smrg template<typename _Tp> 7874fee23f9Smrg inline complex<_Tp> 7884fee23f9Smrg __complex_exp(const complex<_Tp>& __z) 789d35849d0Smrg { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } 7904fee23f9Smrg 7914fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 7924fee23f9Smrg inline __complex__ float 7934fee23f9Smrg __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } 7944fee23f9Smrg 7954fee23f9Smrg inline __complex__ double 7964fee23f9Smrg __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } 7974fee23f9Smrg 7984fee23f9Smrg inline __complex__ long double 7994fee23f9Smrg __complex_exp(const __complex__ long double& __z) 8004fee23f9Smrg { return __builtin_cexpl(__z); } 8014fee23f9Smrg 8024fee23f9Smrg template<typename _Tp> 8034fee23f9Smrg inline complex<_Tp> 8044fee23f9Smrg exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } 8054fee23f9Smrg#else 8064fee23f9Smrg template<typename _Tp> 8074fee23f9Smrg inline complex<_Tp> 8084fee23f9Smrg exp(const complex<_Tp>& __z) { return __complex_exp(__z); } 8094fee23f9Smrg#endif 8104fee23f9Smrg 8114fee23f9Smrg // 26.2.8/5 log(__z): Returns the natural complex logarithm of __z. 8124fee23f9Smrg // The branch cut is along the negative axis. 8134fee23f9Smrg template<typename _Tp> 8144fee23f9Smrg inline complex<_Tp> 8154fee23f9Smrg __complex_log(const complex<_Tp>& __z) 8164fee23f9Smrg { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } 8174fee23f9Smrg 8184fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 8194fee23f9Smrg inline __complex__ float 8204fee23f9Smrg __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } 8214fee23f9Smrg 8224fee23f9Smrg inline __complex__ double 8234fee23f9Smrg __complex_log(__complex__ double __z) { return __builtin_clog(__z); } 8244fee23f9Smrg 8254fee23f9Smrg inline __complex__ long double 8264fee23f9Smrg __complex_log(const __complex__ long double& __z) 8274fee23f9Smrg { return __builtin_clogl(__z); } 8284fee23f9Smrg 8294fee23f9Smrg template<typename _Tp> 8304fee23f9Smrg inline complex<_Tp> 8314fee23f9Smrg log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } 8324fee23f9Smrg#else 8334fee23f9Smrg template<typename _Tp> 8344fee23f9Smrg inline complex<_Tp> 8354fee23f9Smrg log(const complex<_Tp>& __z) { return __complex_log(__z); } 8364fee23f9Smrg#endif 8374fee23f9Smrg 8384fee23f9Smrg template<typename _Tp> 8394fee23f9Smrg inline complex<_Tp> 8404fee23f9Smrg log10(const complex<_Tp>& __z) 8414fee23f9Smrg { return std::log(__z) / log(_Tp(10.0)); } 8424fee23f9Smrg 8434fee23f9Smrg // 26.2.8/10 sin(__z): Returns the sine of __z. 8444fee23f9Smrg template<typename _Tp> 8454fee23f9Smrg inline complex<_Tp> 8464fee23f9Smrg __complex_sin(const complex<_Tp>& __z) 8474fee23f9Smrg { 8484fee23f9Smrg const _Tp __x = __z.real(); 8494fee23f9Smrg const _Tp __y = __z.imag(); 8504fee23f9Smrg return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 8514fee23f9Smrg } 8524fee23f9Smrg 8534fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 8544fee23f9Smrg inline __complex__ float 8554fee23f9Smrg __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } 8564fee23f9Smrg 8574fee23f9Smrg inline __complex__ double 8584fee23f9Smrg __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } 8594fee23f9Smrg 8604fee23f9Smrg inline __complex__ long double 8614fee23f9Smrg __complex_sin(const __complex__ long double& __z) 8624fee23f9Smrg { return __builtin_csinl(__z); } 8634fee23f9Smrg 8644fee23f9Smrg template<typename _Tp> 8654fee23f9Smrg inline complex<_Tp> 8664fee23f9Smrg sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } 8674fee23f9Smrg#else 8684fee23f9Smrg template<typename _Tp> 8694fee23f9Smrg inline complex<_Tp> 8704fee23f9Smrg sin(const complex<_Tp>& __z) { return __complex_sin(__z); } 8714fee23f9Smrg#endif 8724fee23f9Smrg 8734fee23f9Smrg // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. 8744fee23f9Smrg template<typename _Tp> 8754fee23f9Smrg inline complex<_Tp> 8764fee23f9Smrg __complex_sinh(const complex<_Tp>& __z) 8774fee23f9Smrg { 8784fee23f9Smrg const _Tp __x = __z.real(); 8794fee23f9Smrg const _Tp __y = __z.imag(); 8804fee23f9Smrg return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 8814fee23f9Smrg } 8824fee23f9Smrg 8834fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 8844fee23f9Smrg inline __complex__ float 8854fee23f9Smrg __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } 8864fee23f9Smrg 8874fee23f9Smrg inline __complex__ double 8884fee23f9Smrg __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } 8894fee23f9Smrg 8904fee23f9Smrg inline __complex__ long double 8914fee23f9Smrg __complex_sinh(const __complex__ long double& __z) 8924fee23f9Smrg { return __builtin_csinhl(__z); } 8934fee23f9Smrg 8944fee23f9Smrg template<typename _Tp> 8954fee23f9Smrg inline complex<_Tp> 8964fee23f9Smrg sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } 8974fee23f9Smrg#else 8984fee23f9Smrg template<typename _Tp> 8994fee23f9Smrg inline complex<_Tp> 9004fee23f9Smrg sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } 9014fee23f9Smrg#endif 9024fee23f9Smrg 9034fee23f9Smrg // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. 9044fee23f9Smrg // The branch cut is on the negative axis. 9054fee23f9Smrg template<typename _Tp> 9064fee23f9Smrg complex<_Tp> 9074fee23f9Smrg __complex_sqrt(const complex<_Tp>& __z) 9084fee23f9Smrg { 9094fee23f9Smrg _Tp __x = __z.real(); 9104fee23f9Smrg _Tp __y = __z.imag(); 9114fee23f9Smrg 9124fee23f9Smrg if (__x == _Tp()) 9134fee23f9Smrg { 9144fee23f9Smrg _Tp __t = sqrt(abs(__y) / 2); 9154fee23f9Smrg return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 9164fee23f9Smrg } 9174fee23f9Smrg else 9184fee23f9Smrg { 9194fee23f9Smrg _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); 9204fee23f9Smrg _Tp __u = __t / 2; 9214fee23f9Smrg return __x > _Tp() 9224fee23f9Smrg ? complex<_Tp>(__u, __y / __t) 9234fee23f9Smrg : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 9244fee23f9Smrg } 9254fee23f9Smrg } 9264fee23f9Smrg 9274fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 9284fee23f9Smrg inline __complex__ float 9294fee23f9Smrg __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } 9304fee23f9Smrg 9314fee23f9Smrg inline __complex__ double 9324fee23f9Smrg __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } 9334fee23f9Smrg 9344fee23f9Smrg inline __complex__ long double 9354fee23f9Smrg __complex_sqrt(const __complex__ long double& __z) 9364fee23f9Smrg { return __builtin_csqrtl(__z); } 9374fee23f9Smrg 9384fee23f9Smrg template<typename _Tp> 9394fee23f9Smrg inline complex<_Tp> 9404fee23f9Smrg sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } 9414fee23f9Smrg#else 9424fee23f9Smrg template<typename _Tp> 9434fee23f9Smrg inline complex<_Tp> 9444fee23f9Smrg sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } 9454fee23f9Smrg#endif 9464fee23f9Smrg 9474fee23f9Smrg // 26.2.8/14 tan(__z): Return the complex tangent of __z. 9484fee23f9Smrg 9494fee23f9Smrg template<typename _Tp> 9504fee23f9Smrg inline complex<_Tp> 9514fee23f9Smrg __complex_tan(const complex<_Tp>& __z) 9524fee23f9Smrg { return std::sin(__z) / std::cos(__z); } 9534fee23f9Smrg 9544fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 9554fee23f9Smrg inline __complex__ float 9564fee23f9Smrg __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } 9574fee23f9Smrg 9584fee23f9Smrg inline __complex__ double 9594fee23f9Smrg __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } 9604fee23f9Smrg 9614fee23f9Smrg inline __complex__ long double 9624fee23f9Smrg __complex_tan(const __complex__ long double& __z) 9634fee23f9Smrg { return __builtin_ctanl(__z); } 9644fee23f9Smrg 9654fee23f9Smrg template<typename _Tp> 9664fee23f9Smrg inline complex<_Tp> 9674fee23f9Smrg tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } 9684fee23f9Smrg#else 9694fee23f9Smrg template<typename _Tp> 9704fee23f9Smrg inline complex<_Tp> 9714fee23f9Smrg tan(const complex<_Tp>& __z) { return __complex_tan(__z); } 9724fee23f9Smrg#endif 9734fee23f9Smrg 9744fee23f9Smrg 9754fee23f9Smrg // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. 9764fee23f9Smrg 9774fee23f9Smrg template<typename _Tp> 9784fee23f9Smrg inline complex<_Tp> 9794fee23f9Smrg __complex_tanh(const complex<_Tp>& __z) 9804fee23f9Smrg { return std::sinh(__z) / std::cosh(__z); } 9814fee23f9Smrg 9824fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 9834fee23f9Smrg inline __complex__ float 9844fee23f9Smrg __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } 9854fee23f9Smrg 9864fee23f9Smrg inline __complex__ double 9874fee23f9Smrg __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } 9884fee23f9Smrg 9894fee23f9Smrg inline __complex__ long double 9904fee23f9Smrg __complex_tanh(const __complex__ long double& __z) 9914fee23f9Smrg { return __builtin_ctanhl(__z); } 9924fee23f9Smrg 9934fee23f9Smrg template<typename _Tp> 9944fee23f9Smrg inline complex<_Tp> 9954fee23f9Smrg tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } 9964fee23f9Smrg#else 9974fee23f9Smrg template<typename _Tp> 9984fee23f9Smrg inline complex<_Tp> 9994fee23f9Smrg tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } 10004fee23f9Smrg#endif 10014fee23f9Smrg 10024fee23f9Smrg 10034fee23f9Smrg // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x 10044fee23f9Smrg // raised to the __y-th power. The branch 10054fee23f9Smrg // cut is on the negative axis. 100648fb7bfaSmrg template<typename _Tp> 100748fb7bfaSmrg complex<_Tp> 100848fb7bfaSmrg __complex_pow_unsigned(complex<_Tp> __x, unsigned __n) 100948fb7bfaSmrg { 101048fb7bfaSmrg complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1); 101148fb7bfaSmrg 101248fb7bfaSmrg while (__n >>= 1) 101348fb7bfaSmrg { 101448fb7bfaSmrg __x *= __x; 101548fb7bfaSmrg if (__n % 2) 101648fb7bfaSmrg __y *= __x; 101748fb7bfaSmrg } 101848fb7bfaSmrg 101948fb7bfaSmrg return __y; 102048fb7bfaSmrg } 102148fb7bfaSmrg 1022d35849d0Smrg // In C++11 mode we used to implement the resolution of 10234fee23f9Smrg // DR 844. complex pow return type is ambiguous. 1024d35849d0Smrg // thus the following overload was disabled in that mode. However, doing 1025d35849d0Smrg // that causes all sorts of issues, see, for example: 1026d35849d0Smrg // http://gcc.gnu.org/ml/libstdc++/2013-01/msg00058.html 1027d35849d0Smrg // and also PR57974. 10284fee23f9Smrg template<typename _Tp> 10294fee23f9Smrg inline complex<_Tp> 10304fee23f9Smrg pow(const complex<_Tp>& __z, int __n) 103148fb7bfaSmrg { 103248fb7bfaSmrg return __n < 0 103348fb7bfaSmrg ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n) 103448fb7bfaSmrg : std::__complex_pow_unsigned(__z, __n); 103548fb7bfaSmrg } 10364fee23f9Smrg 10374fee23f9Smrg template<typename _Tp> 10384fee23f9Smrg complex<_Tp> 10394fee23f9Smrg pow(const complex<_Tp>& __x, const _Tp& __y) 10404fee23f9Smrg { 1041cdbfa754Smrg#if ! _GLIBCXX_USE_C99_COMPLEX 10424fee23f9Smrg if (__x == _Tp()) 10434fee23f9Smrg return _Tp(); 10444fee23f9Smrg#endif 10454fee23f9Smrg if (__x.imag() == _Tp() && __x.real() > _Tp()) 10464fee23f9Smrg return pow(__x.real(), __y); 10474fee23f9Smrg 10484fee23f9Smrg complex<_Tp> __t = std::log(__x); 1049d35849d0Smrg return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag()); 10504fee23f9Smrg } 10514fee23f9Smrg 10524fee23f9Smrg template<typename _Tp> 10534fee23f9Smrg inline complex<_Tp> 10544fee23f9Smrg __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 10554fee23f9Smrg { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } 10564fee23f9Smrg 10574fee23f9Smrg#if _GLIBCXX_USE_C99_COMPLEX 10584fee23f9Smrg inline __complex__ float 10594fee23f9Smrg __complex_pow(__complex__ float __x, __complex__ float __y) 10604fee23f9Smrg { return __builtin_cpowf(__x, __y); } 10614fee23f9Smrg 10624fee23f9Smrg inline __complex__ double 10634fee23f9Smrg __complex_pow(__complex__ double __x, __complex__ double __y) 10644fee23f9Smrg { return __builtin_cpow(__x, __y); } 10654fee23f9Smrg 10664fee23f9Smrg inline __complex__ long double 10674fee23f9Smrg __complex_pow(const __complex__ long double& __x, 10684fee23f9Smrg const __complex__ long double& __y) 10694fee23f9Smrg { return __builtin_cpowl(__x, __y); } 10704fee23f9Smrg 10714fee23f9Smrg template<typename _Tp> 10724fee23f9Smrg inline complex<_Tp> 10734fee23f9Smrg pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 10744fee23f9Smrg { return __complex_pow(__x.__rep(), __y.__rep()); } 10754fee23f9Smrg#else 10764fee23f9Smrg template<typename _Tp> 10774fee23f9Smrg inline complex<_Tp> 10784fee23f9Smrg pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 10794fee23f9Smrg { return __complex_pow(__x, __y); } 10804fee23f9Smrg#endif 10814fee23f9Smrg 10824fee23f9Smrg template<typename _Tp> 10834fee23f9Smrg inline complex<_Tp> 10844fee23f9Smrg pow(const _Tp& __x, const complex<_Tp>& __y) 10854fee23f9Smrg { 1086d35849d0Smrg return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()), 10874fee23f9Smrg __y.imag() * log(__x)) 10884fee23f9Smrg : std::pow(complex<_Tp>(__x), __y); 10894fee23f9Smrg } 10904fee23f9Smrg 109148fb7bfaSmrg /// 26.2.3 complex specializations 109248fb7bfaSmrg /// complex<float> specialization 10934fee23f9Smrg template<> 1094e9e6e0f6Smrg class complex<float> 10954fee23f9Smrg { 1096e9e6e0f6Smrg public: 10974fee23f9Smrg typedef float value_type; 10984fee23f9Smrg typedef __complex__ float _ComplexT; 10994fee23f9Smrg 110048fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 11014fee23f9Smrg 110248fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f) 110348fb7bfaSmrg#if __cplusplus >= 201103L 110448fb7bfaSmrg : _M_value{ __r, __i } { } 110548fb7bfaSmrg#else 11064fee23f9Smrg { 11074fee23f9Smrg __real__ _M_value = __r; 11084fee23f9Smrg __imag__ _M_value = __i; 11094fee23f9Smrg } 111048fb7bfaSmrg#endif 11114fee23f9Smrg 1112*4fe0f936Smrg#if __cplusplus >= 201103L 1113*4fe0f936Smrg _GLIBCXX14_CONSTEXPR complex(const complex&) = default; 1114*4fe0f936Smrg#endif 1115*4fe0f936Smrg 111648fb7bfaSmrg explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&); 111748fb7bfaSmrg explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); 11184fee23f9Smrg 111948fb7bfaSmrg#if __cplusplus >= 201103L 11204fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 11214fee23f9Smrg // DR 387. std::complex over-encapsulated. 112248fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 112348fb7bfaSmrg constexpr float 1124d35849d0Smrg real() const { return __real__ _M_value; } 11254fee23f9Smrg 112648fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 112748fb7bfaSmrg constexpr float 1128d35849d0Smrg imag() const { return __imag__ _M_value; } 11294fee23f9Smrg#else 113048fb7bfaSmrg float& 113148fb7bfaSmrg real() { return __real__ _M_value; } 11324fee23f9Smrg 113348fb7bfaSmrg const float& 113448fb7bfaSmrg real() const { return __real__ _M_value; } 11354fee23f9Smrg 113648fb7bfaSmrg float& 113748fb7bfaSmrg imag() { return __imag__ _M_value; } 11384fee23f9Smrg 113948fb7bfaSmrg const float& 114048fb7bfaSmrg imag() const { return __imag__ _M_value; } 11414fee23f9Smrg#endif 11424fee23f9Smrg 11434fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 11444fee23f9Smrg // DR 387. std::complex over-encapsulated. 1145654d12c0Smrg _GLIBCXX20_CONSTEXPR void 114648fb7bfaSmrg real(float __val) { __real__ _M_value = __val; } 11474fee23f9Smrg 1148654d12c0Smrg _GLIBCXX20_CONSTEXPR void 114948fb7bfaSmrg imag(float __val) { __imag__ _M_value = __val; } 11504fee23f9Smrg 1151654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11524fee23f9Smrg operator=(float __f) 11534fee23f9Smrg { 115448fb7bfaSmrg _M_value = __f; 11554fee23f9Smrg return *this; 11564fee23f9Smrg } 11574fee23f9Smrg 1158654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11594fee23f9Smrg operator+=(float __f) 11604fee23f9Smrg { 116148fb7bfaSmrg _M_value += __f; 11624fee23f9Smrg return *this; 11634fee23f9Smrg } 11644fee23f9Smrg 1165654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11664fee23f9Smrg operator-=(float __f) 11674fee23f9Smrg { 116848fb7bfaSmrg _M_value -= __f; 11694fee23f9Smrg return *this; 11704fee23f9Smrg } 11714fee23f9Smrg 1172654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11734fee23f9Smrg operator*=(float __f) 11744fee23f9Smrg { 11754fee23f9Smrg _M_value *= __f; 11764fee23f9Smrg return *this; 11774fee23f9Smrg } 11784fee23f9Smrg 1179654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11804fee23f9Smrg operator/=(float __f) 11814fee23f9Smrg { 11824fee23f9Smrg _M_value /= __f; 11834fee23f9Smrg return *this; 11844fee23f9Smrg } 11854fee23f9Smrg 11864fee23f9Smrg // Let the compiler synthesize the copy and assignment 11874fee23f9Smrg // operator. It always does a pretty good job. 1188654d12c0Smrg#if __cplusplus >= 201103L 1189654d12c0Smrg _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; 1190654d12c0Smrg#endif 11914fee23f9Smrg 11924fee23f9Smrg template<typename _Tp> 1193654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 11944fee23f9Smrg operator=(const complex<_Tp>& __z) 11954fee23f9Smrg { 11964fee23f9Smrg __real__ _M_value = __z.real(); 11974fee23f9Smrg __imag__ _M_value = __z.imag(); 11984fee23f9Smrg return *this; 11994fee23f9Smrg } 12004fee23f9Smrg 12014fee23f9Smrg template<typename _Tp> 1202654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 12034fee23f9Smrg operator+=(const complex<_Tp>& __z) 12044fee23f9Smrg { 1205654d12c0Smrg _M_value += __z.__rep(); 12064fee23f9Smrg return *this; 12074fee23f9Smrg } 12084fee23f9Smrg 12094fee23f9Smrg template<class _Tp> 1210654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 12114fee23f9Smrg operator-=(const complex<_Tp>& __z) 12124fee23f9Smrg { 1213654d12c0Smrg _M_value -= __z.__rep(); 12144fee23f9Smrg return *this; 12154fee23f9Smrg } 12164fee23f9Smrg 12174fee23f9Smrg template<class _Tp> 1218654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 12194fee23f9Smrg operator*=(const complex<_Tp>& __z) 12204fee23f9Smrg { 1221654d12c0Smrg const _ComplexT __t = __z.__rep(); 12224fee23f9Smrg _M_value *= __t; 12234fee23f9Smrg return *this; 12244fee23f9Smrg } 12254fee23f9Smrg 12264fee23f9Smrg template<class _Tp> 1227654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 12284fee23f9Smrg operator/=(const complex<_Tp>& __z) 12294fee23f9Smrg { 1230654d12c0Smrg const _ComplexT __t = __z.__rep(); 12314fee23f9Smrg _M_value /= __t; 12324fee23f9Smrg return *this; 12334fee23f9Smrg } 12344fee23f9Smrg 1235d35849d0Smrg _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } 12364fee23f9Smrg 12374fee23f9Smrg private: 12384fee23f9Smrg _ComplexT _M_value; 12394fee23f9Smrg }; 12404fee23f9Smrg 124148fb7bfaSmrg /// 26.2.3 complex specializations 124248fb7bfaSmrg /// complex<double> specialization 12434fee23f9Smrg template<> 1244e9e6e0f6Smrg class complex<double> 12454fee23f9Smrg { 1246e9e6e0f6Smrg public: 12474fee23f9Smrg typedef double value_type; 12484fee23f9Smrg typedef __complex__ double _ComplexT; 12494fee23f9Smrg 125048fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 12514fee23f9Smrg 125248fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0) 125348fb7bfaSmrg#if __cplusplus >= 201103L 125448fb7bfaSmrg : _M_value{ __r, __i } { } 125548fb7bfaSmrg#else 12564fee23f9Smrg { 12574fee23f9Smrg __real__ _M_value = __r; 12584fee23f9Smrg __imag__ _M_value = __i; 12594fee23f9Smrg } 126048fb7bfaSmrg#endif 12614fee23f9Smrg 1262*4fe0f936Smrg#if __cplusplus >= 201103L 1263*4fe0f936Smrg _GLIBCXX14_CONSTEXPR complex(const complex&) = default; 1264*4fe0f936Smrg#endif 1265*4fe0f936Smrg 126648fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) 12674fee23f9Smrg : _M_value(__z.__rep()) { } 12684fee23f9Smrg 126948fb7bfaSmrg explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); 12704fee23f9Smrg 127148fb7bfaSmrg#if __cplusplus >= 201103L 12724fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 12734fee23f9Smrg // DR 387. std::complex over-encapsulated. 127448fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 127548fb7bfaSmrg constexpr double 1276d35849d0Smrg real() const { return __real__ _M_value; } 12774fee23f9Smrg 127848fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 127948fb7bfaSmrg constexpr double 1280d35849d0Smrg imag() const { return __imag__ _M_value; } 12814fee23f9Smrg#else 128248fb7bfaSmrg double& 128348fb7bfaSmrg real() { return __real__ _M_value; } 12844fee23f9Smrg 128548fb7bfaSmrg const double& 128648fb7bfaSmrg real() const { return __real__ _M_value; } 12874fee23f9Smrg 128848fb7bfaSmrg double& 128948fb7bfaSmrg imag() { return __imag__ _M_value; } 12904fee23f9Smrg 129148fb7bfaSmrg const double& 129248fb7bfaSmrg imag() const { return __imag__ _M_value; } 12934fee23f9Smrg#endif 12944fee23f9Smrg 12954fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 12964fee23f9Smrg // DR 387. std::complex over-encapsulated. 1297654d12c0Smrg _GLIBCXX20_CONSTEXPR void 129848fb7bfaSmrg real(double __val) { __real__ _M_value = __val; } 12994fee23f9Smrg 1300654d12c0Smrg _GLIBCXX20_CONSTEXPR void 130148fb7bfaSmrg imag(double __val) { __imag__ _M_value = __val; } 13024fee23f9Smrg 1303654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13044fee23f9Smrg operator=(double __d) 13054fee23f9Smrg { 130648fb7bfaSmrg _M_value = __d; 13074fee23f9Smrg return *this; 13084fee23f9Smrg } 13094fee23f9Smrg 1310654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13114fee23f9Smrg operator+=(double __d) 13124fee23f9Smrg { 131348fb7bfaSmrg _M_value += __d; 13144fee23f9Smrg return *this; 13154fee23f9Smrg } 13164fee23f9Smrg 1317654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13184fee23f9Smrg operator-=(double __d) 13194fee23f9Smrg { 132048fb7bfaSmrg _M_value -= __d; 13214fee23f9Smrg return *this; 13224fee23f9Smrg } 13234fee23f9Smrg 1324654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13254fee23f9Smrg operator*=(double __d) 13264fee23f9Smrg { 13274fee23f9Smrg _M_value *= __d; 13284fee23f9Smrg return *this; 13294fee23f9Smrg } 13304fee23f9Smrg 1331654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13324fee23f9Smrg operator/=(double __d) 13334fee23f9Smrg { 13344fee23f9Smrg _M_value /= __d; 13354fee23f9Smrg return *this; 13364fee23f9Smrg } 13374fee23f9Smrg 13384fee23f9Smrg // The compiler will synthesize this, efficiently. 1339654d12c0Smrg#if __cplusplus >= 201103L 1340654d12c0Smrg _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; 1341654d12c0Smrg#endif 13424fee23f9Smrg 13434fee23f9Smrg template<typename _Tp> 1344654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13454fee23f9Smrg operator=(const complex<_Tp>& __z) 13464fee23f9Smrg { 1347654d12c0Smrg _M_value = __z.__rep(); 13484fee23f9Smrg return *this; 13494fee23f9Smrg } 13504fee23f9Smrg 13514fee23f9Smrg template<typename _Tp> 1352654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13534fee23f9Smrg operator+=(const complex<_Tp>& __z) 13544fee23f9Smrg { 1355654d12c0Smrg _M_value += __z.__rep(); 13564fee23f9Smrg return *this; 13574fee23f9Smrg } 13584fee23f9Smrg 13594fee23f9Smrg template<typename _Tp> 1360654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13614fee23f9Smrg operator-=(const complex<_Tp>& __z) 13624fee23f9Smrg { 1363654d12c0Smrg _M_value -= __z.__rep(); 13644fee23f9Smrg return *this; 13654fee23f9Smrg } 13664fee23f9Smrg 13674fee23f9Smrg template<typename _Tp> 1368654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13694fee23f9Smrg operator*=(const complex<_Tp>& __z) 13704fee23f9Smrg { 1371654d12c0Smrg const _ComplexT __t = __z.__rep(); 13724fee23f9Smrg _M_value *= __t; 13734fee23f9Smrg return *this; 13744fee23f9Smrg } 13754fee23f9Smrg 13764fee23f9Smrg template<typename _Tp> 1377654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 13784fee23f9Smrg operator/=(const complex<_Tp>& __z) 13794fee23f9Smrg { 1380654d12c0Smrg const _ComplexT __t = __z.__rep(); 13814fee23f9Smrg _M_value /= __t; 13824fee23f9Smrg return *this; 13834fee23f9Smrg } 13844fee23f9Smrg 1385d35849d0Smrg _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } 13864fee23f9Smrg 13874fee23f9Smrg private: 13884fee23f9Smrg _ComplexT _M_value; 13894fee23f9Smrg }; 13904fee23f9Smrg 139148fb7bfaSmrg /// 26.2.3 complex specializations 139248fb7bfaSmrg /// complex<long double> specialization 13934fee23f9Smrg template<> 1394e9e6e0f6Smrg class complex<long double> 13954fee23f9Smrg { 1396e9e6e0f6Smrg public: 13974fee23f9Smrg typedef long double value_type; 13984fee23f9Smrg typedef __complex__ long double _ComplexT; 13994fee23f9Smrg 140048fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } 14014fee23f9Smrg 140248fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(long double __r = 0.0L, 140348fb7bfaSmrg long double __i = 0.0L) 140448fb7bfaSmrg#if __cplusplus >= 201103L 140548fb7bfaSmrg : _M_value{ __r, __i } { } 140648fb7bfaSmrg#else 14074fee23f9Smrg { 14084fee23f9Smrg __real__ _M_value = __r; 14094fee23f9Smrg __imag__ _M_value = __i; 14104fee23f9Smrg } 141148fb7bfaSmrg#endif 14124fee23f9Smrg 1413*4fe0f936Smrg#if __cplusplus >= 201103L 1414*4fe0f936Smrg _GLIBCXX14_CONSTEXPR complex(const complex&) = default; 1415*4fe0f936Smrg#endif 1416*4fe0f936Smrg 141748fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) 14184fee23f9Smrg : _M_value(__z.__rep()) { } 14194fee23f9Smrg 142048fb7bfaSmrg _GLIBCXX_CONSTEXPR complex(const complex<double>& __z) 14214fee23f9Smrg : _M_value(__z.__rep()) { } 14224fee23f9Smrg 142348fb7bfaSmrg#if __cplusplus >= 201103L 14244fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 14254fee23f9Smrg // DR 387. std::complex over-encapsulated. 142648fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 142748fb7bfaSmrg constexpr long double 1428d35849d0Smrg real() const { return __real__ _M_value; } 14294fee23f9Smrg 143048fb7bfaSmrg __attribute ((__abi_tag__ ("cxx11"))) 143148fb7bfaSmrg constexpr long double 1432d35849d0Smrg imag() const { return __imag__ _M_value; } 14334fee23f9Smrg#else 143448fb7bfaSmrg long double& 143548fb7bfaSmrg real() { return __real__ _M_value; } 14364fee23f9Smrg 143748fb7bfaSmrg const long double& 143848fb7bfaSmrg real() const { return __real__ _M_value; } 14394fee23f9Smrg 144048fb7bfaSmrg long double& 144148fb7bfaSmrg imag() { return __imag__ _M_value; } 14424fee23f9Smrg 144348fb7bfaSmrg const long double& 144448fb7bfaSmrg imag() const { return __imag__ _M_value; } 14454fee23f9Smrg#endif 14464fee23f9Smrg 14474fee23f9Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 14484fee23f9Smrg // DR 387. std::complex over-encapsulated. 1449654d12c0Smrg _GLIBCXX20_CONSTEXPR void 145048fb7bfaSmrg real(long double __val) { __real__ _M_value = __val; } 14514fee23f9Smrg 1452654d12c0Smrg _GLIBCXX20_CONSTEXPR void 145348fb7bfaSmrg imag(long double __val) { __imag__ _M_value = __val; } 14544fee23f9Smrg 1455654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14564fee23f9Smrg operator=(long double __r) 14574fee23f9Smrg { 145848fb7bfaSmrg _M_value = __r; 14594fee23f9Smrg return *this; 14604fee23f9Smrg } 14614fee23f9Smrg 1462654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14634fee23f9Smrg operator+=(long double __r) 14644fee23f9Smrg { 146548fb7bfaSmrg _M_value += __r; 14664fee23f9Smrg return *this; 14674fee23f9Smrg } 14684fee23f9Smrg 1469654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14704fee23f9Smrg operator-=(long double __r) 14714fee23f9Smrg { 147248fb7bfaSmrg _M_value -= __r; 14734fee23f9Smrg return *this; 14744fee23f9Smrg } 14754fee23f9Smrg 1476654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14774fee23f9Smrg operator*=(long double __r) 14784fee23f9Smrg { 14794fee23f9Smrg _M_value *= __r; 14804fee23f9Smrg return *this; 14814fee23f9Smrg } 14824fee23f9Smrg 1483654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14844fee23f9Smrg operator/=(long double __r) 14854fee23f9Smrg { 14864fee23f9Smrg _M_value /= __r; 14874fee23f9Smrg return *this; 14884fee23f9Smrg } 14894fee23f9Smrg 14904fee23f9Smrg // The compiler knows how to do this efficiently 1491654d12c0Smrg#if __cplusplus >= 201103L 1492654d12c0Smrg _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; 1493654d12c0Smrg#endif 14944fee23f9Smrg 14954fee23f9Smrg template<typename _Tp> 1496654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 14974fee23f9Smrg operator=(const complex<_Tp>& __z) 14984fee23f9Smrg { 1499654d12c0Smrg _M_value = __z.__rep(); 15004fee23f9Smrg return *this; 15014fee23f9Smrg } 15024fee23f9Smrg 15034fee23f9Smrg template<typename _Tp> 1504654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 15054fee23f9Smrg operator+=(const complex<_Tp>& __z) 15064fee23f9Smrg { 1507654d12c0Smrg _M_value += __z.__rep(); 15084fee23f9Smrg return *this; 15094fee23f9Smrg } 15104fee23f9Smrg 15114fee23f9Smrg template<typename _Tp> 1512654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 15134fee23f9Smrg operator-=(const complex<_Tp>& __z) 15144fee23f9Smrg { 1515654d12c0Smrg _M_value -= __z.__rep(); 15164fee23f9Smrg return *this; 15174fee23f9Smrg } 15184fee23f9Smrg 15194fee23f9Smrg template<typename _Tp> 1520654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 15214fee23f9Smrg operator*=(const complex<_Tp>& __z) 15224fee23f9Smrg { 1523654d12c0Smrg const _ComplexT __t = __z.__rep(); 15244fee23f9Smrg _M_value *= __t; 15254fee23f9Smrg return *this; 15264fee23f9Smrg } 15274fee23f9Smrg 15284fee23f9Smrg template<typename _Tp> 1529654d12c0Smrg _GLIBCXX20_CONSTEXPR complex& 15304fee23f9Smrg operator/=(const complex<_Tp>& __z) 15314fee23f9Smrg { 1532654d12c0Smrg const _ComplexT __t = __z.__rep(); 15334fee23f9Smrg _M_value /= __t; 15344fee23f9Smrg return *this; 15354fee23f9Smrg } 15364fee23f9Smrg 1537d35849d0Smrg _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } 15384fee23f9Smrg 15394fee23f9Smrg private: 15404fee23f9Smrg _ComplexT _M_value; 15414fee23f9Smrg }; 15424fee23f9Smrg 15434fee23f9Smrg // These bits have to be at the end of this file, so that the 15444fee23f9Smrg // specializations have all been defined. 154548fb7bfaSmrg inline _GLIBCXX_CONSTEXPR 15464fee23f9Smrg complex<float>::complex(const complex<double>& __z) 15474fee23f9Smrg : _M_value(__z.__rep()) { } 15484fee23f9Smrg 154948fb7bfaSmrg inline _GLIBCXX_CONSTEXPR 15504fee23f9Smrg complex<float>::complex(const complex<long double>& __z) 15514fee23f9Smrg : _M_value(__z.__rep()) { } 15524fee23f9Smrg 155348fb7bfaSmrg inline _GLIBCXX_CONSTEXPR 15544fee23f9Smrg complex<double>::complex(const complex<long double>& __z) 15554fee23f9Smrg : _M_value(__z.__rep()) { } 15564fee23f9Smrg 15574fee23f9Smrg // Inhibit implicit instantiations for required instantiations, 15584fee23f9Smrg // which are defined via explicit instantiations elsewhere. 15594fee23f9Smrg // NB: This syntax is a GNU extension. 15604fee23f9Smrg#if _GLIBCXX_EXTERN_TEMPLATE 15614fee23f9Smrg extern template istream& operator>>(istream&, complex<float>&); 15624fee23f9Smrg extern template ostream& operator<<(ostream&, const complex<float>&); 15634fee23f9Smrg extern template istream& operator>>(istream&, complex<double>&); 15644fee23f9Smrg extern template ostream& operator<<(ostream&, const complex<double>&); 15654fee23f9Smrg extern template istream& operator>>(istream&, complex<long double>&); 15664fee23f9Smrg extern template ostream& operator<<(ostream&, const complex<long double>&); 15674fee23f9Smrg 15684fee23f9Smrg#ifdef _GLIBCXX_USE_WCHAR_T 15694fee23f9Smrg extern template wistream& operator>>(wistream&, complex<float>&); 15704fee23f9Smrg extern template wostream& operator<<(wostream&, const complex<float>&); 15714fee23f9Smrg extern template wistream& operator>>(wistream&, complex<double>&); 15724fee23f9Smrg extern template wostream& operator<<(wostream&, const complex<double>&); 15734fee23f9Smrg extern template wistream& operator>>(wistream&, complex<long double>&); 15744fee23f9Smrg extern template wostream& operator<<(wostream&, const complex<long double>&); 15754fee23f9Smrg#endif 15764fee23f9Smrg#endif 15774fee23f9Smrg 15789f30ce74Smrg /// @} group complex_numbers 15794fee23f9Smrg 158048fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION 158148fb7bfaSmrg} // namespace 15824fee23f9Smrg 158348fb7bfaSmrg#if __cplusplus >= 201103L 158448fb7bfaSmrg 158548fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default) 158648fb7bfaSmrg{ 158748fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 158848fb7bfaSmrg 158948fb7bfaSmrg // Forward declarations. 159048fb7bfaSmrg template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); 159148fb7bfaSmrg template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); 159248fb7bfaSmrg template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); 159348fb7bfaSmrg 159448fb7bfaSmrg template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); 159548fb7bfaSmrg template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); 159648fb7bfaSmrg template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); 159748fb7bfaSmrg // DR 595. 159848fb7bfaSmrg template<typename _Tp> _Tp fabs(const std::complex<_Tp>&); 159948fb7bfaSmrg 160048fb7bfaSmrg template<typename _Tp> 160148fb7bfaSmrg inline std::complex<_Tp> 160248fb7bfaSmrg __complex_acos(const std::complex<_Tp>& __z) 160348fb7bfaSmrg { 160448fb7bfaSmrg const std::complex<_Tp> __t = std::asin(__z); 160548fb7bfaSmrg const _Tp __pi_2 = 1.5707963267948966192313216916397514L; 160648fb7bfaSmrg return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); 160748fb7bfaSmrg } 160848fb7bfaSmrg 160948fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 161048fb7bfaSmrg inline __complex__ float 161148fb7bfaSmrg __complex_acos(__complex__ float __z) 161248fb7bfaSmrg { return __builtin_cacosf(__z); } 161348fb7bfaSmrg 161448fb7bfaSmrg inline __complex__ double 161548fb7bfaSmrg __complex_acos(__complex__ double __z) 161648fb7bfaSmrg { return __builtin_cacos(__z); } 161748fb7bfaSmrg 161848fb7bfaSmrg inline __complex__ long double 161948fb7bfaSmrg __complex_acos(const __complex__ long double& __z) 162048fb7bfaSmrg { return __builtin_cacosl(__z); } 162148fb7bfaSmrg 162248fb7bfaSmrg template<typename _Tp> 162348fb7bfaSmrg inline std::complex<_Tp> 162448fb7bfaSmrg acos(const std::complex<_Tp>& __z) 162548fb7bfaSmrg { return __complex_acos(__z.__rep()); } 16264fee23f9Smrg#else 162748fb7bfaSmrg /// acos(__z) [8.1.2]. 162848fb7bfaSmrg // Effects: Behaves the same as C99 function cacos, defined 162948fb7bfaSmrg // in subclause 7.3.5.1. 163048fb7bfaSmrg template<typename _Tp> 163148fb7bfaSmrg inline std::complex<_Tp> 163248fb7bfaSmrg acos(const std::complex<_Tp>& __z) 163348fb7bfaSmrg { return __complex_acos(__z); } 16344fee23f9Smrg#endif 16354fee23f9Smrg 163648fb7bfaSmrg template<typename _Tp> 163748fb7bfaSmrg inline std::complex<_Tp> 163848fb7bfaSmrg __complex_asin(const std::complex<_Tp>& __z) 163948fb7bfaSmrg { 164048fb7bfaSmrg std::complex<_Tp> __t(-__z.imag(), __z.real()); 164148fb7bfaSmrg __t = std::asinh(__t); 164248fb7bfaSmrg return std::complex<_Tp>(__t.imag(), -__t.real()); 164348fb7bfaSmrg } 164448fb7bfaSmrg 164548fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 164648fb7bfaSmrg inline __complex__ float 164748fb7bfaSmrg __complex_asin(__complex__ float __z) 164848fb7bfaSmrg { return __builtin_casinf(__z); } 164948fb7bfaSmrg 165048fb7bfaSmrg inline __complex__ double 165148fb7bfaSmrg __complex_asin(__complex__ double __z) 165248fb7bfaSmrg { return __builtin_casin(__z); } 165348fb7bfaSmrg 165448fb7bfaSmrg inline __complex__ long double 165548fb7bfaSmrg __complex_asin(const __complex__ long double& __z) 165648fb7bfaSmrg { return __builtin_casinl(__z); } 165748fb7bfaSmrg 165848fb7bfaSmrg template<typename _Tp> 165948fb7bfaSmrg inline std::complex<_Tp> 166048fb7bfaSmrg asin(const std::complex<_Tp>& __z) 166148fb7bfaSmrg { return __complex_asin(__z.__rep()); } 166248fb7bfaSmrg#else 166348fb7bfaSmrg /// asin(__z) [8.1.3]. 166448fb7bfaSmrg // Effects: Behaves the same as C99 function casin, defined 166548fb7bfaSmrg // in subclause 7.3.5.2. 166648fb7bfaSmrg template<typename _Tp> 166748fb7bfaSmrg inline std::complex<_Tp> 166848fb7bfaSmrg asin(const std::complex<_Tp>& __z) 166948fb7bfaSmrg { return __complex_asin(__z); } 167048fb7bfaSmrg#endif 167148fb7bfaSmrg 167248fb7bfaSmrg template<typename _Tp> 167348fb7bfaSmrg std::complex<_Tp> 167448fb7bfaSmrg __complex_atan(const std::complex<_Tp>& __z) 167548fb7bfaSmrg { 167648fb7bfaSmrg const _Tp __r2 = __z.real() * __z.real(); 167748fb7bfaSmrg const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); 167848fb7bfaSmrg 167948fb7bfaSmrg _Tp __num = __z.imag() + _Tp(1.0); 168048fb7bfaSmrg _Tp __den = __z.imag() - _Tp(1.0); 168148fb7bfaSmrg 168248fb7bfaSmrg __num = __r2 + __num * __num; 168348fb7bfaSmrg __den = __r2 + __den * __den; 168448fb7bfaSmrg 168548fb7bfaSmrg return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), 168648fb7bfaSmrg _Tp(0.25) * log(__num / __den)); 168748fb7bfaSmrg } 168848fb7bfaSmrg 168948fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 169048fb7bfaSmrg inline __complex__ float 169148fb7bfaSmrg __complex_atan(__complex__ float __z) 169248fb7bfaSmrg { return __builtin_catanf(__z); } 169348fb7bfaSmrg 169448fb7bfaSmrg inline __complex__ double 169548fb7bfaSmrg __complex_atan(__complex__ double __z) 169648fb7bfaSmrg { return __builtin_catan(__z); } 169748fb7bfaSmrg 169848fb7bfaSmrg inline __complex__ long double 169948fb7bfaSmrg __complex_atan(const __complex__ long double& __z) 170048fb7bfaSmrg { return __builtin_catanl(__z); } 170148fb7bfaSmrg 170248fb7bfaSmrg template<typename _Tp> 170348fb7bfaSmrg inline std::complex<_Tp> 170448fb7bfaSmrg atan(const std::complex<_Tp>& __z) 170548fb7bfaSmrg { return __complex_atan(__z.__rep()); } 170648fb7bfaSmrg#else 170748fb7bfaSmrg /// atan(__z) [8.1.4]. 170848fb7bfaSmrg // Effects: Behaves the same as C99 function catan, defined 170948fb7bfaSmrg // in subclause 7.3.5.3. 171048fb7bfaSmrg template<typename _Tp> 171148fb7bfaSmrg inline std::complex<_Tp> 171248fb7bfaSmrg atan(const std::complex<_Tp>& __z) 171348fb7bfaSmrg { return __complex_atan(__z); } 171448fb7bfaSmrg#endif 171548fb7bfaSmrg 171648fb7bfaSmrg template<typename _Tp> 171748fb7bfaSmrg std::complex<_Tp> 171848fb7bfaSmrg __complex_acosh(const std::complex<_Tp>& __z) 171948fb7bfaSmrg { 172048fb7bfaSmrg // Kahan's formula. 172148fb7bfaSmrg return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) 172248fb7bfaSmrg + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); 172348fb7bfaSmrg } 172448fb7bfaSmrg 172548fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 172648fb7bfaSmrg inline __complex__ float 172748fb7bfaSmrg __complex_acosh(__complex__ float __z) 172848fb7bfaSmrg { return __builtin_cacoshf(__z); } 172948fb7bfaSmrg 173048fb7bfaSmrg inline __complex__ double 173148fb7bfaSmrg __complex_acosh(__complex__ double __z) 173248fb7bfaSmrg { return __builtin_cacosh(__z); } 173348fb7bfaSmrg 173448fb7bfaSmrg inline __complex__ long double 173548fb7bfaSmrg __complex_acosh(const __complex__ long double& __z) 173648fb7bfaSmrg { return __builtin_cacoshl(__z); } 173748fb7bfaSmrg 173848fb7bfaSmrg template<typename _Tp> 173948fb7bfaSmrg inline std::complex<_Tp> 174048fb7bfaSmrg acosh(const std::complex<_Tp>& __z) 174148fb7bfaSmrg { return __complex_acosh(__z.__rep()); } 174248fb7bfaSmrg#else 174348fb7bfaSmrg /// acosh(__z) [8.1.5]. 174448fb7bfaSmrg // Effects: Behaves the same as C99 function cacosh, defined 174548fb7bfaSmrg // in subclause 7.3.6.1. 174648fb7bfaSmrg template<typename _Tp> 174748fb7bfaSmrg inline std::complex<_Tp> 174848fb7bfaSmrg acosh(const std::complex<_Tp>& __z) 174948fb7bfaSmrg { return __complex_acosh(__z); } 175048fb7bfaSmrg#endif 175148fb7bfaSmrg 175248fb7bfaSmrg template<typename _Tp> 175348fb7bfaSmrg std::complex<_Tp> 175448fb7bfaSmrg __complex_asinh(const std::complex<_Tp>& __z) 175548fb7bfaSmrg { 175648fb7bfaSmrg std::complex<_Tp> __t((__z.real() - __z.imag()) 175748fb7bfaSmrg * (__z.real() + __z.imag()) + _Tp(1.0), 175848fb7bfaSmrg _Tp(2.0) * __z.real() * __z.imag()); 175948fb7bfaSmrg __t = std::sqrt(__t); 176048fb7bfaSmrg 176148fb7bfaSmrg return std::log(__t + __z); 176248fb7bfaSmrg } 176348fb7bfaSmrg 176448fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 176548fb7bfaSmrg inline __complex__ float 176648fb7bfaSmrg __complex_asinh(__complex__ float __z) 176748fb7bfaSmrg { return __builtin_casinhf(__z); } 176848fb7bfaSmrg 176948fb7bfaSmrg inline __complex__ double 177048fb7bfaSmrg __complex_asinh(__complex__ double __z) 177148fb7bfaSmrg { return __builtin_casinh(__z); } 177248fb7bfaSmrg 177348fb7bfaSmrg inline __complex__ long double 177448fb7bfaSmrg __complex_asinh(const __complex__ long double& __z) 177548fb7bfaSmrg { return __builtin_casinhl(__z); } 177648fb7bfaSmrg 177748fb7bfaSmrg template<typename _Tp> 177848fb7bfaSmrg inline std::complex<_Tp> 177948fb7bfaSmrg asinh(const std::complex<_Tp>& __z) 178048fb7bfaSmrg { return __complex_asinh(__z.__rep()); } 178148fb7bfaSmrg#else 178248fb7bfaSmrg /// asinh(__z) [8.1.6]. 178348fb7bfaSmrg // Effects: Behaves the same as C99 function casin, defined 178448fb7bfaSmrg // in subclause 7.3.6.2. 178548fb7bfaSmrg template<typename _Tp> 178648fb7bfaSmrg inline std::complex<_Tp> 178748fb7bfaSmrg asinh(const std::complex<_Tp>& __z) 178848fb7bfaSmrg { return __complex_asinh(__z); } 178948fb7bfaSmrg#endif 179048fb7bfaSmrg 179148fb7bfaSmrg template<typename _Tp> 179248fb7bfaSmrg std::complex<_Tp> 179348fb7bfaSmrg __complex_atanh(const std::complex<_Tp>& __z) 179448fb7bfaSmrg { 179548fb7bfaSmrg const _Tp __i2 = __z.imag() * __z.imag(); 179648fb7bfaSmrg const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); 179748fb7bfaSmrg 179848fb7bfaSmrg _Tp __num = _Tp(1.0) + __z.real(); 179948fb7bfaSmrg _Tp __den = _Tp(1.0) - __z.real(); 180048fb7bfaSmrg 180148fb7bfaSmrg __num = __i2 + __num * __num; 180248fb7bfaSmrg __den = __i2 + __den * __den; 180348fb7bfaSmrg 180448fb7bfaSmrg return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), 180548fb7bfaSmrg _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); 180648fb7bfaSmrg } 180748fb7bfaSmrg 180848fb7bfaSmrg#if _GLIBCXX_USE_C99_COMPLEX_TR1 180948fb7bfaSmrg inline __complex__ float 181048fb7bfaSmrg __complex_atanh(__complex__ float __z) 181148fb7bfaSmrg { return __builtin_catanhf(__z); } 181248fb7bfaSmrg 181348fb7bfaSmrg inline __complex__ double 181448fb7bfaSmrg __complex_atanh(__complex__ double __z) 181548fb7bfaSmrg { return __builtin_catanh(__z); } 181648fb7bfaSmrg 181748fb7bfaSmrg inline __complex__ long double 181848fb7bfaSmrg __complex_atanh(const __complex__ long double& __z) 181948fb7bfaSmrg { return __builtin_catanhl(__z); } 182048fb7bfaSmrg 182148fb7bfaSmrg template<typename _Tp> 182248fb7bfaSmrg inline std::complex<_Tp> 182348fb7bfaSmrg atanh(const std::complex<_Tp>& __z) 182448fb7bfaSmrg { return __complex_atanh(__z.__rep()); } 182548fb7bfaSmrg#else 182648fb7bfaSmrg /// atanh(__z) [8.1.7]. 182748fb7bfaSmrg // Effects: Behaves the same as C99 function catanh, defined 182848fb7bfaSmrg // in subclause 7.3.6.3. 182948fb7bfaSmrg template<typename _Tp> 183048fb7bfaSmrg inline std::complex<_Tp> 183148fb7bfaSmrg atanh(const std::complex<_Tp>& __z) 183248fb7bfaSmrg { return __complex_atanh(__z); } 183348fb7bfaSmrg#endif 183448fb7bfaSmrg 183548fb7bfaSmrg template<typename _Tp> 183648fb7bfaSmrg inline _Tp 183748fb7bfaSmrg /// fabs(__z) [8.1.8]. 183848fb7bfaSmrg // Effects: Behaves the same as C99 function cabs, defined 183948fb7bfaSmrg // in subclause 7.3.8.1. 184048fb7bfaSmrg fabs(const std::complex<_Tp>& __z) 184148fb7bfaSmrg { return std::abs(__z); } 184248fb7bfaSmrg 184348fb7bfaSmrg /// Additional overloads [8.1.9]. 184448fb7bfaSmrg template<typename _Tp> 184548fb7bfaSmrg inline typename __gnu_cxx::__promote<_Tp>::__type 184648fb7bfaSmrg arg(_Tp __x) 184748fb7bfaSmrg { 184848fb7bfaSmrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 1849cdbfa754Smrg#if (_GLIBCXX11_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) 185048fb7bfaSmrg return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) 185148fb7bfaSmrg : __type(); 185248fb7bfaSmrg#else 185348fb7bfaSmrg return std::arg(std::complex<__type>(__x)); 185448fb7bfaSmrg#endif 185548fb7bfaSmrg } 185648fb7bfaSmrg 185748fb7bfaSmrg template<typename _Tp> 1858a41324a9Smrg _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type 185948fb7bfaSmrg imag(_Tp) 186048fb7bfaSmrg { return _Tp(); } 186148fb7bfaSmrg 186248fb7bfaSmrg template<typename _Tp> 1863654d12c0Smrg _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type 186448fb7bfaSmrg norm(_Tp __x) 186548fb7bfaSmrg { 186648fb7bfaSmrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 186748fb7bfaSmrg return __type(__x) * __type(__x); 186848fb7bfaSmrg } 186948fb7bfaSmrg 187048fb7bfaSmrg template<typename _Tp> 1871a41324a9Smrg _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type 187248fb7bfaSmrg real(_Tp __x) 187348fb7bfaSmrg { return __x; } 187448fb7bfaSmrg 187548fb7bfaSmrg template<typename _Tp, typename _Up> 187648fb7bfaSmrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 187748fb7bfaSmrg pow(const std::complex<_Tp>& __x, const _Up& __y) 187848fb7bfaSmrg { 187948fb7bfaSmrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 188048fb7bfaSmrg return std::pow(std::complex<__type>(__x), __type(__y)); 188148fb7bfaSmrg } 188248fb7bfaSmrg 188348fb7bfaSmrg template<typename _Tp, typename _Up> 188448fb7bfaSmrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 188548fb7bfaSmrg pow(const _Tp& __x, const std::complex<_Up>& __y) 188648fb7bfaSmrg { 188748fb7bfaSmrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 188848fb7bfaSmrg return std::pow(__type(__x), std::complex<__type>(__y)); 188948fb7bfaSmrg } 189048fb7bfaSmrg 189148fb7bfaSmrg template<typename _Tp, typename _Up> 189248fb7bfaSmrg inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> 189348fb7bfaSmrg pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) 189448fb7bfaSmrg { 189548fb7bfaSmrg typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; 189648fb7bfaSmrg return std::pow(std::complex<__type>(__x), 189748fb7bfaSmrg std::complex<__type>(__y)); 189848fb7bfaSmrg } 18994fee23f9Smrg 19004fee23f9Smrg // Forward declarations. 19014fee23f9Smrg // DR 781. 19024fee23f9Smrg template<typename _Tp> 1903654d12c0Smrg std::complex<_Tp> proj(const std::complex<_Tp>&); 19044fee23f9Smrg 1905654d12c0Smrg // Generic implementation of std::proj, does not work for infinities. 19064fee23f9Smrg template<typename _Tp> 19074fee23f9Smrg inline std::complex<_Tp> 1908654d12c0Smrg __complex_proj(const std::complex<_Tp>& __z) 1909654d12c0Smrg { return __z; } 1910654d12c0Smrg 1911654d12c0Smrg#if _GLIBCXX_USE_C99_COMPLEX 1912654d12c0Smrg inline complex<float> 1913654d12c0Smrg __complex_proj(const complex<float>& __z) 1914654d12c0Smrg { return __builtin_cprojf(__z.__rep()); } 1915654d12c0Smrg 1916654d12c0Smrg inline complex<double> 1917654d12c0Smrg __complex_proj(const complex<double>& __z) 1918654d12c0Smrg { return __builtin_cproj(__z.__rep()); } 1919654d12c0Smrg 1920654d12c0Smrg inline complex<long double> 1921654d12c0Smrg __complex_proj(const complex<long double>& __z) 1922654d12c0Smrg { return __builtin_cprojl(__z.__rep()); } 1923654d12c0Smrg#elif defined _GLIBCXX_USE_C99_MATH_TR1 1924654d12c0Smrg inline complex<float> 1925654d12c0Smrg __complex_proj(const complex<float>& __z) 1926654d12c0Smrg { 1927654d12c0Smrg if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) 1928654d12c0Smrg return complex<float>(__builtin_inff(), 1929654d12c0Smrg __builtin_copysignf(0.0f, __z.imag())); 1930654d12c0Smrg return __z; 1931654d12c0Smrg } 1932654d12c0Smrg 1933654d12c0Smrg inline complex<double> 1934654d12c0Smrg __complex_proj(const complex<double>& __z) 1935654d12c0Smrg { 1936654d12c0Smrg if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) 1937654d12c0Smrg return complex<double>(__builtin_inf(), 1938654d12c0Smrg __builtin_copysign(0.0, __z.imag())); 1939654d12c0Smrg return __z; 1940654d12c0Smrg } 1941654d12c0Smrg 1942654d12c0Smrg inline complex<long double> 1943654d12c0Smrg __complex_proj(const complex<long double>& __z) 1944654d12c0Smrg { 1945654d12c0Smrg if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) 1946654d12c0Smrg return complex<long double>(__builtin_infl(), 1947654d12c0Smrg __builtin_copysignl(0.0l, __z.imag())); 1948654d12c0Smrg return __z; 1949654d12c0Smrg } 1950654d12c0Smrg#endif 1951654d12c0Smrg 19524fee23f9Smrg template<typename _Tp> 19534fee23f9Smrg inline std::complex<_Tp> 19544fee23f9Smrg proj(const std::complex<_Tp>& __z) 19554fee23f9Smrg { return __complex_proj(__z); } 19564fee23f9Smrg 1957654d12c0Smrg // Overload for scalars 19584fee23f9Smrg template<typename _Tp> 1959a41324a9Smrg inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> 19604fee23f9Smrg proj(_Tp __x) 1961a41324a9Smrg { 1962a41324a9Smrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 1963a41324a9Smrg return std::proj(std::complex<__type>(__x)); 1964a41324a9Smrg } 19654fee23f9Smrg 19664fee23f9Smrg template<typename _Tp> 1967654d12c0Smrg inline _GLIBCXX20_CONSTEXPR 1968654d12c0Smrg std::complex<typename __gnu_cxx::__promote<_Tp>::__type> 19694fee23f9Smrg conj(_Tp __x) 1970a41324a9Smrg { 1971a41324a9Smrg typedef typename __gnu_cxx::__promote<_Tp>::__type __type; 1972a41324a9Smrg return std::complex<__type>(__x, -__type()); 1973a41324a9Smrg } 19744fee23f9Smrg 1975d35849d0Smrg#if __cplusplus > 201103L 1976d35849d0Smrg 1977d35849d0Smrginline namespace literals { 1978d35849d0Smrginline namespace complex_literals { 19793f8cba22Smrg#pragma GCC diagnostic push 19803f8cba22Smrg#pragma GCC diagnostic ignored "-Wliteral-suffix" 1981e9e6e0f6Smrg#define __cpp_lib_complex_udls 201309L 1982d35849d0Smrg 1983d35849d0Smrg constexpr std::complex<float> 1984d35849d0Smrg operator""if(long double __num) 1985d35849d0Smrg { return std::complex<float>{0.0F, static_cast<float>(__num)}; } 1986d35849d0Smrg 1987d35849d0Smrg constexpr std::complex<float> 1988d35849d0Smrg operator""if(unsigned long long __num) 1989d35849d0Smrg { return std::complex<float>{0.0F, static_cast<float>(__num)}; } 1990d35849d0Smrg 1991d35849d0Smrg constexpr std::complex<double> 1992d35849d0Smrg operator""i(long double __num) 1993d35849d0Smrg { return std::complex<double>{0.0, static_cast<double>(__num)}; } 1994d35849d0Smrg 1995d35849d0Smrg constexpr std::complex<double> 1996d35849d0Smrg operator""i(unsigned long long __num) 1997d35849d0Smrg { return std::complex<double>{0.0, static_cast<double>(__num)}; } 1998d35849d0Smrg 1999d35849d0Smrg constexpr std::complex<long double> 2000d35849d0Smrg operator""il(long double __num) 2001d35849d0Smrg { return std::complex<long double>{0.0L, __num}; } 2002d35849d0Smrg 2003d35849d0Smrg constexpr std::complex<long double> 2004d35849d0Smrg operator""il(unsigned long long __num) 2005d35849d0Smrg { return std::complex<long double>{0.0L, static_cast<long double>(__num)}; } 2006d35849d0Smrg 20073f8cba22Smrg#pragma GCC diagnostic pop 2008d35849d0Smrg} // inline namespace complex_literals 2009d35849d0Smrg} // inline namespace literals 2010d35849d0Smrg 2011d35849d0Smrg#endif // C++14 2012d35849d0Smrg 20133f8cba22Smrg_GLIBCXX_END_NAMESPACE_VERSION 201448fb7bfaSmrg} // namespace 20154fee23f9Smrg 201648fb7bfaSmrg#endif // C++11 20174fee23f9Smrg 20184fee23f9Smrg#endif /* _GLIBCXX_COMPLEX */ 2019