100db7afdSDavid E. O'Brien // The template and inlines for the -*- C++ -*- complex number classes. 200db7afdSDavid E. O'Brien 3f260e61bSAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 400db7afdSDavid E. O'Brien // Free Software Foundation, Inc. 500db7afdSDavid E. O'Brien // 600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library. This library is free 700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the 800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the 900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option) 1000db7afdSDavid E. O'Brien // any later version. 1100db7afdSDavid E. O'Brien 1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful, 1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of 1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1500db7afdSDavid E. O'Brien // GNU General Public License for more details. 1600db7afdSDavid E. O'Brien 1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along 1800db7afdSDavid E. O'Brien // with this library; see the file COPYING. If not, write to the Free 19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2000db7afdSDavid E. O'Brien // USA. 2100db7afdSDavid E. O'Brien 2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software 2300db7afdSDavid E. O'Brien // library without restriction. Specifically, if other files instantiate 2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile 2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this 2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by 2700db7afdSDavid E. O'Brien // the GNU General Public License. This exception does not however 2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by 2900db7afdSDavid E. O'Brien // the GNU General Public License. 3000db7afdSDavid E. O'Brien 31*f8a1b7d9SAlexander Kabaev /** @file complex 32*f8a1b7d9SAlexander Kabaev * This is a Standard C++ Library header. 33*f8a1b7d9SAlexander Kabaev */ 34*f8a1b7d9SAlexander Kabaev 3500db7afdSDavid E. O'Brien // 3600db7afdSDavid E. O'Brien // ISO C++ 14882: 26.2 Complex Numbers 3700db7afdSDavid E. O'Brien // Note: this is not a conforming implementation. 3800db7afdSDavid E. O'Brien // Initially implemented by Ulrich Drepper <[email protected]> 3900db7afdSDavid E. O'Brien // Improved by Gabriel Dos Reis <[email protected]> 4000db7afdSDavid E. O'Brien // 4100db7afdSDavid E. O'Brien 42ffeaf689SAlexander Kabaev #ifndef _GLIBCXX_COMPLEX 43ffeaf689SAlexander Kabaev #define _GLIBCXX_COMPLEX 1 4400db7afdSDavid E. O'Brien 4500db7afdSDavid E. O'Brien #pragma GCC system_header 4600db7afdSDavid E. O'Brien 4700db7afdSDavid E. O'Brien #include <bits/c++config.h> 4800db7afdSDavid E. O'Brien #include <bits/cpp_type_traits.h> 4900db7afdSDavid E. O'Brien #include <cmath> 5000db7afdSDavid E. O'Brien #include <sstream> 5100db7afdSDavid E. O'Brien 52*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std) 53*f8a1b7d9SAlexander Kabaev 54*f8a1b7d9SAlexander Kabaev // Forward declarations. 5500db7afdSDavid E. O'Brien template<typename _Tp> class complex; 5600db7afdSDavid E. O'Brien template<> class complex<float>; 5700db7afdSDavid E. O'Brien template<> class complex<double>; 5800db7afdSDavid E. O'Brien template<> class complex<long double>; 5900db7afdSDavid E. O'Brien 60ffeaf689SAlexander Kabaev /// Return magnitude of @a z. 6100db7afdSDavid E. O'Brien template<typename _Tp> _Tp abs(const complex<_Tp>&); 62ffeaf689SAlexander Kabaev /// Return phase angle of @a z. 6300db7afdSDavid E. O'Brien template<typename _Tp> _Tp arg(const complex<_Tp>&); 64ffeaf689SAlexander Kabaev /// Return @a z magnitude squared. 6500db7afdSDavid E. O'Brien template<typename _Tp> _Tp norm(const complex<_Tp>&); 6600db7afdSDavid E. O'Brien 67ffeaf689SAlexander Kabaev /// Return complex conjugate of @a z. 6800db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 69ffeaf689SAlexander Kabaev /// Return complex with magnitude @a rho and angle @a theta. 7000db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 7100db7afdSDavid E. O'Brien 7200db7afdSDavid E. O'Brien // Transcendentals: 73ffeaf689SAlexander Kabaev /// Return complex cosine of @a z. 7400db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 75ffeaf689SAlexander Kabaev /// Return complex hyperbolic cosine of @a z. 7600db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 77ffeaf689SAlexander Kabaev /// Return complex base e exponential of @a z. 7800db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 79ffeaf689SAlexander Kabaev /// Return complex natural logarithm of @a z. 8000db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 81ffeaf689SAlexander Kabaev /// Return complex base 10 logarithm of @a z. 8200db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 83ffeaf689SAlexander Kabaev /// Return complex cosine of @a z. 8400db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 85ffeaf689SAlexander Kabaev /// Return @a x to the @a y'th power. 8600db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 87ffeaf689SAlexander Kabaev /// Return @a x to the @a y'th power. 8800db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 8900db7afdSDavid E. O'Brien const complex<_Tp>&); 90ffeaf689SAlexander Kabaev /// Return @a x to the @a y'th power. 9100db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 92ffeaf689SAlexander Kabaev /// Return complex sine of @a z. 9300db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 94ffeaf689SAlexander Kabaev /// Return complex hyperbolic sine of @a z. 9500db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 96ffeaf689SAlexander Kabaev /// Return complex square root of @a z. 9700db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 98ffeaf689SAlexander Kabaev /// Return complex tangent of @a z. 9900db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 100ffeaf689SAlexander Kabaev /// Return complex hyperbolic tangent of @a z. 10100db7afdSDavid E. O'Brien template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 102ffeaf689SAlexander Kabaev //@} 10300db7afdSDavid E. O'Brien 10400db7afdSDavid E. O'Brien 10500db7afdSDavid E. O'Brien // 26.2.2 Primary template class complex 106ffeaf689SAlexander Kabaev /** 107ffeaf689SAlexander Kabaev * Template to represent complex numbers. 108ffeaf689SAlexander Kabaev * 109ffeaf689SAlexander Kabaev * Specializations for float, double, and long double are part of the 110ffeaf689SAlexander Kabaev * library. Results with any other type are not guaranteed. 111ffeaf689SAlexander Kabaev * 112ffeaf689SAlexander Kabaev * @param Tp Type of real and imaginary values. 113ffeaf689SAlexander Kabaev */ 11400db7afdSDavid E. O'Brien template<typename _Tp> 115*f8a1b7d9SAlexander Kabaev struct complex 11600db7afdSDavid E. O'Brien { 117ffeaf689SAlexander Kabaev /// Value typedef. 11800db7afdSDavid E. O'Brien typedef _Tp value_type; 11900db7afdSDavid E. O'Brien 120ffeaf689SAlexander Kabaev /// Default constructor. First parameter is x, second parameter is y. 121ffeaf689SAlexander Kabaev /// Unspecified parameters default to 0. 12200db7afdSDavid E. O'Brien complex(const _Tp& = _Tp(), const _Tp & = _Tp()); 12300db7afdSDavid E. O'Brien 124ffeaf689SAlexander Kabaev // Lets the compiler synthesize the copy constructor 12500db7afdSDavid E. O'Brien // complex (const complex<_Tp>&); 126ffeaf689SAlexander Kabaev /// Copy constructor. 12700db7afdSDavid E. O'Brien template<typename _Up> 12800db7afdSDavid E. O'Brien complex(const complex<_Up>&); 12900db7afdSDavid E. O'Brien 130ffeaf689SAlexander Kabaev /// Return real part of complex number. 131ffeaf689SAlexander Kabaev _Tp& real(); 132ffeaf689SAlexander Kabaev /// Return real part of complex number. 133ffeaf689SAlexander Kabaev const _Tp& real() const; 134ffeaf689SAlexander Kabaev /// Return imaginary part of complex number. 135ffeaf689SAlexander Kabaev _Tp& imag(); 136ffeaf689SAlexander Kabaev /// Return imaginary part of complex number. 137ffeaf689SAlexander Kabaev const _Tp& imag() const; 13800db7afdSDavid E. O'Brien 139ffeaf689SAlexander Kabaev /// Assign this complex number to scalar @a t. 14000db7afdSDavid E. O'Brien complex<_Tp>& operator=(const _Tp&); 141ffeaf689SAlexander Kabaev /// Add @a t to this complex number. 14200db7afdSDavid E. O'Brien complex<_Tp>& operator+=(const _Tp&); 143ffeaf689SAlexander Kabaev /// Subtract @a t from this complex number. 14400db7afdSDavid E. O'Brien complex<_Tp>& operator-=(const _Tp&); 145ffeaf689SAlexander Kabaev /// Multiply this complex number by @a t. 14600db7afdSDavid E. O'Brien complex<_Tp>& operator*=(const _Tp&); 147ffeaf689SAlexander Kabaev /// Divide this complex number by @a t. 14800db7afdSDavid E. O'Brien complex<_Tp>& operator/=(const _Tp&); 14900db7afdSDavid E. O'Brien 150ffeaf689SAlexander Kabaev // Lets the compiler synthesize the 15100db7afdSDavid E. O'Brien // copy and assignment operator 15200db7afdSDavid E. O'Brien // complex<_Tp>& operator= (const complex<_Tp>&); 153ffeaf689SAlexander Kabaev /// Assign this complex number to complex @a z. 15400db7afdSDavid E. O'Brien template<typename _Up> 15500db7afdSDavid E. O'Brien complex<_Tp>& operator=(const complex<_Up>&); 156ffeaf689SAlexander Kabaev /// Add @a z to this complex number. 15700db7afdSDavid E. O'Brien template<typename _Up> 15800db7afdSDavid E. O'Brien complex<_Tp>& operator+=(const complex<_Up>&); 159ffeaf689SAlexander Kabaev /// Subtract @a z from this complex number. 16000db7afdSDavid E. O'Brien template<typename _Up> 16100db7afdSDavid E. O'Brien complex<_Tp>& operator-=(const complex<_Up>&); 162ffeaf689SAlexander Kabaev /// Multiply this complex number by @a z. 16300db7afdSDavid E. O'Brien template<typename _Up> 16400db7afdSDavid E. O'Brien complex<_Tp>& operator*=(const complex<_Up>&); 165ffeaf689SAlexander Kabaev /// Divide this complex number by @a z. 16600db7afdSDavid E. O'Brien template<typename _Up> 16700db7afdSDavid E. O'Brien complex<_Tp>& operator/=(const complex<_Up>&); 16800db7afdSDavid E. O'Brien 169*f8a1b7d9SAlexander Kabaev const complex& __rep() const; 170*f8a1b7d9SAlexander Kabaev 17100db7afdSDavid E. O'Brien private: 172ffeaf689SAlexander Kabaev _Tp _M_real; 173ffeaf689SAlexander Kabaev _Tp _M_imag; 17400db7afdSDavid E. O'Brien }; 17500db7afdSDavid E. O'Brien 17600db7afdSDavid E. O'Brien template<typename _Tp> 177ffeaf689SAlexander Kabaev inline _Tp& real()178ffeaf689SAlexander Kabaev complex<_Tp>::real() { return _M_real; } 179ffeaf689SAlexander Kabaev 180ffeaf689SAlexander Kabaev template<typename _Tp> 181ffeaf689SAlexander Kabaev inline const _Tp& real()18200db7afdSDavid E. O'Brien complex<_Tp>::real() const { return _M_real; } 18300db7afdSDavid E. O'Brien 18400db7afdSDavid E. O'Brien template<typename _Tp> 185ffeaf689SAlexander Kabaev inline _Tp& imag()186ffeaf689SAlexander Kabaev complex<_Tp>::imag() { return _M_imag; } 187ffeaf689SAlexander Kabaev 188ffeaf689SAlexander Kabaev template<typename _Tp> 189ffeaf689SAlexander Kabaev inline const _Tp& imag()19000db7afdSDavid E. O'Brien complex<_Tp>::imag() const { return _M_imag; } 19100db7afdSDavid E. O'Brien 19200db7afdSDavid E. O'Brien template<typename _Tp> 19300db7afdSDavid E. O'Brien inline complex(const _Tp & __r,const _Tp & __i)19400db7afdSDavid E. O'Brien complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) 19500db7afdSDavid E. O'Brien : _M_real(__r), _M_imag(__i) { } 19600db7afdSDavid E. O'Brien 19700db7afdSDavid E. O'Brien template<typename _Tp> 19800db7afdSDavid E. O'Brien template<typename _Up> 19900db7afdSDavid E. O'Brien inline complex(const complex<_Up> & __z)20000db7afdSDavid E. O'Brien complex<_Tp>::complex(const complex<_Up>& __z) 20100db7afdSDavid E. O'Brien : _M_real(__z.real()), _M_imag(__z.imag()) { } 20200db7afdSDavid E. O'Brien 20300db7afdSDavid E. O'Brien template<typename _Tp> 20400db7afdSDavid E. O'Brien complex<_Tp>& 20500db7afdSDavid E. O'Brien complex<_Tp>::operator=(const _Tp& __t) 20600db7afdSDavid E. O'Brien { 20700db7afdSDavid E. O'Brien _M_real = __t; 20800db7afdSDavid E. O'Brien _M_imag = _Tp(); 20900db7afdSDavid E. O'Brien return *this; 21000db7afdSDavid E. O'Brien } 21100db7afdSDavid E. O'Brien 21200db7afdSDavid E. O'Brien // 26.2.5/1 21300db7afdSDavid E. O'Brien template<typename _Tp> 21400db7afdSDavid E. O'Brien inline complex<_Tp>& 21500db7afdSDavid E. O'Brien complex<_Tp>::operator+=(const _Tp& __t) 21600db7afdSDavid E. O'Brien { 21700db7afdSDavid E. O'Brien _M_real += __t; 21800db7afdSDavid E. O'Brien return *this; 21900db7afdSDavid E. O'Brien } 22000db7afdSDavid E. O'Brien 22100db7afdSDavid E. O'Brien // 26.2.5/3 22200db7afdSDavid E. O'Brien template<typename _Tp> 22300db7afdSDavid E. O'Brien inline complex<_Tp>& 22400db7afdSDavid E. O'Brien complex<_Tp>::operator-=(const _Tp& __t) 22500db7afdSDavid E. O'Brien { 22600db7afdSDavid E. O'Brien _M_real -= __t; 22700db7afdSDavid E. O'Brien return *this; 22800db7afdSDavid E. O'Brien } 22900db7afdSDavid E. O'Brien 23000db7afdSDavid E. O'Brien // 26.2.5/5 23100db7afdSDavid E. O'Brien template<typename _Tp> 23200db7afdSDavid E. O'Brien complex<_Tp>& 23300db7afdSDavid E. O'Brien complex<_Tp>::operator*=(const _Tp& __t) 23400db7afdSDavid E. O'Brien { 23500db7afdSDavid E. O'Brien _M_real *= __t; 23600db7afdSDavid E. O'Brien _M_imag *= __t; 23700db7afdSDavid E. O'Brien return *this; 23800db7afdSDavid E. O'Brien } 23900db7afdSDavid E. O'Brien 24000db7afdSDavid E. O'Brien // 26.2.5/7 24100db7afdSDavid E. O'Brien template<typename _Tp> 24200db7afdSDavid E. O'Brien complex<_Tp>& 24300db7afdSDavid E. O'Brien complex<_Tp>::operator/=(const _Tp& __t) 24400db7afdSDavid E. O'Brien { 24500db7afdSDavid E. O'Brien _M_real /= __t; 24600db7afdSDavid E. O'Brien _M_imag /= __t; 24700db7afdSDavid E. O'Brien return *this; 24800db7afdSDavid E. O'Brien } 24900db7afdSDavid E. O'Brien 25000db7afdSDavid E. O'Brien template<typename _Tp> 25100db7afdSDavid E. O'Brien template<typename _Up> 25200db7afdSDavid E. O'Brien complex<_Tp>& 25300db7afdSDavid E. O'Brien complex<_Tp>::operator=(const complex<_Up>& __z) 25400db7afdSDavid E. O'Brien { 25500db7afdSDavid E. O'Brien _M_real = __z.real(); 25600db7afdSDavid E. O'Brien _M_imag = __z.imag(); 25700db7afdSDavid E. O'Brien return *this; 25800db7afdSDavid E. O'Brien } 25900db7afdSDavid E. O'Brien 26000db7afdSDavid E. O'Brien // 26.2.5/9 26100db7afdSDavid E. O'Brien template<typename _Tp> 26200db7afdSDavid E. O'Brien template<typename _Up> 26300db7afdSDavid E. O'Brien complex<_Tp>& 26400db7afdSDavid E. O'Brien complex<_Tp>::operator+=(const complex<_Up>& __z) 26500db7afdSDavid E. O'Brien { 26600db7afdSDavid E. O'Brien _M_real += __z.real(); 26700db7afdSDavid E. O'Brien _M_imag += __z.imag(); 26800db7afdSDavid E. O'Brien return *this; 26900db7afdSDavid E. O'Brien } 27000db7afdSDavid E. O'Brien 27100db7afdSDavid E. O'Brien // 26.2.5/11 27200db7afdSDavid E. O'Brien template<typename _Tp> 27300db7afdSDavid E. O'Brien template<typename _Up> 27400db7afdSDavid E. O'Brien complex<_Tp>& 27500db7afdSDavid E. O'Brien complex<_Tp>::operator-=(const complex<_Up>& __z) 27600db7afdSDavid E. O'Brien { 27700db7afdSDavid E. O'Brien _M_real -= __z.real(); 27800db7afdSDavid E. O'Brien _M_imag -= __z.imag(); 27900db7afdSDavid E. O'Brien return *this; 28000db7afdSDavid E. O'Brien } 28100db7afdSDavid E. O'Brien 28200db7afdSDavid E. O'Brien // 26.2.5/13 28300db7afdSDavid E. O'Brien // XXX: This is a grammar school implementation. 28400db7afdSDavid E. O'Brien template<typename _Tp> 28500db7afdSDavid E. O'Brien template<typename _Up> 28600db7afdSDavid E. O'Brien complex<_Tp>& 28700db7afdSDavid E. O'Brien complex<_Tp>::operator*=(const complex<_Up>& __z) 28800db7afdSDavid E. O'Brien { 28900db7afdSDavid E. O'Brien const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 29000db7afdSDavid E. O'Brien _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 29100db7afdSDavid E. O'Brien _M_real = __r; 29200db7afdSDavid E. O'Brien return *this; 29300db7afdSDavid E. O'Brien } 29400db7afdSDavid E. O'Brien 29500db7afdSDavid E. O'Brien // 26.2.5/15 29600db7afdSDavid E. O'Brien // XXX: This is a grammar school implementation. 29700db7afdSDavid E. O'Brien template<typename _Tp> 29800db7afdSDavid E. O'Brien template<typename _Up> 29900db7afdSDavid E. O'Brien complex<_Tp>& 30000db7afdSDavid E. O'Brien complex<_Tp>::operator/=(const complex<_Up>& __z) 30100db7afdSDavid E. O'Brien { 30200db7afdSDavid E. O'Brien const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 303ffeaf689SAlexander Kabaev const _Tp __n = std::norm(__z); 30400db7afdSDavid E. O'Brien _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 30500db7afdSDavid E. O'Brien _M_real = __r / __n; 30600db7afdSDavid E. O'Brien return *this; 30700db7afdSDavid E. O'Brien } 30800db7afdSDavid E. O'Brien 309*f8a1b7d9SAlexander Kabaev template<typename _Tp> 310*f8a1b7d9SAlexander Kabaev inline const complex<_Tp>& __rep()311*f8a1b7d9SAlexander Kabaev complex<_Tp>::__rep() const { return *this; } 312*f8a1b7d9SAlexander Kabaev 31300db7afdSDavid E. O'Brien // Operators: 314ffeaf689SAlexander Kabaev //@{ 315ffeaf689SAlexander Kabaev /// Return new complex value @a x plus @a y. 31600db7afdSDavid E. O'Brien template<typename _Tp> 31700db7afdSDavid E. O'Brien inline complex<_Tp> 31800db7afdSDavid E. O'Brien operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 319ffeaf689SAlexander Kabaev { 320ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 321ffeaf689SAlexander Kabaev __r += __y; 322ffeaf689SAlexander Kabaev return __r; 323ffeaf689SAlexander Kabaev } 32400db7afdSDavid E. O'Brien 32500db7afdSDavid E. O'Brien template<typename _Tp> 32600db7afdSDavid E. O'Brien inline complex<_Tp> 32700db7afdSDavid E. O'Brien operator+(const complex<_Tp>& __x, const _Tp& __y) 328ffeaf689SAlexander Kabaev { 329ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 330ffeaf689SAlexander Kabaev __r.real() += __y; 331ffeaf689SAlexander Kabaev return __r; 332ffeaf689SAlexander Kabaev } 33300db7afdSDavid E. O'Brien 33400db7afdSDavid E. O'Brien template<typename _Tp> 33500db7afdSDavid E. O'Brien inline complex<_Tp> 33600db7afdSDavid E. O'Brien operator+(const _Tp& __x, const complex<_Tp>& __y) 337ffeaf689SAlexander Kabaev { 338ffeaf689SAlexander Kabaev complex<_Tp> __r = __y; 339ffeaf689SAlexander Kabaev __r.real() += __x; 340ffeaf689SAlexander Kabaev return __r; 341ffeaf689SAlexander Kabaev } 342ffeaf689SAlexander Kabaev //@} 34300db7afdSDavid E. O'Brien 344ffeaf689SAlexander Kabaev //@{ 345ffeaf689SAlexander Kabaev /// Return new complex value @a x minus @a y. 34600db7afdSDavid E. O'Brien template<typename _Tp> 34700db7afdSDavid E. O'Brien inline complex<_Tp> 34800db7afdSDavid E. O'Brien operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 349ffeaf689SAlexander Kabaev { 350ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 351ffeaf689SAlexander Kabaev __r -= __y; 352ffeaf689SAlexander Kabaev return __r; 353ffeaf689SAlexander Kabaev } 35400db7afdSDavid E. O'Brien 35500db7afdSDavid E. O'Brien template<typename _Tp> 35600db7afdSDavid E. O'Brien inline complex<_Tp> 35700db7afdSDavid E. O'Brien operator-(const complex<_Tp>& __x, const _Tp& __y) 358ffeaf689SAlexander Kabaev { 359ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 360ffeaf689SAlexander Kabaev __r.real() -= __y; 361ffeaf689SAlexander Kabaev return __r; 362ffeaf689SAlexander Kabaev } 36300db7afdSDavid E. O'Brien 36400db7afdSDavid E. O'Brien template<typename _Tp> 36500db7afdSDavid E. O'Brien inline complex<_Tp> 36600db7afdSDavid E. O'Brien operator-(const _Tp& __x, const complex<_Tp>& __y) 367ffeaf689SAlexander Kabaev { 368ffeaf689SAlexander Kabaev complex<_Tp> __r(__x, -__y.imag()); 369ffeaf689SAlexander Kabaev __r.real() -= __y.real(); 370ffeaf689SAlexander Kabaev return __r; 371ffeaf689SAlexander Kabaev } 372ffeaf689SAlexander Kabaev //@} 37300db7afdSDavid E. O'Brien 374ffeaf689SAlexander Kabaev //@{ 375ffeaf689SAlexander Kabaev /// Return new complex value @a x times @a y. 37600db7afdSDavid E. O'Brien template<typename _Tp> 37700db7afdSDavid E. O'Brien inline complex<_Tp> 37800db7afdSDavid E. O'Brien operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 379ffeaf689SAlexander Kabaev { 380ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 381ffeaf689SAlexander Kabaev __r *= __y; 382ffeaf689SAlexander Kabaev return __r; 383ffeaf689SAlexander Kabaev } 38400db7afdSDavid E. O'Brien 38500db7afdSDavid E. O'Brien template<typename _Tp> 38600db7afdSDavid E. O'Brien inline complex<_Tp> 38700db7afdSDavid E. O'Brien operator*(const complex<_Tp>& __x, const _Tp& __y) 388ffeaf689SAlexander Kabaev { 389ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 390ffeaf689SAlexander Kabaev __r *= __y; 391ffeaf689SAlexander Kabaev return __r; 392ffeaf689SAlexander Kabaev } 39300db7afdSDavid E. O'Brien 39400db7afdSDavid E. O'Brien template<typename _Tp> 39500db7afdSDavid E. O'Brien inline complex<_Tp> 39600db7afdSDavid E. O'Brien operator*(const _Tp& __x, const complex<_Tp>& __y) 397ffeaf689SAlexander Kabaev { 398ffeaf689SAlexander Kabaev complex<_Tp> __r = __y; 399ffeaf689SAlexander Kabaev __r *= __x; 400ffeaf689SAlexander Kabaev return __r; 401ffeaf689SAlexander Kabaev } 402ffeaf689SAlexander Kabaev //@} 40300db7afdSDavid E. O'Brien 404ffeaf689SAlexander Kabaev //@{ 405ffeaf689SAlexander Kabaev /// Return new complex value @a x divided by @a y. 40600db7afdSDavid E. O'Brien template<typename _Tp> 40700db7afdSDavid E. O'Brien inline complex<_Tp> 40800db7afdSDavid E. O'Brien operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 409ffeaf689SAlexander Kabaev { 410ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 411ffeaf689SAlexander Kabaev __r /= __y; 412ffeaf689SAlexander Kabaev return __r; 413ffeaf689SAlexander Kabaev } 41400db7afdSDavid E. O'Brien 41500db7afdSDavid E. O'Brien template<typename _Tp> 41600db7afdSDavid E. O'Brien inline complex<_Tp> 41700db7afdSDavid E. O'Brien operator/(const complex<_Tp>& __x, const _Tp& __y) 418ffeaf689SAlexander Kabaev { 419ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 420ffeaf689SAlexander Kabaev __r /= __y; 421ffeaf689SAlexander Kabaev return __r; 422ffeaf689SAlexander Kabaev } 42300db7afdSDavid E. O'Brien 42400db7afdSDavid E. O'Brien template<typename _Tp> 42500db7afdSDavid E. O'Brien inline complex<_Tp> 42600db7afdSDavid E. O'Brien operator/(const _Tp& __x, const complex<_Tp>& __y) 427ffeaf689SAlexander Kabaev { 428ffeaf689SAlexander Kabaev complex<_Tp> __r = __x; 429ffeaf689SAlexander Kabaev __r /= __y; 430ffeaf689SAlexander Kabaev return __r; 431ffeaf689SAlexander Kabaev } 432ffeaf689SAlexander Kabaev //@} 43300db7afdSDavid E. O'Brien 434ffeaf689SAlexander Kabaev /// Return @a x. 43500db7afdSDavid E. O'Brien template<typename _Tp> 43600db7afdSDavid E. O'Brien inline complex<_Tp> 43700db7afdSDavid E. O'Brien operator+(const complex<_Tp>& __x) 43800db7afdSDavid E. O'Brien { return __x; } 43900db7afdSDavid E. O'Brien 440ffeaf689SAlexander Kabaev /// Return complex negation of @a x. 44100db7afdSDavid E. O'Brien template<typename _Tp> 44200db7afdSDavid E. O'Brien inline complex<_Tp> 44300db7afdSDavid E. O'Brien operator-(const complex<_Tp>& __x) 44400db7afdSDavid E. O'Brien { return complex<_Tp>(-__x.real(), -__x.imag()); } 44500db7afdSDavid E. O'Brien 446ffeaf689SAlexander Kabaev //@{ 447ffeaf689SAlexander Kabaev /// Return true if @a x is equal to @a y. 44800db7afdSDavid E. O'Brien template<typename _Tp> 44900db7afdSDavid E. O'Brien inline bool 45000db7afdSDavid E. O'Brien operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 45100db7afdSDavid E. O'Brien { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 45200db7afdSDavid E. O'Brien 45300db7afdSDavid E. O'Brien template<typename _Tp> 45400db7afdSDavid E. O'Brien inline bool 45500db7afdSDavid E. O'Brien operator==(const complex<_Tp>& __x, const _Tp& __y) 45600db7afdSDavid E. O'Brien { return __x.real() == __y && __x.imag() == _Tp(); } 45700db7afdSDavid E. O'Brien 45800db7afdSDavid E. O'Brien template<typename _Tp> 45900db7afdSDavid E. O'Brien inline bool 46000db7afdSDavid E. O'Brien operator==(const _Tp& __x, const complex<_Tp>& __y) 46100db7afdSDavid E. O'Brien { return __x == __y.real() && _Tp() == __y.imag(); } 462ffeaf689SAlexander Kabaev //@} 46300db7afdSDavid E. O'Brien 464ffeaf689SAlexander Kabaev //@{ 465ffeaf689SAlexander Kabaev /// Return false if @a x is equal to @a y. 46600db7afdSDavid E. O'Brien template<typename _Tp> 46700db7afdSDavid E. O'Brien inline bool 46800db7afdSDavid E. O'Brien operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 46900db7afdSDavid E. O'Brien { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 47000db7afdSDavid E. O'Brien 47100db7afdSDavid E. O'Brien template<typename _Tp> 47200db7afdSDavid E. O'Brien inline bool 47300db7afdSDavid E. O'Brien operator!=(const complex<_Tp>& __x, const _Tp& __y) 47400db7afdSDavid E. O'Brien { return __x.real() != __y || __x.imag() != _Tp(); } 47500db7afdSDavid E. O'Brien 47600db7afdSDavid E. O'Brien template<typename _Tp> 47700db7afdSDavid E. O'Brien inline bool 47800db7afdSDavid E. O'Brien operator!=(const _Tp& __x, const complex<_Tp>& __y) 47900db7afdSDavid E. O'Brien { return __x != __y.real() || _Tp() != __y.imag(); } 480ffeaf689SAlexander Kabaev //@} 48100db7afdSDavid E. O'Brien 482ffeaf689SAlexander Kabaev /// Extraction operator for complex values. 48300db7afdSDavid E. O'Brien template<typename _Tp, typename _CharT, class _Traits> 48400db7afdSDavid E. O'Brien basic_istream<_CharT, _Traits>& 48500db7afdSDavid E. O'Brien operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 48600db7afdSDavid E. O'Brien { 48700db7afdSDavid E. O'Brien _Tp __re_x, __im_x; 48800db7afdSDavid E. O'Brien _CharT __ch; 48900db7afdSDavid E. O'Brien __is >> __ch; 49000db7afdSDavid E. O'Brien if (__ch == '(') 49100db7afdSDavid E. O'Brien { 49200db7afdSDavid E. O'Brien __is >> __re_x >> __ch; 49300db7afdSDavid E. O'Brien if (__ch == ',') 49400db7afdSDavid E. O'Brien { 49500db7afdSDavid E. O'Brien __is >> __im_x >> __ch; 49600db7afdSDavid E. O'Brien if (__ch == ')') 49700db7afdSDavid E. O'Brien __x = complex<_Tp>(__re_x, __im_x); 49800db7afdSDavid E. O'Brien else 49900db7afdSDavid E. O'Brien __is.setstate(ios_base::failbit); 50000db7afdSDavid E. O'Brien } 50100db7afdSDavid E. O'Brien else if (__ch == ')') 502ffeaf689SAlexander Kabaev __x = __re_x; 50300db7afdSDavid E. O'Brien else 50400db7afdSDavid E. O'Brien __is.setstate(ios_base::failbit); 50500db7afdSDavid E. O'Brien } 50600db7afdSDavid E. O'Brien else 50700db7afdSDavid E. O'Brien { 50800db7afdSDavid E. O'Brien __is.putback(__ch); 50900db7afdSDavid E. O'Brien __is >> __re_x; 510ffeaf689SAlexander Kabaev __x = __re_x; 51100db7afdSDavid E. O'Brien } 51200db7afdSDavid E. O'Brien return __is; 51300db7afdSDavid E. O'Brien } 51400db7afdSDavid E. O'Brien 515ffeaf689SAlexander Kabaev /// Insertion operator for complex values. 51600db7afdSDavid E. O'Brien template<typename _Tp, typename _CharT, class _Traits> 51700db7afdSDavid E. O'Brien basic_ostream<_CharT, _Traits>& 51800db7afdSDavid E. O'Brien operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 51900db7afdSDavid E. O'Brien { 52000db7afdSDavid E. O'Brien basic_ostringstream<_CharT, _Traits> __s; 52100db7afdSDavid E. O'Brien __s.flags(__os.flags()); 52200db7afdSDavid E. O'Brien __s.imbue(__os.getloc()); 52300db7afdSDavid E. O'Brien __s.precision(__os.precision()); 5241b86b14eSAlexander Kabaev __s << '(' << __x.real() << ',' << __x.imag() << ')'; 52500db7afdSDavid E. O'Brien return __os << __s.str(); 52600db7afdSDavid E. O'Brien } 52700db7afdSDavid E. O'Brien 52800db7afdSDavid E. O'Brien // Values 52900db7afdSDavid E. O'Brien template<typename _Tp> 530ffeaf689SAlexander Kabaev inline _Tp& real(complex<_Tp> & __z)531ffeaf689SAlexander Kabaev real(complex<_Tp>& __z) 532ffeaf689SAlexander Kabaev { return __z.real(); } 533ffeaf689SAlexander Kabaev 534ffeaf689SAlexander Kabaev template<typename _Tp> 535ffeaf689SAlexander Kabaev inline const _Tp& real(const complex<_Tp> & __z)53600db7afdSDavid E. O'Brien real(const complex<_Tp>& __z) 53700db7afdSDavid E. O'Brien { return __z.real(); } 53800db7afdSDavid E. O'Brien 53900db7afdSDavid E. O'Brien template<typename _Tp> 540ffeaf689SAlexander Kabaev inline _Tp& imag(complex<_Tp> & __z)541ffeaf689SAlexander Kabaev imag(complex<_Tp>& __z) 542ffeaf689SAlexander Kabaev { return __z.imag(); } 543ffeaf689SAlexander Kabaev 544ffeaf689SAlexander Kabaev template<typename _Tp> 545ffeaf689SAlexander Kabaev inline const _Tp& imag(const complex<_Tp> & __z)54600db7afdSDavid E. O'Brien imag(const complex<_Tp>& __z) 54700db7afdSDavid E. O'Brien { return __z.imag(); } 54800db7afdSDavid E. O'Brien 549*f8a1b7d9SAlexander Kabaev // 26.2.7/3 abs(__z): Returns the magnitude of __z. 55000db7afdSDavid E. O'Brien template<typename _Tp> 55100db7afdSDavid E. O'Brien inline _Tp __complex_abs(const complex<_Tp> & __z)552*f8a1b7d9SAlexander Kabaev __complex_abs(const complex<_Tp>& __z) 55300db7afdSDavid E. O'Brien { 55400db7afdSDavid E. O'Brien _Tp __x = __z.real(); 55500db7afdSDavid E. O'Brien _Tp __y = __z.imag(); 556ffeaf689SAlexander Kabaev const _Tp __s = std::max(abs(__x), abs(__y)); 55700db7afdSDavid E. O'Brien if (__s == _Tp()) // well ... 55800db7afdSDavid E. O'Brien return __s; 55900db7afdSDavid E. O'Brien __x /= __s; 56000db7afdSDavid E. O'Brien __y /= __s; 56100db7afdSDavid E. O'Brien return __s * sqrt(__x * __x + __y * __y); 56200db7afdSDavid E. O'Brien } 56300db7afdSDavid E. O'Brien 564*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 565*f8a1b7d9SAlexander Kabaev inline float __complex_abs(__complex__ float __z)566*f8a1b7d9SAlexander Kabaev __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); } 567*f8a1b7d9SAlexander Kabaev 568*f8a1b7d9SAlexander Kabaev inline double __complex_abs(__complex__ double __z)569*f8a1b7d9SAlexander Kabaev __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); } 570*f8a1b7d9SAlexander Kabaev 571*f8a1b7d9SAlexander Kabaev inline long double __complex_abs(const __complex__ long double & __z)572*f8a1b7d9SAlexander Kabaev __complex_abs(const __complex__ long double& __z) 573*f8a1b7d9SAlexander Kabaev { return __builtin_cabsl(__z); } 574*f8a1b7d9SAlexander Kabaev 57500db7afdSDavid E. O'Brien template<typename _Tp> 57600db7afdSDavid E. O'Brien inline _Tp abs(const complex<_Tp> & __z)577*f8a1b7d9SAlexander Kabaev abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } 578*f8a1b7d9SAlexander Kabaev #else 579*f8a1b7d9SAlexander Kabaev template<typename _Tp> 580*f8a1b7d9SAlexander Kabaev inline _Tp abs(const complex<_Tp> & __z)581*f8a1b7d9SAlexander Kabaev abs(const complex<_Tp>& __z) { return __complex_abs(__z); } 582*f8a1b7d9SAlexander Kabaev #endif 583*f8a1b7d9SAlexander Kabaev 584*f8a1b7d9SAlexander Kabaev 585*f8a1b7d9SAlexander Kabaev // 26.2.7/4: arg(__z): Returns the phase angle of __z. 586*f8a1b7d9SAlexander Kabaev template<typename _Tp> 587*f8a1b7d9SAlexander Kabaev inline _Tp __complex_arg(const complex<_Tp> & __z)588*f8a1b7d9SAlexander Kabaev __complex_arg(const complex<_Tp>& __z) 58900db7afdSDavid E. O'Brien { return atan2(__z.imag(), __z.real()); } 59000db7afdSDavid E. O'Brien 591*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 592*f8a1b7d9SAlexander Kabaev inline float __complex_arg(__complex__ float __z)593*f8a1b7d9SAlexander Kabaev __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } 594*f8a1b7d9SAlexander Kabaev 595*f8a1b7d9SAlexander Kabaev inline double __complex_arg(__complex__ double __z)596*f8a1b7d9SAlexander Kabaev __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } 597*f8a1b7d9SAlexander Kabaev 598*f8a1b7d9SAlexander Kabaev inline long double __complex_arg(const __complex__ long double & __z)599*f8a1b7d9SAlexander Kabaev __complex_arg(const __complex__ long double& __z) 600*f8a1b7d9SAlexander Kabaev { return __builtin_cargl(__z); } 601*f8a1b7d9SAlexander Kabaev 602*f8a1b7d9SAlexander Kabaev template<typename _Tp> 603*f8a1b7d9SAlexander Kabaev inline _Tp arg(const complex<_Tp> & __z)604*f8a1b7d9SAlexander Kabaev arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } 605*f8a1b7d9SAlexander Kabaev #else 606*f8a1b7d9SAlexander Kabaev template<typename _Tp> 607*f8a1b7d9SAlexander Kabaev inline _Tp arg(const complex<_Tp> & __z)608*f8a1b7d9SAlexander Kabaev arg(const complex<_Tp>& __z) { return __complex_arg(__z); } 609*f8a1b7d9SAlexander Kabaev #endif 610*f8a1b7d9SAlexander Kabaev 61100db7afdSDavid E. O'Brien // 26.2.7/5: norm(__z) returns the squared magintude of __z. 61200db7afdSDavid E. O'Brien // As defined, norm() is -not- a norm is the common mathematical 61300db7afdSDavid E. O'Brien // sens used in numerics. The helper class _Norm_helper<> tries to 61400db7afdSDavid E. O'Brien // distinguish between builtin floating point and the rest, so as 61500db7afdSDavid E. O'Brien // to deliver an answer as close as possible to the real value. 61600db7afdSDavid E. O'Brien template<bool> 61700db7afdSDavid E. O'Brien struct _Norm_helper 61800db7afdSDavid E. O'Brien { 61900db7afdSDavid E. O'Brien template<typename _Tp> _S_do_it_Norm_helper62000db7afdSDavid E. O'Brien static inline _Tp _S_do_it(const complex<_Tp>& __z) 62100db7afdSDavid E. O'Brien { 62200db7afdSDavid E. O'Brien const _Tp __x = __z.real(); 62300db7afdSDavid E. O'Brien const _Tp __y = __z.imag(); 62400db7afdSDavid E. O'Brien return __x * __x + __y * __y; 62500db7afdSDavid E. O'Brien } 62600db7afdSDavid E. O'Brien }; 62700db7afdSDavid E. O'Brien 62800db7afdSDavid E. O'Brien template<> 62900db7afdSDavid E. O'Brien struct _Norm_helper<true> 63000db7afdSDavid E. O'Brien { 63100db7afdSDavid E. O'Brien template<typename _Tp> 63200db7afdSDavid E. O'Brien static inline _Tp _S_do_it(const complex<_Tp>& __z) 63300db7afdSDavid E. O'Brien { 634ffeaf689SAlexander Kabaev _Tp __res = std::abs(__z); 63500db7afdSDavid E. O'Brien return __res * __res; 63600db7afdSDavid E. O'Brien } 63700db7afdSDavid E. O'Brien }; 63800db7afdSDavid E. O'Brien 63900db7afdSDavid E. O'Brien template<typename _Tp> 64000db7afdSDavid E. O'Brien inline _Tp 64100db7afdSDavid E. O'Brien norm(const complex<_Tp>& __z) 64200db7afdSDavid E. O'Brien { 643*f8a1b7d9SAlexander Kabaev return _Norm_helper<__is_floating<_Tp>::__value 644*f8a1b7d9SAlexander Kabaev && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); 64500db7afdSDavid E. O'Brien } 64600db7afdSDavid E. O'Brien 64700db7afdSDavid E. O'Brien template<typename _Tp> 64800db7afdSDavid E. O'Brien inline complex<_Tp> 64900db7afdSDavid E. O'Brien polar(const _Tp& __rho, const _Tp& __theta) 65000db7afdSDavid E. O'Brien { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 65100db7afdSDavid E. O'Brien 65200db7afdSDavid E. O'Brien template<typename _Tp> 65300db7afdSDavid E. O'Brien inline complex<_Tp> 65400db7afdSDavid E. O'Brien conj(const complex<_Tp>& __z) 65500db7afdSDavid E. O'Brien { return complex<_Tp>(__z.real(), -__z.imag()); } 65600db7afdSDavid E. O'Brien 65700db7afdSDavid E. O'Brien // Transcendentals 658*f8a1b7d9SAlexander Kabaev 659*f8a1b7d9SAlexander Kabaev // 26.2.8/1 cos(__z): Returns the cosine of __z. 66000db7afdSDavid E. O'Brien template<typename _Tp> 66100db7afdSDavid E. O'Brien inline complex<_Tp> 662*f8a1b7d9SAlexander Kabaev __complex_cos(const complex<_Tp>& __z) 66300db7afdSDavid E. O'Brien { 66400db7afdSDavid E. O'Brien const _Tp __x = __z.real(); 66500db7afdSDavid E. O'Brien const _Tp __y = __z.imag(); 66600db7afdSDavid E. O'Brien return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 66700db7afdSDavid E. O'Brien } 66800db7afdSDavid E. O'Brien 669*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 670*f8a1b7d9SAlexander Kabaev inline __complex__ float 671*f8a1b7d9SAlexander Kabaev __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } 672*f8a1b7d9SAlexander Kabaev 673*f8a1b7d9SAlexander Kabaev inline __complex__ double 674*f8a1b7d9SAlexander Kabaev __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } 675*f8a1b7d9SAlexander Kabaev 676*f8a1b7d9SAlexander Kabaev inline __complex__ long double 677*f8a1b7d9SAlexander Kabaev __complex_cos(const __complex__ long double& __z) 678*f8a1b7d9SAlexander Kabaev { return __builtin_ccosl(__z); } 679*f8a1b7d9SAlexander Kabaev 68000db7afdSDavid E. O'Brien template<typename _Tp> 68100db7afdSDavid E. O'Brien inline complex<_Tp> 682*f8a1b7d9SAlexander Kabaev cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } 683*f8a1b7d9SAlexander Kabaev #else 684*f8a1b7d9SAlexander Kabaev template<typename _Tp> 685*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 686*f8a1b7d9SAlexander Kabaev cos(const complex<_Tp>& __z) { return __complex_cos(__z); } 687*f8a1b7d9SAlexander Kabaev #endif 688*f8a1b7d9SAlexander Kabaev 689*f8a1b7d9SAlexander Kabaev // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. 690*f8a1b7d9SAlexander Kabaev template<typename _Tp> 691*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 692*f8a1b7d9SAlexander Kabaev __complex_cosh(const complex<_Tp>& __z) 69300db7afdSDavid E. O'Brien { 69400db7afdSDavid E. O'Brien const _Tp __x = __z.real(); 69500db7afdSDavid E. O'Brien const _Tp __y = __z.imag(); 69600db7afdSDavid E. O'Brien return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 69700db7afdSDavid E. O'Brien } 69800db7afdSDavid E. O'Brien 699*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 700*f8a1b7d9SAlexander Kabaev inline __complex__ float 701*f8a1b7d9SAlexander Kabaev __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } 702*f8a1b7d9SAlexander Kabaev 703*f8a1b7d9SAlexander Kabaev inline __complex__ double 704*f8a1b7d9SAlexander Kabaev __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } 705*f8a1b7d9SAlexander Kabaev 706*f8a1b7d9SAlexander Kabaev inline __complex__ long double 707*f8a1b7d9SAlexander Kabaev __complex_cosh(const __complex__ long double& __z) 708*f8a1b7d9SAlexander Kabaev { return __builtin_ccoshl(__z); } 70900db7afdSDavid E. O'Brien 71000db7afdSDavid E. O'Brien template<typename _Tp> 71100db7afdSDavid E. O'Brien inline complex<_Tp> 712*f8a1b7d9SAlexander Kabaev cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } 713*f8a1b7d9SAlexander Kabaev #else 714*f8a1b7d9SAlexander Kabaev template<typename _Tp> 715*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 716*f8a1b7d9SAlexander Kabaev cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } 717*f8a1b7d9SAlexander Kabaev #endif 718*f8a1b7d9SAlexander Kabaev 719*f8a1b7d9SAlexander Kabaev // 26.2.8/3 exp(__z): Returns the complex base e exponential of x 720*f8a1b7d9SAlexander Kabaev template<typename _Tp> 721*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 722*f8a1b7d9SAlexander Kabaev __complex_exp(const complex<_Tp>& __z) 723*f8a1b7d9SAlexander Kabaev { return std::polar(exp(__z.real()), __z.imag()); } 724*f8a1b7d9SAlexander Kabaev 725*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 726*f8a1b7d9SAlexander Kabaev inline __complex__ float 727*f8a1b7d9SAlexander Kabaev __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } 728*f8a1b7d9SAlexander Kabaev 729*f8a1b7d9SAlexander Kabaev inline __complex__ double 730*f8a1b7d9SAlexander Kabaev __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } 731*f8a1b7d9SAlexander Kabaev 732*f8a1b7d9SAlexander Kabaev inline __complex__ long double 733*f8a1b7d9SAlexander Kabaev __complex_exp(const __complex__ long double& __z) 734*f8a1b7d9SAlexander Kabaev { return __builtin_cexpl(__z); } 735*f8a1b7d9SAlexander Kabaev 736*f8a1b7d9SAlexander Kabaev template<typename _Tp> 737*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 738*f8a1b7d9SAlexander Kabaev exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } 739*f8a1b7d9SAlexander Kabaev #else 740*f8a1b7d9SAlexander Kabaev template<typename _Tp> 741*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 742*f8a1b7d9SAlexander Kabaev exp(const complex<_Tp>& __z) { return __complex_exp(__z); } 743*f8a1b7d9SAlexander Kabaev #endif 744*f8a1b7d9SAlexander Kabaev 745*f8a1b7d9SAlexander Kabaev // 26.2.8/5 log(__z): Reurns the natural complex logaritm of __z. 746*f8a1b7d9SAlexander Kabaev // The branch cut is along the negative axis. 747*f8a1b7d9SAlexander Kabaev template<typename _Tp> 748*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 749*f8a1b7d9SAlexander Kabaev __complex_log(const complex<_Tp>& __z) 750ffeaf689SAlexander Kabaev { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } 75100db7afdSDavid E. O'Brien 752*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 753*f8a1b7d9SAlexander Kabaev inline __complex__ float 754*f8a1b7d9SAlexander Kabaev __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } 755*f8a1b7d9SAlexander Kabaev 756*f8a1b7d9SAlexander Kabaev inline __complex__ double 757*f8a1b7d9SAlexander Kabaev __complex_log(__complex__ double __z) { return __builtin_clog(__z); } 758*f8a1b7d9SAlexander Kabaev 759*f8a1b7d9SAlexander Kabaev inline __complex__ long double 760*f8a1b7d9SAlexander Kabaev __complex_log(const __complex__ long double& __z) 761*f8a1b7d9SAlexander Kabaev { return __builtin_clogl(__z); } 762*f8a1b7d9SAlexander Kabaev 763*f8a1b7d9SAlexander Kabaev template<typename _Tp> 764*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 765*f8a1b7d9SAlexander Kabaev log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } 766*f8a1b7d9SAlexander Kabaev #else 767*f8a1b7d9SAlexander Kabaev template<typename _Tp> 768*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 769*f8a1b7d9SAlexander Kabaev log(const complex<_Tp>& __z) { return __complex_log(__z); } 770*f8a1b7d9SAlexander Kabaev #endif 771*f8a1b7d9SAlexander Kabaev 77200db7afdSDavid E. O'Brien template<typename _Tp> 77300db7afdSDavid E. O'Brien inline complex<_Tp> 77400db7afdSDavid E. O'Brien log10(const complex<_Tp>& __z) 775ffeaf689SAlexander Kabaev { return std::log(__z) / log(_Tp(10.0)); } 77600db7afdSDavid E. O'Brien 777*f8a1b7d9SAlexander Kabaev // 26.2.8/10 sin(__z): Returns the sine of __z. 77800db7afdSDavid E. O'Brien template<typename _Tp> 77900db7afdSDavid E. O'Brien inline complex<_Tp> 780*f8a1b7d9SAlexander Kabaev __complex_sin(const complex<_Tp>& __z) 78100db7afdSDavid E. O'Brien { 78200db7afdSDavid E. O'Brien const _Tp __x = __z.real(); 78300db7afdSDavid E. O'Brien const _Tp __y = __z.imag(); 78400db7afdSDavid E. O'Brien return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 78500db7afdSDavid E. O'Brien } 78600db7afdSDavid E. O'Brien 787*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 788*f8a1b7d9SAlexander Kabaev inline __complex__ float 789*f8a1b7d9SAlexander Kabaev __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } 790*f8a1b7d9SAlexander Kabaev 791*f8a1b7d9SAlexander Kabaev inline __complex__ double 792*f8a1b7d9SAlexander Kabaev __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } 793*f8a1b7d9SAlexander Kabaev 794*f8a1b7d9SAlexander Kabaev inline __complex__ long double 795*f8a1b7d9SAlexander Kabaev __complex_sin(const __complex__ long double& __z) 796*f8a1b7d9SAlexander Kabaev { return __builtin_csinl(__z); } 797*f8a1b7d9SAlexander Kabaev 79800db7afdSDavid E. O'Brien template<typename _Tp> 79900db7afdSDavid E. O'Brien inline complex<_Tp> 800*f8a1b7d9SAlexander Kabaev sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } 801*f8a1b7d9SAlexander Kabaev #else 802*f8a1b7d9SAlexander Kabaev template<typename _Tp> 803*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 804*f8a1b7d9SAlexander Kabaev sin(const complex<_Tp>& __z) { return __complex_sin(__z); } 805*f8a1b7d9SAlexander Kabaev #endif 806*f8a1b7d9SAlexander Kabaev 807*f8a1b7d9SAlexander Kabaev // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. 808*f8a1b7d9SAlexander Kabaev template<typename _Tp> 809*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 810*f8a1b7d9SAlexander Kabaev __complex_sinh(const complex<_Tp>& __z) 81100db7afdSDavid E. O'Brien { 81200db7afdSDavid E. O'Brien const _Tp __x = __z.real(); 81300db7afdSDavid E. O'Brien const _Tp __y = __z.imag(); 81400db7afdSDavid E. O'Brien return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 81500db7afdSDavid E. O'Brien } 81600db7afdSDavid E. O'Brien 817*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 818*f8a1b7d9SAlexander Kabaev inline __complex__ float 819*f8a1b7d9SAlexander Kabaev __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } 820*f8a1b7d9SAlexander Kabaev 821*f8a1b7d9SAlexander Kabaev inline __complex__ double 822*f8a1b7d9SAlexander Kabaev __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } 823*f8a1b7d9SAlexander Kabaev 824*f8a1b7d9SAlexander Kabaev inline __complex__ long double 825*f8a1b7d9SAlexander Kabaev __complex_sinh(const __complex__ long double& __z) 826*f8a1b7d9SAlexander Kabaev { return __builtin_csinhl(__z); } 827*f8a1b7d9SAlexander Kabaev 828*f8a1b7d9SAlexander Kabaev template<typename _Tp> 829*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 830*f8a1b7d9SAlexander Kabaev sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } 831*f8a1b7d9SAlexander Kabaev #else 832*f8a1b7d9SAlexander Kabaev template<typename _Tp> 833*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 834*f8a1b7d9SAlexander Kabaev sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } 835*f8a1b7d9SAlexander Kabaev #endif 836*f8a1b7d9SAlexander Kabaev 837*f8a1b7d9SAlexander Kabaev // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. 838*f8a1b7d9SAlexander Kabaev // The branch cut is on the negative axis. 83900db7afdSDavid E. O'Brien template<typename _Tp> 84000db7afdSDavid E. O'Brien complex<_Tp> 841*f8a1b7d9SAlexander Kabaev __complex_sqrt(const complex<_Tp>& __z) 84200db7afdSDavid E. O'Brien { 84300db7afdSDavid E. O'Brien _Tp __x = __z.real(); 84400db7afdSDavid E. O'Brien _Tp __y = __z.imag(); 84500db7afdSDavid E. O'Brien 84600db7afdSDavid E. O'Brien if (__x == _Tp()) 84700db7afdSDavid E. O'Brien { 84800db7afdSDavid E. O'Brien _Tp __t = sqrt(abs(__y) / 2); 84900db7afdSDavid E. O'Brien return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 85000db7afdSDavid E. O'Brien } 85100db7afdSDavid E. O'Brien else 85200db7afdSDavid E. O'Brien { 853ffeaf689SAlexander Kabaev _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); 85400db7afdSDavid E. O'Brien _Tp __u = __t / 2; 85500db7afdSDavid E. O'Brien return __x > _Tp() 85600db7afdSDavid E. O'Brien ? complex<_Tp>(__u, __y / __t) 85700db7afdSDavid E. O'Brien : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 85800db7afdSDavid E. O'Brien } 85900db7afdSDavid E. O'Brien } 86000db7afdSDavid E. O'Brien 861*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 862*f8a1b7d9SAlexander Kabaev inline __complex__ float 863*f8a1b7d9SAlexander Kabaev __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } 864*f8a1b7d9SAlexander Kabaev 865*f8a1b7d9SAlexander Kabaev inline __complex__ double 866*f8a1b7d9SAlexander Kabaev __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } 867*f8a1b7d9SAlexander Kabaev 868*f8a1b7d9SAlexander Kabaev inline __complex__ long double 869*f8a1b7d9SAlexander Kabaev __complex_sqrt(const __complex__ long double& __z) 870*f8a1b7d9SAlexander Kabaev { return __builtin_csqrtl(__z); } 87100db7afdSDavid E. O'Brien 87200db7afdSDavid E. O'Brien template<typename _Tp> 87300db7afdSDavid E. O'Brien inline complex<_Tp> 874*f8a1b7d9SAlexander Kabaev sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } 875*f8a1b7d9SAlexander Kabaev #else 876*f8a1b7d9SAlexander Kabaev template<typename _Tp> 877*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 878*f8a1b7d9SAlexander Kabaev sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } 879*f8a1b7d9SAlexander Kabaev #endif 88000db7afdSDavid E. O'Brien 881*f8a1b7d9SAlexander Kabaev // 26.2.8/14 tan(__z): Return the complex tangent of __z. 882*f8a1b7d9SAlexander Kabaev 883*f8a1b7d9SAlexander Kabaev template<typename _Tp> 884*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 885*f8a1b7d9SAlexander Kabaev __complex_tan(const complex<_Tp>& __z) 886*f8a1b7d9SAlexander Kabaev { return std::sin(__z) / std::cos(__z); } 887*f8a1b7d9SAlexander Kabaev 888*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 889*f8a1b7d9SAlexander Kabaev inline __complex__ float 890*f8a1b7d9SAlexander Kabaev __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } 891*f8a1b7d9SAlexander Kabaev 892*f8a1b7d9SAlexander Kabaev inline __complex__ double 893*f8a1b7d9SAlexander Kabaev __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } 894*f8a1b7d9SAlexander Kabaev 895*f8a1b7d9SAlexander Kabaev inline __complex__ long double 896*f8a1b7d9SAlexander Kabaev __complex_tan(const __complex__ long double& __z) 897*f8a1b7d9SAlexander Kabaev { return __builtin_ctanl(__z); } 898*f8a1b7d9SAlexander Kabaev 899*f8a1b7d9SAlexander Kabaev template<typename _Tp> 900*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 901*f8a1b7d9SAlexander Kabaev tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } 902*f8a1b7d9SAlexander Kabaev #else 903*f8a1b7d9SAlexander Kabaev template<typename _Tp> 904*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 905*f8a1b7d9SAlexander Kabaev tan(const complex<_Tp>& __z) { return __complex_tan(__z); } 906*f8a1b7d9SAlexander Kabaev #endif 907*f8a1b7d9SAlexander Kabaev 908*f8a1b7d9SAlexander Kabaev 909*f8a1b7d9SAlexander Kabaev // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. 910*f8a1b7d9SAlexander Kabaev 911*f8a1b7d9SAlexander Kabaev template<typename _Tp> 912*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 913*f8a1b7d9SAlexander Kabaev __complex_tanh(const complex<_Tp>& __z) 914*f8a1b7d9SAlexander Kabaev { return std::sinh(__z) / std::cosh(__z); } 915*f8a1b7d9SAlexander Kabaev 916*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 917*f8a1b7d9SAlexander Kabaev inline __complex__ float 918*f8a1b7d9SAlexander Kabaev __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } 919*f8a1b7d9SAlexander Kabaev 920*f8a1b7d9SAlexander Kabaev inline __complex__ double 921*f8a1b7d9SAlexander Kabaev __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } 922*f8a1b7d9SAlexander Kabaev 923*f8a1b7d9SAlexander Kabaev inline __complex__ long double 924*f8a1b7d9SAlexander Kabaev __complex_tanh(const __complex__ long double& __z) 925*f8a1b7d9SAlexander Kabaev { return __builtin_ctanhl(__z); } 926*f8a1b7d9SAlexander Kabaev 927*f8a1b7d9SAlexander Kabaev template<typename _Tp> 928*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 929*f8a1b7d9SAlexander Kabaev tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } 930*f8a1b7d9SAlexander Kabaev #else 931*f8a1b7d9SAlexander Kabaev template<typename _Tp> 932*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 933*f8a1b7d9SAlexander Kabaev tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } 934*f8a1b7d9SAlexander Kabaev #endif 935*f8a1b7d9SAlexander Kabaev 936*f8a1b7d9SAlexander Kabaev 937*f8a1b7d9SAlexander Kabaev // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x 938*f8a1b7d9SAlexander Kabaev // raised to the __y-th power. The branch 939*f8a1b7d9SAlexander Kabaev // cut is on the negative axis. 94000db7afdSDavid E. O'Brien template<typename _Tp> 94100db7afdSDavid E. O'Brien inline complex<_Tp> 94200db7afdSDavid E. O'Brien pow(const complex<_Tp>& __z, int __n) 943*f8a1b7d9SAlexander Kabaev { return std::__pow_helper(__z, __n); } 94400db7afdSDavid E. O'Brien 94500db7afdSDavid E. O'Brien template<typename _Tp> 9461b86b14eSAlexander Kabaev complex<_Tp> 94700db7afdSDavid E. O'Brien pow(const complex<_Tp>& __x, const _Tp& __y) 94800db7afdSDavid E. O'Brien { 949*f8a1b7d9SAlexander Kabaev #ifndef _GLIBCXX_USE_C99_COMPLEX 950*f8a1b7d9SAlexander Kabaev if (__x == _Tp()) 951*f8a1b7d9SAlexander Kabaev return _Tp(); 952*f8a1b7d9SAlexander Kabaev #endif 953ffeaf689SAlexander Kabaev if (__x.imag() == _Tp() && __x.real() > _Tp()) 9541b86b14eSAlexander Kabaev return pow(__x.real(), __y); 9551b86b14eSAlexander Kabaev 956ffeaf689SAlexander Kabaev complex<_Tp> __t = std::log(__x); 957ffeaf689SAlexander Kabaev return std::polar(exp(__y * __t.real()), __y * __t.imag()); 95800db7afdSDavid E. O'Brien } 95900db7afdSDavid E. O'Brien 96000db7afdSDavid E. O'Brien template<typename _Tp> 96100db7afdSDavid E. O'Brien inline complex<_Tp> 962*f8a1b7d9SAlexander Kabaev __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 963*f8a1b7d9SAlexander Kabaev { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } 964*f8a1b7d9SAlexander Kabaev 965*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_USE_C99_COMPLEX 966*f8a1b7d9SAlexander Kabaev inline __complex__ float 967*f8a1b7d9SAlexander Kabaev __complex_pow(__complex__ float __x, __complex__ float __y) 968*f8a1b7d9SAlexander Kabaev { return __builtin_cpowf(__x, __y); } 969*f8a1b7d9SAlexander Kabaev 970*f8a1b7d9SAlexander Kabaev inline __complex__ double 971*f8a1b7d9SAlexander Kabaev __complex_pow(__complex__ double __x, __complex__ double __y) 972*f8a1b7d9SAlexander Kabaev { return __builtin_cpow(__x, __y); } 973*f8a1b7d9SAlexander Kabaev 974*f8a1b7d9SAlexander Kabaev inline __complex__ long double 975*f8a1b7d9SAlexander Kabaev __complex_pow(const __complex__ long double& __x, 976*f8a1b7d9SAlexander Kabaev const __complex__ long double& __y) 977*f8a1b7d9SAlexander Kabaev { return __builtin_cpowl(__x, __y); } 978*f8a1b7d9SAlexander Kabaev 979*f8a1b7d9SAlexander Kabaev template<typename _Tp> 980*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 98100db7afdSDavid E. O'Brien pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 982*f8a1b7d9SAlexander Kabaev { return __complex_pow(__x.__rep(), __y.__rep()); } 983*f8a1b7d9SAlexander Kabaev #else 984*f8a1b7d9SAlexander Kabaev template<typename _Tp> 985*f8a1b7d9SAlexander Kabaev inline complex<_Tp> 986*f8a1b7d9SAlexander Kabaev pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 987*f8a1b7d9SAlexander Kabaev { return __complex_pow(__x, __y); } 988*f8a1b7d9SAlexander Kabaev #endif 98900db7afdSDavid E. O'Brien 99000db7afdSDavid E. O'Brien template<typename _Tp> 99100db7afdSDavid E. O'Brien inline complex<_Tp> 99200db7afdSDavid E. O'Brien pow(const _Tp& __x, const complex<_Tp>& __y) 99300db7afdSDavid E. O'Brien { 994ffeaf689SAlexander Kabaev return __x > _Tp() ? std::polar(pow(__x, __y.real()), 995ffeaf689SAlexander Kabaev __y.imag() * log(__x)) 996ffeaf689SAlexander Kabaev : std::pow(complex<_Tp>(__x, _Tp()), __y); 99700db7afdSDavid E. O'Brien } 99800db7afdSDavid E. O'Brien 99900db7afdSDavid E. O'Brien // 26.2.3 complex specializations 100000db7afdSDavid E. O'Brien // complex<float> specialization 1001*f8a1b7d9SAlexander Kabaev template<> 1002*f8a1b7d9SAlexander Kabaev struct complex<float> 100300db7afdSDavid E. O'Brien { 100400db7afdSDavid E. O'Brien typedef float value_type; 1005*f8a1b7d9SAlexander Kabaev typedef __complex__ float _ComplexT; 1006*f8a1b7d9SAlexander Kabaev 1007*f8a1b7d9SAlexander Kabaev complex(_ComplexT __z) : _M_value(__z) { } 100800db7afdSDavid E. O'Brien 100900db7afdSDavid E. O'Brien complex(float = 0.0f, float = 0.0f); 1010f260e61bSAlexander Kabaev 101100db7afdSDavid E. O'Brien explicit complex(const complex<double>&); 101200db7afdSDavid E. O'Brien explicit complex(const complex<long double>&); 101300db7afdSDavid E. O'Brien 1014ffeaf689SAlexander Kabaev float& real(); 1015ffeaf689SAlexander Kabaev const float& real() const; 1016ffeaf689SAlexander Kabaev float& imag(); 1017ffeaf689SAlexander Kabaev const float& imag() const; 101800db7afdSDavid E. O'Brien 101900db7afdSDavid E. O'Brien complex<float>& operator=(float); 102000db7afdSDavid E. O'Brien complex<float>& operator+=(float); 102100db7afdSDavid E. O'Brien complex<float>& operator-=(float); 102200db7afdSDavid E. O'Brien complex<float>& operator*=(float); 102300db7afdSDavid E. O'Brien complex<float>& operator/=(float); 102400db7afdSDavid E. O'Brien 102500db7afdSDavid E. O'Brien // Let's the compiler synthetize the copy and assignment 102600db7afdSDavid E. O'Brien // operator. It always does a pretty good job. 102700db7afdSDavid E. O'Brien // complex& operator= (const complex&); 102800db7afdSDavid E. O'Brien template<typename _Tp> 102900db7afdSDavid E. O'Brien complex<float>&operator=(const complex<_Tp>&); 103000db7afdSDavid E. O'Brien template<typename _Tp> 103100db7afdSDavid E. O'Brien complex<float>& operator+=(const complex<_Tp>&); 103200db7afdSDavid E. O'Brien template<class _Tp> 103300db7afdSDavid E. O'Brien complex<float>& operator-=(const complex<_Tp>&); 103400db7afdSDavid E. O'Brien template<class _Tp> 103500db7afdSDavid E. O'Brien complex<float>& operator*=(const complex<_Tp>&); 103600db7afdSDavid E. O'Brien template<class _Tp> 103700db7afdSDavid E. O'Brien complex<float>&operator/=(const complex<_Tp>&); 103800db7afdSDavid E. O'Brien 1039*f8a1b7d9SAlexander Kabaev const _ComplexT& __rep() const { return _M_value; } 1040*f8a1b7d9SAlexander Kabaev 104100db7afdSDavid E. O'Brien private: 104200db7afdSDavid E. O'Brien _ComplexT _M_value; 104300db7afdSDavid E. O'Brien }; 104400db7afdSDavid E. O'Brien 1045ffeaf689SAlexander Kabaev inline float& 1046ffeaf689SAlexander Kabaev complex<float>::real() 1047ffeaf689SAlexander Kabaev { return __real__ _M_value; } 1048ffeaf689SAlexander Kabaev 1049ffeaf689SAlexander Kabaev inline const float& 105000db7afdSDavid E. O'Brien complex<float>::real() const 105100db7afdSDavid E. O'Brien { return __real__ _M_value; } 105200db7afdSDavid E. O'Brien 1053ffeaf689SAlexander Kabaev inline float& 1054ffeaf689SAlexander Kabaev complex<float>::imag() 1055ffeaf689SAlexander Kabaev { return __imag__ _M_value; } 1056ffeaf689SAlexander Kabaev 1057ffeaf689SAlexander Kabaev inline const float& 105800db7afdSDavid E. O'Brien complex<float>::imag() const 105900db7afdSDavid E. O'Brien { return __imag__ _M_value; } 106000db7afdSDavid E. O'Brien 106100db7afdSDavid E. O'Brien inline 106200db7afdSDavid E. O'Brien complex<float>::complex(float r, float i) 106300db7afdSDavid E. O'Brien { 106400db7afdSDavid E. O'Brien __real__ _M_value = r; 106500db7afdSDavid E. O'Brien __imag__ _M_value = i; 106600db7afdSDavid E. O'Brien } 106700db7afdSDavid E. O'Brien 106800db7afdSDavid E. O'Brien inline complex<float>& 106900db7afdSDavid E. O'Brien complex<float>::operator=(float __f) 107000db7afdSDavid E. O'Brien { 107100db7afdSDavid E. O'Brien __real__ _M_value = __f; 107200db7afdSDavid E. O'Brien __imag__ _M_value = 0.0f; 107300db7afdSDavid E. O'Brien return *this; 107400db7afdSDavid E. O'Brien } 107500db7afdSDavid E. O'Brien 107600db7afdSDavid E. O'Brien inline complex<float>& 107700db7afdSDavid E. O'Brien complex<float>::operator+=(float __f) 107800db7afdSDavid E. O'Brien { 107900db7afdSDavid E. O'Brien __real__ _M_value += __f; 108000db7afdSDavid E. O'Brien return *this; 108100db7afdSDavid E. O'Brien } 108200db7afdSDavid E. O'Brien 108300db7afdSDavid E. O'Brien inline complex<float>& 108400db7afdSDavid E. O'Brien complex<float>::operator-=(float __f) 108500db7afdSDavid E. O'Brien { 108600db7afdSDavid E. O'Brien __real__ _M_value -= __f; 108700db7afdSDavid E. O'Brien return *this; 108800db7afdSDavid E. O'Brien } 108900db7afdSDavid E. O'Brien 109000db7afdSDavid E. O'Brien inline complex<float>& 109100db7afdSDavid E. O'Brien complex<float>::operator*=(float __f) 109200db7afdSDavid E. O'Brien { 109300db7afdSDavid E. O'Brien _M_value *= __f; 109400db7afdSDavid E. O'Brien return *this; 109500db7afdSDavid E. O'Brien } 109600db7afdSDavid E. O'Brien 109700db7afdSDavid E. O'Brien inline complex<float>& 109800db7afdSDavid E. O'Brien complex<float>::operator/=(float __f) 109900db7afdSDavid E. O'Brien { 110000db7afdSDavid E. O'Brien _M_value /= __f; 110100db7afdSDavid E. O'Brien return *this; 110200db7afdSDavid E. O'Brien } 110300db7afdSDavid E. O'Brien 110400db7afdSDavid E. O'Brien template<typename _Tp> 110500db7afdSDavid E. O'Brien inline complex<float>& 110600db7afdSDavid E. O'Brien complex<float>::operator=(const complex<_Tp>& __z) 110700db7afdSDavid E. O'Brien { 110800db7afdSDavid E. O'Brien __real__ _M_value = __z.real(); 110900db7afdSDavid E. O'Brien __imag__ _M_value = __z.imag(); 111000db7afdSDavid E. O'Brien return *this; 111100db7afdSDavid E. O'Brien } 111200db7afdSDavid E. O'Brien 111300db7afdSDavid E. O'Brien template<typename _Tp> 111400db7afdSDavid E. O'Brien inline complex<float>& 111500db7afdSDavid E. O'Brien complex<float>::operator+=(const complex<_Tp>& __z) 111600db7afdSDavid E. O'Brien { 111700db7afdSDavid E. O'Brien __real__ _M_value += __z.real(); 111800db7afdSDavid E. O'Brien __imag__ _M_value += __z.imag(); 111900db7afdSDavid E. O'Brien return *this; 112000db7afdSDavid E. O'Brien } 112100db7afdSDavid E. O'Brien 112200db7afdSDavid E. O'Brien template<typename _Tp> 112300db7afdSDavid E. O'Brien inline complex<float>& 112400db7afdSDavid E. O'Brien complex<float>::operator-=(const complex<_Tp>& __z) 112500db7afdSDavid E. O'Brien { 112600db7afdSDavid E. O'Brien __real__ _M_value -= __z.real(); 112700db7afdSDavid E. O'Brien __imag__ _M_value -= __z.imag(); 112800db7afdSDavid E. O'Brien return *this; 112900db7afdSDavid E. O'Brien } 113000db7afdSDavid E. O'Brien 113100db7afdSDavid E. O'Brien template<typename _Tp> 113200db7afdSDavid E. O'Brien inline complex<float>& 113300db7afdSDavid E. O'Brien complex<float>::operator*=(const complex<_Tp>& __z) 113400db7afdSDavid E. O'Brien { 113500db7afdSDavid E. O'Brien _ComplexT __t; 113600db7afdSDavid E. O'Brien __real__ __t = __z.real(); 113700db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 113800db7afdSDavid E. O'Brien _M_value *= __t; 113900db7afdSDavid E. O'Brien return *this; 114000db7afdSDavid E. O'Brien } 114100db7afdSDavid E. O'Brien 114200db7afdSDavid E. O'Brien template<typename _Tp> 114300db7afdSDavid E. O'Brien inline complex<float>& 114400db7afdSDavid E. O'Brien complex<float>::operator/=(const complex<_Tp>& __z) 114500db7afdSDavid E. O'Brien { 114600db7afdSDavid E. O'Brien _ComplexT __t; 114700db7afdSDavid E. O'Brien __real__ __t = __z.real(); 114800db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 114900db7afdSDavid E. O'Brien _M_value /= __t; 115000db7afdSDavid E. O'Brien return *this; 115100db7afdSDavid E. O'Brien } 115200db7afdSDavid E. O'Brien 115300db7afdSDavid E. O'Brien // 26.2.3 complex specializations 115400db7afdSDavid E. O'Brien // complex<double> specialization 1155*f8a1b7d9SAlexander Kabaev template<> 1156*f8a1b7d9SAlexander Kabaev struct complex<double> 115700db7afdSDavid E. O'Brien { 115800db7afdSDavid E. O'Brien typedef double value_type; 1159*f8a1b7d9SAlexander Kabaev typedef __complex__ double _ComplexT; 1160*f8a1b7d9SAlexander Kabaev 1161*f8a1b7d9SAlexander Kabaev complex(_ComplexT __z) : _M_value(__z) { } 116200db7afdSDavid E. O'Brien 116300db7afdSDavid E. O'Brien complex(double = 0.0, double = 0.0); 1164f260e61bSAlexander Kabaev 116500db7afdSDavid E. O'Brien complex(const complex<float>&); 116600db7afdSDavid E. O'Brien explicit complex(const complex<long double>&); 116700db7afdSDavid E. O'Brien 1168ffeaf689SAlexander Kabaev double& real(); 1169ffeaf689SAlexander Kabaev const double& real() const; 1170ffeaf689SAlexander Kabaev double& imag(); 1171ffeaf689SAlexander Kabaev const double& imag() const; 117200db7afdSDavid E. O'Brien 117300db7afdSDavid E. O'Brien complex<double>& operator=(double); 117400db7afdSDavid E. O'Brien complex<double>& operator+=(double); 117500db7afdSDavid E. O'Brien complex<double>& operator-=(double); 117600db7afdSDavid E. O'Brien complex<double>& operator*=(double); 117700db7afdSDavid E. O'Brien complex<double>& operator/=(double); 117800db7afdSDavid E. O'Brien 117900db7afdSDavid E. O'Brien // The compiler will synthetize this, efficiently. 118000db7afdSDavid E. O'Brien // complex& operator= (const complex&); 118100db7afdSDavid E. O'Brien template<typename _Tp> 118200db7afdSDavid E. O'Brien complex<double>& operator=(const complex<_Tp>&); 118300db7afdSDavid E. O'Brien template<typename _Tp> 118400db7afdSDavid E. O'Brien complex<double>& operator+=(const complex<_Tp>&); 118500db7afdSDavid E. O'Brien template<typename _Tp> 118600db7afdSDavid E. O'Brien complex<double>& operator-=(const complex<_Tp>&); 118700db7afdSDavid E. O'Brien template<typename _Tp> 118800db7afdSDavid E. O'Brien complex<double>& operator*=(const complex<_Tp>&); 118900db7afdSDavid E. O'Brien template<typename _Tp> 119000db7afdSDavid E. O'Brien complex<double>& operator/=(const complex<_Tp>&); 119100db7afdSDavid E. O'Brien 1192*f8a1b7d9SAlexander Kabaev const _ComplexT& __rep() const { return _M_value; } 1193*f8a1b7d9SAlexander Kabaev 119400db7afdSDavid E. O'Brien private: 119500db7afdSDavid E. O'Brien _ComplexT _M_value; 119600db7afdSDavid E. O'Brien }; 119700db7afdSDavid E. O'Brien 1198ffeaf689SAlexander Kabaev inline double& 1199ffeaf689SAlexander Kabaev complex<double>::real() 1200ffeaf689SAlexander Kabaev { return __real__ _M_value; } 1201ffeaf689SAlexander Kabaev 1202ffeaf689SAlexander Kabaev inline const double& 120300db7afdSDavid E. O'Brien complex<double>::real() const 120400db7afdSDavid E. O'Brien { return __real__ _M_value; } 120500db7afdSDavid E. O'Brien 1206ffeaf689SAlexander Kabaev inline double& 1207ffeaf689SAlexander Kabaev complex<double>::imag() 1208ffeaf689SAlexander Kabaev { return __imag__ _M_value; } 1209ffeaf689SAlexander Kabaev 1210ffeaf689SAlexander Kabaev inline const double& 121100db7afdSDavid E. O'Brien complex<double>::imag() const 121200db7afdSDavid E. O'Brien { return __imag__ _M_value; } 121300db7afdSDavid E. O'Brien 121400db7afdSDavid E. O'Brien inline 121500db7afdSDavid E. O'Brien complex<double>::complex(double __r, double __i) 121600db7afdSDavid E. O'Brien { 121700db7afdSDavid E. O'Brien __real__ _M_value = __r; 121800db7afdSDavid E. O'Brien __imag__ _M_value = __i; 121900db7afdSDavid E. O'Brien } 122000db7afdSDavid E. O'Brien 122100db7afdSDavid E. O'Brien inline complex<double>& 122200db7afdSDavid E. O'Brien complex<double>::operator=(double __d) 122300db7afdSDavid E. O'Brien { 122400db7afdSDavid E. O'Brien __real__ _M_value = __d; 122500db7afdSDavid E. O'Brien __imag__ _M_value = 0.0; 122600db7afdSDavid E. O'Brien return *this; 122700db7afdSDavid E. O'Brien } 122800db7afdSDavid E. O'Brien 122900db7afdSDavid E. O'Brien inline complex<double>& 123000db7afdSDavid E. O'Brien complex<double>::operator+=(double __d) 123100db7afdSDavid E. O'Brien { 123200db7afdSDavid E. O'Brien __real__ _M_value += __d; 123300db7afdSDavid E. O'Brien return *this; 123400db7afdSDavid E. O'Brien } 123500db7afdSDavid E. O'Brien 123600db7afdSDavid E. O'Brien inline complex<double>& 123700db7afdSDavid E. O'Brien complex<double>::operator-=(double __d) 123800db7afdSDavid E. O'Brien { 123900db7afdSDavid E. O'Brien __real__ _M_value -= __d; 124000db7afdSDavid E. O'Brien return *this; 124100db7afdSDavid E. O'Brien } 124200db7afdSDavid E. O'Brien 124300db7afdSDavid E. O'Brien inline complex<double>& 124400db7afdSDavid E. O'Brien complex<double>::operator*=(double __d) 124500db7afdSDavid E. O'Brien { 124600db7afdSDavid E. O'Brien _M_value *= __d; 124700db7afdSDavid E. O'Brien return *this; 124800db7afdSDavid E. O'Brien } 124900db7afdSDavid E. O'Brien 125000db7afdSDavid E. O'Brien inline complex<double>& 125100db7afdSDavid E. O'Brien complex<double>::operator/=(double __d) 125200db7afdSDavid E. O'Brien { 125300db7afdSDavid E. O'Brien _M_value /= __d; 125400db7afdSDavid E. O'Brien return *this; 125500db7afdSDavid E. O'Brien } 125600db7afdSDavid E. O'Brien 125700db7afdSDavid E. O'Brien template<typename _Tp> 125800db7afdSDavid E. O'Brien inline complex<double>& 125900db7afdSDavid E. O'Brien complex<double>::operator=(const complex<_Tp>& __z) 126000db7afdSDavid E. O'Brien { 126100db7afdSDavid E. O'Brien __real__ _M_value = __z.real(); 126200db7afdSDavid E. O'Brien __imag__ _M_value = __z.imag(); 126300db7afdSDavid E. O'Brien return *this; 126400db7afdSDavid E. O'Brien } 126500db7afdSDavid E. O'Brien 126600db7afdSDavid E. O'Brien template<typename _Tp> 126700db7afdSDavid E. O'Brien inline complex<double>& 126800db7afdSDavid E. O'Brien complex<double>::operator+=(const complex<_Tp>& __z) 126900db7afdSDavid E. O'Brien { 127000db7afdSDavid E. O'Brien __real__ _M_value += __z.real(); 127100db7afdSDavid E. O'Brien __imag__ _M_value += __z.imag(); 127200db7afdSDavid E. O'Brien return *this; 127300db7afdSDavid E. O'Brien } 127400db7afdSDavid E. O'Brien 127500db7afdSDavid E. O'Brien template<typename _Tp> 127600db7afdSDavid E. O'Brien inline complex<double>& 127700db7afdSDavid E. O'Brien complex<double>::operator-=(const complex<_Tp>& __z) 127800db7afdSDavid E. O'Brien { 127900db7afdSDavid E. O'Brien __real__ _M_value -= __z.real(); 128000db7afdSDavid E. O'Brien __imag__ _M_value -= __z.imag(); 128100db7afdSDavid E. O'Brien return *this; 128200db7afdSDavid E. O'Brien } 128300db7afdSDavid E. O'Brien 128400db7afdSDavid E. O'Brien template<typename _Tp> 128500db7afdSDavid E. O'Brien inline complex<double>& 128600db7afdSDavid E. O'Brien complex<double>::operator*=(const complex<_Tp>& __z) 128700db7afdSDavid E. O'Brien { 128800db7afdSDavid E. O'Brien _ComplexT __t; 128900db7afdSDavid E. O'Brien __real__ __t = __z.real(); 129000db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 129100db7afdSDavid E. O'Brien _M_value *= __t; 129200db7afdSDavid E. O'Brien return *this; 129300db7afdSDavid E. O'Brien } 129400db7afdSDavid E. O'Brien 129500db7afdSDavid E. O'Brien template<typename _Tp> 129600db7afdSDavid E. O'Brien inline complex<double>& 129700db7afdSDavid E. O'Brien complex<double>::operator/=(const complex<_Tp>& __z) 129800db7afdSDavid E. O'Brien { 129900db7afdSDavid E. O'Brien _ComplexT __t; 130000db7afdSDavid E. O'Brien __real__ __t = __z.real(); 130100db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 130200db7afdSDavid E. O'Brien _M_value /= __t; 130300db7afdSDavid E. O'Brien return *this; 130400db7afdSDavid E. O'Brien } 130500db7afdSDavid E. O'Brien 130600db7afdSDavid E. O'Brien // 26.2.3 complex specializations 130700db7afdSDavid E. O'Brien // complex<long double> specialization 1308*f8a1b7d9SAlexander Kabaev template<> 1309*f8a1b7d9SAlexander Kabaev struct complex<long double> 131000db7afdSDavid E. O'Brien { 131100db7afdSDavid E. O'Brien typedef long double value_type; 1312*f8a1b7d9SAlexander Kabaev typedef __complex__ long double _ComplexT; 1313*f8a1b7d9SAlexander Kabaev 1314*f8a1b7d9SAlexander Kabaev complex(_ComplexT __z) : _M_value(__z) { } 131500db7afdSDavid E. O'Brien 131600db7afdSDavid E. O'Brien complex(long double = 0.0L, long double = 0.0L); 1317f260e61bSAlexander Kabaev 131800db7afdSDavid E. O'Brien complex(const complex<float>&); 131900db7afdSDavid E. O'Brien complex(const complex<double>&); 132000db7afdSDavid E. O'Brien 1321ffeaf689SAlexander Kabaev long double& real(); 1322ffeaf689SAlexander Kabaev const long double& real() const; 1323ffeaf689SAlexander Kabaev long double& imag(); 1324ffeaf689SAlexander Kabaev const long double& imag() const; 132500db7afdSDavid E. O'Brien 132600db7afdSDavid E. O'Brien complex<long double>& operator= (long double); 132700db7afdSDavid E. O'Brien complex<long double>& operator+= (long double); 132800db7afdSDavid E. O'Brien complex<long double>& operator-= (long double); 132900db7afdSDavid E. O'Brien complex<long double>& operator*= (long double); 133000db7afdSDavid E. O'Brien complex<long double>& operator/= (long double); 133100db7afdSDavid E. O'Brien 133200db7afdSDavid E. O'Brien // The compiler knows how to do this efficiently 133300db7afdSDavid E. O'Brien // complex& operator= (const complex&); 133400db7afdSDavid E. O'Brien template<typename _Tp> 133500db7afdSDavid E. O'Brien complex<long double>& operator=(const complex<_Tp>&); 133600db7afdSDavid E. O'Brien template<typename _Tp> 133700db7afdSDavid E. O'Brien complex<long double>& operator+=(const complex<_Tp>&); 133800db7afdSDavid E. O'Brien template<typename _Tp> 133900db7afdSDavid E. O'Brien complex<long double>& operator-=(const complex<_Tp>&); 134000db7afdSDavid E. O'Brien template<typename _Tp> 134100db7afdSDavid E. O'Brien complex<long double>& operator*=(const complex<_Tp>&); 134200db7afdSDavid E. O'Brien template<typename _Tp> 134300db7afdSDavid E. O'Brien complex<long double>& operator/=(const complex<_Tp>&); 134400db7afdSDavid E. O'Brien 1345*f8a1b7d9SAlexander Kabaev const _ComplexT& __rep() const { return _M_value; } 1346*f8a1b7d9SAlexander Kabaev 134700db7afdSDavid E. O'Brien private: 134800db7afdSDavid E. O'Brien _ComplexT _M_value; 134900db7afdSDavid E. O'Brien }; 135000db7afdSDavid E. O'Brien 135100db7afdSDavid E. O'Brien inline 135200db7afdSDavid E. O'Brien complex<long double>::complex(long double __r, long double __i) 135300db7afdSDavid E. O'Brien { 135400db7afdSDavid E. O'Brien __real__ _M_value = __r; 135500db7afdSDavid E. O'Brien __imag__ _M_value = __i; 135600db7afdSDavid E. O'Brien } 135700db7afdSDavid E. O'Brien 1358ffeaf689SAlexander Kabaev inline long double& 1359ffeaf689SAlexander Kabaev complex<long double>::real() 1360ffeaf689SAlexander Kabaev { return __real__ _M_value; } 1361ffeaf689SAlexander Kabaev 1362ffeaf689SAlexander Kabaev inline const long double& 136300db7afdSDavid E. O'Brien complex<long double>::real() const 136400db7afdSDavid E. O'Brien { return __real__ _M_value; } 136500db7afdSDavid E. O'Brien 1366ffeaf689SAlexander Kabaev inline long double& 1367ffeaf689SAlexander Kabaev complex<long double>::imag() 1368ffeaf689SAlexander Kabaev { return __imag__ _M_value; } 1369ffeaf689SAlexander Kabaev 1370ffeaf689SAlexander Kabaev inline const long double& 137100db7afdSDavid E. O'Brien complex<long double>::imag() const 137200db7afdSDavid E. O'Brien { return __imag__ _M_value; } 137300db7afdSDavid E. O'Brien 137400db7afdSDavid E. O'Brien inline complex<long double>& 137500db7afdSDavid E. O'Brien complex<long double>::operator=(long double __r) 137600db7afdSDavid E. O'Brien { 137700db7afdSDavid E. O'Brien __real__ _M_value = __r; 137800db7afdSDavid E. O'Brien __imag__ _M_value = 0.0L; 137900db7afdSDavid E. O'Brien return *this; 138000db7afdSDavid E. O'Brien } 138100db7afdSDavid E. O'Brien 138200db7afdSDavid E. O'Brien inline complex<long double>& 138300db7afdSDavid E. O'Brien complex<long double>::operator+=(long double __r) 138400db7afdSDavid E. O'Brien { 138500db7afdSDavid E. O'Brien __real__ _M_value += __r; 138600db7afdSDavid E. O'Brien return *this; 138700db7afdSDavid E. O'Brien } 138800db7afdSDavid E. O'Brien 138900db7afdSDavid E. O'Brien inline complex<long double>& 139000db7afdSDavid E. O'Brien complex<long double>::operator-=(long double __r) 139100db7afdSDavid E. O'Brien { 139200db7afdSDavid E. O'Brien __real__ _M_value -= __r; 139300db7afdSDavid E. O'Brien return *this; 139400db7afdSDavid E. O'Brien } 139500db7afdSDavid E. O'Brien 139600db7afdSDavid E. O'Brien inline complex<long double>& 139700db7afdSDavid E. O'Brien complex<long double>::operator*=(long double __r) 139800db7afdSDavid E. O'Brien { 139900db7afdSDavid E. O'Brien _M_value *= __r; 140000db7afdSDavid E. O'Brien return *this; 140100db7afdSDavid E. O'Brien } 140200db7afdSDavid E. O'Brien 140300db7afdSDavid E. O'Brien inline complex<long double>& 140400db7afdSDavid E. O'Brien complex<long double>::operator/=(long double __r) 140500db7afdSDavid E. O'Brien { 140600db7afdSDavid E. O'Brien _M_value /= __r; 140700db7afdSDavid E. O'Brien return *this; 140800db7afdSDavid E. O'Brien } 140900db7afdSDavid E. O'Brien 141000db7afdSDavid E. O'Brien template<typename _Tp> 141100db7afdSDavid E. O'Brien inline complex<long double>& 141200db7afdSDavid E. O'Brien complex<long double>::operator=(const complex<_Tp>& __z) 141300db7afdSDavid E. O'Brien { 141400db7afdSDavid E. O'Brien __real__ _M_value = __z.real(); 141500db7afdSDavid E. O'Brien __imag__ _M_value = __z.imag(); 141600db7afdSDavid E. O'Brien return *this; 141700db7afdSDavid E. O'Brien } 141800db7afdSDavid E. O'Brien 141900db7afdSDavid E. O'Brien template<typename _Tp> 142000db7afdSDavid E. O'Brien inline complex<long double>& 142100db7afdSDavid E. O'Brien complex<long double>::operator+=(const complex<_Tp>& __z) 142200db7afdSDavid E. O'Brien { 142300db7afdSDavid E. O'Brien __real__ _M_value += __z.real(); 142400db7afdSDavid E. O'Brien __imag__ _M_value += __z.imag(); 142500db7afdSDavid E. O'Brien return *this; 142600db7afdSDavid E. O'Brien } 142700db7afdSDavid E. O'Brien 142800db7afdSDavid E. O'Brien template<typename _Tp> 142900db7afdSDavid E. O'Brien inline complex<long double>& 143000db7afdSDavid E. O'Brien complex<long double>::operator-=(const complex<_Tp>& __z) 143100db7afdSDavid E. O'Brien { 143200db7afdSDavid E. O'Brien __real__ _M_value -= __z.real(); 143300db7afdSDavid E. O'Brien __imag__ _M_value -= __z.imag(); 143400db7afdSDavid E. O'Brien return *this; 143500db7afdSDavid E. O'Brien } 143600db7afdSDavid E. O'Brien 143700db7afdSDavid E. O'Brien template<typename _Tp> 143800db7afdSDavid E. O'Brien inline complex<long double>& 143900db7afdSDavid E. O'Brien complex<long double>::operator*=(const complex<_Tp>& __z) 144000db7afdSDavid E. O'Brien { 144100db7afdSDavid E. O'Brien _ComplexT __t; 144200db7afdSDavid E. O'Brien __real__ __t = __z.real(); 144300db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 144400db7afdSDavid E. O'Brien _M_value *= __t; 144500db7afdSDavid E. O'Brien return *this; 144600db7afdSDavid E. O'Brien } 144700db7afdSDavid E. O'Brien 144800db7afdSDavid E. O'Brien template<typename _Tp> 144900db7afdSDavid E. O'Brien inline complex<long double>& 145000db7afdSDavid E. O'Brien complex<long double>::operator/=(const complex<_Tp>& __z) 145100db7afdSDavid E. O'Brien { 145200db7afdSDavid E. O'Brien _ComplexT __t; 145300db7afdSDavid E. O'Brien __real__ __t = __z.real(); 145400db7afdSDavid E. O'Brien __imag__ __t = __z.imag(); 145500db7afdSDavid E. O'Brien _M_value /= __t; 145600db7afdSDavid E. O'Brien return *this; 145700db7afdSDavid E. O'Brien } 145800db7afdSDavid E. O'Brien 145900db7afdSDavid E. O'Brien // These bits have to be at the end of this file, so that the 146000db7afdSDavid E. O'Brien // specializations have all been defined. 146100db7afdSDavid E. O'Brien // ??? No, they have to be there because of compiler limitation at 146200db7afdSDavid E. O'Brien // inlining. It suffices that class specializations be defined. 146300db7afdSDavid E. O'Brien inline 146400db7afdSDavid E. O'Brien complex<float>::complex(const complex<double>& __z) 1465*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 146600db7afdSDavid E. O'Brien 146700db7afdSDavid E. O'Brien inline 146800db7afdSDavid E. O'Brien complex<float>::complex(const complex<long double>& __z) 1469*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 147000db7afdSDavid E. O'Brien 147100db7afdSDavid E. O'Brien inline 147200db7afdSDavid E. O'Brien complex<double>::complex(const complex<float>& __z) 1473*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 147400db7afdSDavid E. O'Brien 147500db7afdSDavid E. O'Brien inline 147600db7afdSDavid E. O'Brien complex<double>::complex(const complex<long double>& __z) 1477*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 147800db7afdSDavid E. O'Brien 147900db7afdSDavid E. O'Brien inline 148000db7afdSDavid E. O'Brien complex<long double>::complex(const complex<float>& __z) 1481*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 148200db7afdSDavid E. O'Brien 148300db7afdSDavid E. O'Brien inline 148400db7afdSDavid E. O'Brien complex<long double>::complex(const complex<double>& __z) 1485*f8a1b7d9SAlexander Kabaev : _M_value(__z.__rep()) { } 1486*f8a1b7d9SAlexander Kabaev 1487*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE 148800db7afdSDavid E. O'Brien 1489ffeaf689SAlexander Kabaev #endif /* _GLIBCXX_COMPLEX */ 1490