197403Sobrien// The template and inlines for the -*- C++ -*- complex number classes. 297403Sobrien 3146897Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 497403Sobrien// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 31169691Skan/** @file complex 32169691Skan * This is a Standard C++ Library header. 33169691Skan */ 34169691Skan 3597403Sobrien// 3697403Sobrien// ISO C++ 14882: 26.2 Complex Numbers 3797403Sobrien// Note: this is not a conforming implementation. 3897403Sobrien// Initially implemented by Ulrich Drepper <drepper@cygnus.com> 3997403Sobrien// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 4097403Sobrien// 4197403Sobrien 42132720Skan#ifndef _GLIBCXX_COMPLEX 43132720Skan#define _GLIBCXX_COMPLEX 1 4497403Sobrien 4597403Sobrien#pragma GCC system_header 4697403Sobrien 4797403Sobrien#include <bits/c++config.h> 4897403Sobrien#include <bits/cpp_type_traits.h> 4997403Sobrien#include <cmath> 5097403Sobrien#include <sstream> 5197403Sobrien 52169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 53169691Skan 54169691Skan // Forward declarations. 5597403Sobrien template<typename _Tp> class complex; 5697403Sobrien template<> class complex<float>; 5797403Sobrien template<> class complex<double>; 5897403Sobrien template<> class complex<long double>; 5997403Sobrien 60132720Skan /// Return magnitude of @a z. 6197403Sobrien template<typename _Tp> _Tp abs(const complex<_Tp>&); 62132720Skan /// Return phase angle of @a z. 6397403Sobrien template<typename _Tp> _Tp arg(const complex<_Tp>&); 64132720Skan /// Return @a z magnitude squared. 6597403Sobrien template<typename _Tp> _Tp norm(const complex<_Tp>&); 6697403Sobrien 67132720Skan /// Return complex conjugate of @a z. 6897403Sobrien template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 69132720Skan /// Return complex with magnitude @a rho and angle @a theta. 7097403Sobrien template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); 7197403Sobrien 7297403Sobrien // Transcendentals: 73132720Skan /// Return complex cosine of @a z. 7497403Sobrien template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 75132720Skan /// Return complex hyperbolic cosine of @a z. 7697403Sobrien template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 77132720Skan /// Return complex base e exponential of @a z. 7897403Sobrien template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 79132720Skan /// Return complex natural logarithm of @a z. 8097403Sobrien template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 81132720Skan /// Return complex base 10 logarithm of @a z. 8297403Sobrien template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 83132720Skan /// Return complex cosine of @a z. 8497403Sobrien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 85132720Skan /// Return @a x to the @a y'th power. 8697403Sobrien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 87132720Skan /// Return @a x to the @a y'th power. 8897403Sobrien template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 89169691Skan const complex<_Tp>&); 90132720Skan /// Return @a x to the @a y'th power. 9197403Sobrien template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 92132720Skan /// Return complex sine of @a z. 9397403Sobrien template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 94132720Skan /// Return complex hyperbolic sine of @a z. 9597403Sobrien template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 96132720Skan /// Return complex square root of @a z. 9797403Sobrien template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 98132720Skan /// Return complex tangent of @a z. 9997403Sobrien template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 100132720Skan /// Return complex hyperbolic tangent of @a z. 10197403Sobrien template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 102132720Skan //@} 10397403Sobrien 10497403Sobrien 10597403Sobrien // 26.2.2 Primary template class complex 106132720Skan /** 107132720Skan * Template to represent complex numbers. 108132720Skan * 109132720Skan * Specializations for float, double, and long double are part of the 110132720Skan * library. Results with any other type are not guaranteed. 111132720Skan * 112132720Skan * @param Tp Type of real and imaginary values. 113132720Skan */ 11497403Sobrien template<typename _Tp> 115169691Skan struct complex 11697403Sobrien { 117132720Skan /// Value typedef. 11897403Sobrien typedef _Tp value_type; 11997403Sobrien 120132720Skan /// Default constructor. First parameter is x, second parameter is y. 121132720Skan /// Unspecified parameters default to 0. 12297403Sobrien complex(const _Tp& = _Tp(), const _Tp & = _Tp()); 12397403Sobrien 124132720Skan // Lets the compiler synthesize the copy constructor 12597403Sobrien // complex (const complex<_Tp>&); 126132720Skan /// Copy constructor. 12797403Sobrien template<typename _Up> 12897403Sobrien complex(const complex<_Up>&); 12997403Sobrien 130132720Skan /// Return real part of complex number. 131132720Skan _Tp& real(); 132132720Skan /// Return real part of complex number. 133132720Skan const _Tp& real() const; 134132720Skan /// Return imaginary part of complex number. 135132720Skan _Tp& imag(); 136132720Skan /// Return imaginary part of complex number. 137132720Skan const _Tp& imag() const; 138132720Skan 139132720Skan /// Assign this complex number to scalar @a t. 14097403Sobrien complex<_Tp>& operator=(const _Tp&); 141132720Skan /// Add @a t to this complex number. 14297403Sobrien complex<_Tp>& operator+=(const _Tp&); 143132720Skan /// Subtract @a t from this complex number. 14497403Sobrien complex<_Tp>& operator-=(const _Tp&); 145132720Skan /// Multiply this complex number by @a t. 14697403Sobrien complex<_Tp>& operator*=(const _Tp&); 147132720Skan /// Divide this complex number by @a t. 14897403Sobrien complex<_Tp>& operator/=(const _Tp&); 14997403Sobrien 150132720Skan // Lets the compiler synthesize the 15197403Sobrien // copy and assignment operator 15297403Sobrien // complex<_Tp>& operator= (const complex<_Tp>&); 153132720Skan /// Assign this complex number to complex @a z. 15497403Sobrien template<typename _Up> 15597403Sobrien complex<_Tp>& operator=(const complex<_Up>&); 156132720Skan /// Add @a z to this complex number. 15797403Sobrien template<typename _Up> 15897403Sobrien complex<_Tp>& operator+=(const complex<_Up>&); 159132720Skan /// Subtract @a z from this complex number. 16097403Sobrien template<typename _Up> 16197403Sobrien complex<_Tp>& operator-=(const complex<_Up>&); 162132720Skan /// Multiply this complex number by @a z. 16397403Sobrien template<typename _Up> 16497403Sobrien complex<_Tp>& operator*=(const complex<_Up>&); 165132720Skan /// Divide this complex number by @a z. 16697403Sobrien template<typename _Up> 16797403Sobrien complex<_Tp>& operator/=(const complex<_Up>&); 16897403Sobrien 169169691Skan const complex& __rep() const; 170169691Skan 17197403Sobrien private: 172132720Skan _Tp _M_real; 173132720Skan _Tp _M_imag; 17497403Sobrien }; 17597403Sobrien 17697403Sobrien template<typename _Tp> 177132720Skan inline _Tp& 178132720Skan complex<_Tp>::real() { return _M_real; } 179132720Skan 180132720Skan template<typename _Tp> 181132720Skan inline const _Tp& 18297403Sobrien complex<_Tp>::real() const { return _M_real; } 18397403Sobrien 18497403Sobrien template<typename _Tp> 185132720Skan inline _Tp& 186132720Skan complex<_Tp>::imag() { return _M_imag; } 187132720Skan 188132720Skan template<typename _Tp> 189132720Skan inline const _Tp& 19097403Sobrien complex<_Tp>::imag() const { return _M_imag; } 19197403Sobrien 19297403Sobrien template<typename _Tp> 19397403Sobrien inline 19497403Sobrien complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) 19597403Sobrien : _M_real(__r), _M_imag(__i) { } 19697403Sobrien 19797403Sobrien template<typename _Tp> 19897403Sobrien template<typename _Up> 19997403Sobrien inline 20097403Sobrien complex<_Tp>::complex(const complex<_Up>& __z) 20197403Sobrien : _M_real(__z.real()), _M_imag(__z.imag()) { } 20297403Sobrien 20397403Sobrien template<typename _Tp> 20497403Sobrien complex<_Tp>& 20597403Sobrien complex<_Tp>::operator=(const _Tp& __t) 20697403Sobrien { 20797403Sobrien _M_real = __t; 20897403Sobrien _M_imag = _Tp(); 20997403Sobrien return *this; 21097403Sobrien } 21197403Sobrien 21297403Sobrien // 26.2.5/1 21397403Sobrien template<typename _Tp> 21497403Sobrien inline complex<_Tp>& 21597403Sobrien complex<_Tp>::operator+=(const _Tp& __t) 21697403Sobrien { 21797403Sobrien _M_real += __t; 21897403Sobrien return *this; 21997403Sobrien } 22097403Sobrien 22197403Sobrien // 26.2.5/3 22297403Sobrien template<typename _Tp> 22397403Sobrien inline complex<_Tp>& 22497403Sobrien complex<_Tp>::operator-=(const _Tp& __t) 22597403Sobrien { 22697403Sobrien _M_real -= __t; 22797403Sobrien return *this; 22897403Sobrien } 22997403Sobrien 23097403Sobrien // 26.2.5/5 23197403Sobrien template<typename _Tp> 23297403Sobrien complex<_Tp>& 23397403Sobrien complex<_Tp>::operator*=(const _Tp& __t) 23497403Sobrien { 23597403Sobrien _M_real *= __t; 23697403Sobrien _M_imag *= __t; 23797403Sobrien return *this; 23897403Sobrien } 23997403Sobrien 24097403Sobrien // 26.2.5/7 24197403Sobrien template<typename _Tp> 24297403Sobrien complex<_Tp>& 24397403Sobrien complex<_Tp>::operator/=(const _Tp& __t) 24497403Sobrien { 24597403Sobrien _M_real /= __t; 24697403Sobrien _M_imag /= __t; 24797403Sobrien return *this; 24897403Sobrien } 24997403Sobrien 25097403Sobrien template<typename _Tp> 25197403Sobrien template<typename _Up> 25297403Sobrien complex<_Tp>& 25397403Sobrien complex<_Tp>::operator=(const complex<_Up>& __z) 25497403Sobrien { 25597403Sobrien _M_real = __z.real(); 25697403Sobrien _M_imag = __z.imag(); 25797403Sobrien return *this; 25897403Sobrien } 25997403Sobrien 26097403Sobrien // 26.2.5/9 26197403Sobrien template<typename _Tp> 26297403Sobrien template<typename _Up> 26397403Sobrien complex<_Tp>& 26497403Sobrien complex<_Tp>::operator+=(const complex<_Up>& __z) 26597403Sobrien { 26697403Sobrien _M_real += __z.real(); 26797403Sobrien _M_imag += __z.imag(); 26897403Sobrien return *this; 26997403Sobrien } 27097403Sobrien 27197403Sobrien // 26.2.5/11 27297403Sobrien template<typename _Tp> 27397403Sobrien template<typename _Up> 27497403Sobrien complex<_Tp>& 27597403Sobrien complex<_Tp>::operator-=(const complex<_Up>& __z) 27697403Sobrien { 27797403Sobrien _M_real -= __z.real(); 27897403Sobrien _M_imag -= __z.imag(); 27997403Sobrien return *this; 28097403Sobrien } 28197403Sobrien 28297403Sobrien // 26.2.5/13 28397403Sobrien // XXX: This is a grammar school implementation. 28497403Sobrien template<typename _Tp> 28597403Sobrien template<typename _Up> 28697403Sobrien complex<_Tp>& 28797403Sobrien complex<_Tp>::operator*=(const complex<_Up>& __z) 28897403Sobrien { 28997403Sobrien const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 29097403Sobrien _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 29197403Sobrien _M_real = __r; 29297403Sobrien return *this; 29397403Sobrien } 29497403Sobrien 29597403Sobrien // 26.2.5/15 29697403Sobrien // XXX: This is a grammar school implementation. 29797403Sobrien template<typename _Tp> 29897403Sobrien template<typename _Up> 29997403Sobrien complex<_Tp>& 30097403Sobrien complex<_Tp>::operator/=(const complex<_Up>& __z) 30197403Sobrien { 30297403Sobrien const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 303132720Skan const _Tp __n = std::norm(__z); 30497403Sobrien _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 30597403Sobrien _M_real = __r / __n; 30697403Sobrien return *this; 30797403Sobrien } 308169691Skan 309169691Skan template<typename _Tp> 310169691Skan inline const complex<_Tp>& 311169691Skan complex<_Tp>::__rep() const { return *this; } 31297403Sobrien 31397403Sobrien // Operators: 314132720Skan //@{ 315132720Skan /// Return new complex value @a x plus @a y. 31697403Sobrien template<typename _Tp> 31797403Sobrien inline complex<_Tp> 31897403Sobrien operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 319132720Skan { 320132720Skan complex<_Tp> __r = __x; 321132720Skan __r += __y; 322132720Skan return __r; 323132720Skan } 32497403Sobrien 32597403Sobrien template<typename _Tp> 32697403Sobrien inline complex<_Tp> 32797403Sobrien operator+(const complex<_Tp>& __x, const _Tp& __y) 328132720Skan { 329132720Skan complex<_Tp> __r = __x; 330132720Skan __r.real() += __y; 331132720Skan return __r; 332132720Skan } 33397403Sobrien 33497403Sobrien template<typename _Tp> 33597403Sobrien inline complex<_Tp> 33697403Sobrien operator+(const _Tp& __x, const complex<_Tp>& __y) 337132720Skan { 338132720Skan complex<_Tp> __r = __y; 339132720Skan __r.real() += __x; 340132720Skan return __r; 341132720Skan } 342132720Skan //@} 34397403Sobrien 344132720Skan //@{ 345132720Skan /// Return new complex value @a x minus @a y. 34697403Sobrien template<typename _Tp> 34797403Sobrien inline complex<_Tp> 34897403Sobrien operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 349132720Skan { 350132720Skan complex<_Tp> __r = __x; 351132720Skan __r -= __y; 352132720Skan return __r; 353132720Skan } 35497403Sobrien 35597403Sobrien template<typename _Tp> 35697403Sobrien inline complex<_Tp> 35797403Sobrien operator-(const complex<_Tp>& __x, const _Tp& __y) 358132720Skan { 359132720Skan complex<_Tp> __r = __x; 360132720Skan __r.real() -= __y; 361132720Skan return __r; 362132720Skan } 36397403Sobrien 36497403Sobrien template<typename _Tp> 36597403Sobrien inline complex<_Tp> 36697403Sobrien operator-(const _Tp& __x, const complex<_Tp>& __y) 367132720Skan { 368132720Skan complex<_Tp> __r(__x, -__y.imag()); 369132720Skan __r.real() -= __y.real(); 370132720Skan return __r; 371132720Skan } 372132720Skan //@} 37397403Sobrien 374132720Skan //@{ 375132720Skan /// Return new complex value @a x times @a y. 37697403Sobrien template<typename _Tp> 37797403Sobrien inline complex<_Tp> 37897403Sobrien operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 379132720Skan { 380132720Skan complex<_Tp> __r = __x; 381132720Skan __r *= __y; 382132720Skan return __r; 383132720Skan } 38497403Sobrien 38597403Sobrien template<typename _Tp> 38697403Sobrien inline complex<_Tp> 38797403Sobrien operator*(const complex<_Tp>& __x, const _Tp& __y) 388132720Skan { 389132720Skan complex<_Tp> __r = __x; 390132720Skan __r *= __y; 391132720Skan return __r; 392132720Skan } 39397403Sobrien 39497403Sobrien template<typename _Tp> 39597403Sobrien inline complex<_Tp> 39697403Sobrien operator*(const _Tp& __x, const complex<_Tp>& __y) 397132720Skan { 398132720Skan complex<_Tp> __r = __y; 399132720Skan __r *= __x; 400132720Skan return __r; 401132720Skan } 402132720Skan //@} 40397403Sobrien 404132720Skan //@{ 405132720Skan /// Return new complex value @a x divided by @a y. 40697403Sobrien template<typename _Tp> 40797403Sobrien inline complex<_Tp> 40897403Sobrien operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 409132720Skan { 410132720Skan complex<_Tp> __r = __x; 411132720Skan __r /= __y; 412132720Skan return __r; 413132720Skan } 41497403Sobrien 41597403Sobrien template<typename _Tp> 41697403Sobrien inline complex<_Tp> 41797403Sobrien operator/(const complex<_Tp>& __x, const _Tp& __y) 418132720Skan { 419132720Skan complex<_Tp> __r = __x; 420132720Skan __r /= __y; 421132720Skan return __r; 422132720Skan } 42397403Sobrien 42497403Sobrien template<typename _Tp> 42597403Sobrien inline complex<_Tp> 42697403Sobrien operator/(const _Tp& __x, const complex<_Tp>& __y) 427132720Skan { 428132720Skan complex<_Tp> __r = __x; 429132720Skan __r /= __y; 430132720Skan return __r; 431132720Skan } 432132720Skan //@} 43397403Sobrien 434132720Skan /// Return @a x. 43597403Sobrien template<typename _Tp> 43697403Sobrien inline complex<_Tp> 43797403Sobrien operator+(const complex<_Tp>& __x) 43897403Sobrien { return __x; } 43997403Sobrien 440132720Skan /// Return complex negation of @a x. 44197403Sobrien template<typename _Tp> 44297403Sobrien inline complex<_Tp> 44397403Sobrien operator-(const complex<_Tp>& __x) 44497403Sobrien { return complex<_Tp>(-__x.real(), -__x.imag()); } 44597403Sobrien 446132720Skan //@{ 447132720Skan /// Return true if @a x is equal to @a y. 44897403Sobrien template<typename _Tp> 44997403Sobrien inline bool 45097403Sobrien operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 45197403Sobrien { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 45297403Sobrien 45397403Sobrien template<typename _Tp> 45497403Sobrien inline bool 45597403Sobrien operator==(const complex<_Tp>& __x, const _Tp& __y) 45697403Sobrien { return __x.real() == __y && __x.imag() == _Tp(); } 45797403Sobrien 45897403Sobrien template<typename _Tp> 45997403Sobrien inline bool 46097403Sobrien operator==(const _Tp& __x, const complex<_Tp>& __y) 46197403Sobrien { return __x == __y.real() && _Tp() == __y.imag(); } 462132720Skan //@} 46397403Sobrien 464132720Skan //@{ 465132720Skan /// Return false if @a x is equal to @a y. 46697403Sobrien template<typename _Tp> 46797403Sobrien inline bool 46897403Sobrien operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 46997403Sobrien { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 47097403Sobrien 47197403Sobrien template<typename _Tp> 47297403Sobrien inline bool 47397403Sobrien operator!=(const complex<_Tp>& __x, const _Tp& __y) 47497403Sobrien { return __x.real() != __y || __x.imag() != _Tp(); } 47597403Sobrien 47697403Sobrien template<typename _Tp> 47797403Sobrien inline bool 47897403Sobrien operator!=(const _Tp& __x, const complex<_Tp>& __y) 47997403Sobrien { return __x != __y.real() || _Tp() != __y.imag(); } 480132720Skan //@} 48197403Sobrien 482132720Skan /// Extraction operator for complex values. 48397403Sobrien template<typename _Tp, typename _CharT, class _Traits> 48497403Sobrien basic_istream<_CharT, _Traits>& 48597403Sobrien operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 48697403Sobrien { 48797403Sobrien _Tp __re_x, __im_x; 48897403Sobrien _CharT __ch; 48997403Sobrien __is >> __ch; 49097403Sobrien if (__ch == '(') 49197403Sobrien { 49297403Sobrien __is >> __re_x >> __ch; 49397403Sobrien if (__ch == ',') 49497403Sobrien { 49597403Sobrien __is >> __im_x >> __ch; 49697403Sobrien if (__ch == ')') 49797403Sobrien __x = complex<_Tp>(__re_x, __im_x); 49897403Sobrien else 49997403Sobrien __is.setstate(ios_base::failbit); 50097403Sobrien } 50197403Sobrien else if (__ch == ')') 502132720Skan __x = __re_x; 50397403Sobrien else 50497403Sobrien __is.setstate(ios_base::failbit); 50597403Sobrien } 50697403Sobrien else 50797403Sobrien { 50897403Sobrien __is.putback(__ch); 50997403Sobrien __is >> __re_x; 510132720Skan __x = __re_x; 51197403Sobrien } 51297403Sobrien return __is; 51397403Sobrien } 51497403Sobrien 515132720Skan /// Insertion operator for complex values. 51697403Sobrien template<typename _Tp, typename _CharT, class _Traits> 51797403Sobrien basic_ostream<_CharT, _Traits>& 51897403Sobrien operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 51997403Sobrien { 52097403Sobrien basic_ostringstream<_CharT, _Traits> __s; 52197403Sobrien __s.flags(__os.flags()); 52297403Sobrien __s.imbue(__os.getloc()); 52397403Sobrien __s.precision(__os.precision()); 524117397Skan __s << '(' << __x.real() << ',' << __x.imag() << ')'; 52597403Sobrien return __os << __s.str(); 52697403Sobrien } 52797403Sobrien 52897403Sobrien // Values 52997403Sobrien template<typename _Tp> 530132720Skan inline _Tp& 531132720Skan real(complex<_Tp>& __z) 532132720Skan { return __z.real(); } 533132720Skan 534132720Skan template<typename _Tp> 535132720Skan inline const _Tp& 53697403Sobrien real(const complex<_Tp>& __z) 53797403Sobrien { return __z.real(); } 53897403Sobrien 53997403Sobrien template<typename _Tp> 540132720Skan inline _Tp& 541132720Skan imag(complex<_Tp>& __z) 542132720Skan { return __z.imag(); } 543132720Skan 544132720Skan template<typename _Tp> 545132720Skan inline const _Tp& 54697403Sobrien imag(const complex<_Tp>& __z) 54797403Sobrien { return __z.imag(); } 54897403Sobrien 549169691Skan // 26.2.7/3 abs(__z): Returns the magnitude of __z. 55097403Sobrien template<typename _Tp> 55197403Sobrien inline _Tp 552169691Skan __complex_abs(const complex<_Tp>& __z) 55397403Sobrien { 55497403Sobrien _Tp __x = __z.real(); 55597403Sobrien _Tp __y = __z.imag(); 556132720Skan const _Tp __s = std::max(abs(__x), abs(__y)); 55797403Sobrien if (__s == _Tp()) // well ... 55897403Sobrien return __s; 55997403Sobrien __x /= __s; 56097403Sobrien __y /= __s; 56197403Sobrien return __s * sqrt(__x * __x + __y * __y); 56297403Sobrien } 56397403Sobrien 564169691Skan#if _GLIBCXX_USE_C99_COMPLEX 565169691Skan inline float 566169691Skan __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); } 567169691Skan 568169691Skan inline double 569169691Skan __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); } 570169691Skan 571169691Skan inline long double 572169691Skan __complex_abs(const __complex__ long double& __z) 573169691Skan { return __builtin_cabsl(__z); } 574169691Skan 57597403Sobrien template<typename _Tp> 57697403Sobrien inline _Tp 577169691Skan abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } 578169691Skan#else 579169691Skan template<typename _Tp> 580169691Skan inline _Tp 581169691Skan abs(const complex<_Tp>& __z) { return __complex_abs(__z); } 582169691Skan#endif 58397403Sobrien 584169691Skan 585169691Skan // 26.2.7/4: arg(__z): Returns the phase angle of __z. 586169691Skan template<typename _Tp> 587169691Skan inline _Tp 588169691Skan __complex_arg(const complex<_Tp>& __z) 589169691Skan { return atan2(__z.imag(), __z.real()); } 590169691Skan 591169691Skan#if _GLIBCXX_USE_C99_COMPLEX 592169691Skan inline float 593169691Skan __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } 594169691Skan 595169691Skan inline double 596169691Skan __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } 597169691Skan 598169691Skan inline long double 599169691Skan __complex_arg(const __complex__ long double& __z) 600169691Skan { return __builtin_cargl(__z); } 601169691Skan 602169691Skan template<typename _Tp> 603169691Skan inline _Tp 604169691Skan arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } 605169691Skan#else 606169691Skan template<typename _Tp> 607169691Skan inline _Tp 608169691Skan arg(const complex<_Tp>& __z) { return __complex_arg(__z); } 609169691Skan#endif 610169691Skan 61197403Sobrien // 26.2.7/5: norm(__z) returns the squared magintude of __z. 61297403Sobrien // As defined, norm() is -not- a norm is the common mathematical 61397403Sobrien // sens used in numerics. The helper class _Norm_helper<> tries to 61497403Sobrien // distinguish between builtin floating point and the rest, so as 61597403Sobrien // to deliver an answer as close as possible to the real value. 61697403Sobrien template<bool> 61797403Sobrien struct _Norm_helper 61897403Sobrien { 61997403Sobrien template<typename _Tp> 62097403Sobrien static inline _Tp _S_do_it(const complex<_Tp>& __z) 62197403Sobrien { 62297403Sobrien const _Tp __x = __z.real(); 62397403Sobrien const _Tp __y = __z.imag(); 62497403Sobrien return __x * __x + __y * __y; 62597403Sobrien } 62697403Sobrien }; 62797403Sobrien 62897403Sobrien template<> 62997403Sobrien struct _Norm_helper<true> 63097403Sobrien { 63197403Sobrien template<typename _Tp> 63297403Sobrien static inline _Tp _S_do_it(const complex<_Tp>& __z) 63397403Sobrien { 634132720Skan _Tp __res = std::abs(__z); 63597403Sobrien return __res * __res; 63697403Sobrien } 63797403Sobrien }; 63897403Sobrien 63997403Sobrien template<typename _Tp> 64097403Sobrien inline _Tp 64197403Sobrien norm(const complex<_Tp>& __z) 64297403Sobrien { 643169691Skan return _Norm_helper<__is_floating<_Tp>::__value 644169691Skan && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); 64597403Sobrien } 64697403Sobrien 64797403Sobrien template<typename _Tp> 64897403Sobrien inline complex<_Tp> 64997403Sobrien polar(const _Tp& __rho, const _Tp& __theta) 65097403Sobrien { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 65197403Sobrien 65297403Sobrien template<typename _Tp> 65397403Sobrien inline complex<_Tp> 65497403Sobrien conj(const complex<_Tp>& __z) 65597403Sobrien { return complex<_Tp>(__z.real(), -__z.imag()); } 65697403Sobrien 65797403Sobrien // Transcendentals 658169691Skan 659169691Skan // 26.2.8/1 cos(__z): Returns the cosine of __z. 66097403Sobrien template<typename _Tp> 66197403Sobrien inline complex<_Tp> 662169691Skan __complex_cos(const complex<_Tp>& __z) 66397403Sobrien { 66497403Sobrien const _Tp __x = __z.real(); 66597403Sobrien const _Tp __y = __z.imag(); 66697403Sobrien return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 66797403Sobrien } 66897403Sobrien 669169691Skan#if _GLIBCXX_USE_C99_COMPLEX 670169691Skan inline __complex__ float 671169691Skan __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } 672169691Skan 673169691Skan inline __complex__ double 674169691Skan __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } 675169691Skan 676169691Skan inline __complex__ long double 677169691Skan __complex_cos(const __complex__ long double& __z) 678169691Skan { return __builtin_ccosl(__z); } 679169691Skan 68097403Sobrien template<typename _Tp> 68197403Sobrien inline complex<_Tp> 682169691Skan cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } 683169691Skan#else 684169691Skan template<typename _Tp> 685169691Skan inline complex<_Tp> 686169691Skan cos(const complex<_Tp>& __z) { return __complex_cos(__z); } 687169691Skan#endif 688169691Skan 689169691Skan // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. 690169691Skan template<typename _Tp> 691169691Skan inline complex<_Tp> 692169691Skan __complex_cosh(const complex<_Tp>& __z) 69397403Sobrien { 69497403Sobrien const _Tp __x = __z.real(); 69597403Sobrien const _Tp __y = __z.imag(); 69697403Sobrien return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 69797403Sobrien } 69897403Sobrien 699169691Skan#if _GLIBCXX_USE_C99_COMPLEX 700169691Skan inline __complex__ float 701169691Skan __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } 702169691Skan 703169691Skan inline __complex__ double 704169691Skan __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } 705169691Skan 706169691Skan inline __complex__ long double 707169691Skan __complex_cosh(const __complex__ long double& __z) 708169691Skan { return __builtin_ccoshl(__z); } 709169691Skan 71097403Sobrien template<typename _Tp> 71197403Sobrien inline complex<_Tp> 712169691Skan cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } 713169691Skan#else 714169691Skan template<typename _Tp> 715169691Skan inline complex<_Tp> 716169691Skan cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } 717169691Skan#endif 718169691Skan 719169691Skan // 26.2.8/3 exp(__z): Returns the complex base e exponential of x 720169691Skan template<typename _Tp> 721169691Skan inline complex<_Tp> 722169691Skan __complex_exp(const complex<_Tp>& __z) 723132720Skan { return std::polar(exp(__z.real()), __z.imag()); } 72497403Sobrien 725169691Skan#if _GLIBCXX_USE_C99_COMPLEX 726169691Skan inline __complex__ float 727169691Skan __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } 728169691Skan 729169691Skan inline __complex__ double 730169691Skan __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } 731169691Skan 732169691Skan inline __complex__ long double 733169691Skan __complex_exp(const __complex__ long double& __z) 734169691Skan { return __builtin_cexpl(__z); } 735169691Skan 73697403Sobrien template<typename _Tp> 73797403Sobrien inline complex<_Tp> 738169691Skan exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } 739169691Skan#else 740169691Skan template<typename _Tp> 741169691Skan inline complex<_Tp> 742169691Skan exp(const complex<_Tp>& __z) { return __complex_exp(__z); } 743169691Skan#endif 744169691Skan 745169691Skan // 26.2.8/5 log(__z): Reurns the natural complex logaritm of __z. 746169691Skan // The branch cut is along the negative axis. 747169691Skan template<typename _Tp> 748169691Skan inline complex<_Tp> 749169691Skan __complex_log(const complex<_Tp>& __z) 750132720Skan { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } 75197403Sobrien 752169691Skan#if _GLIBCXX_USE_C99_COMPLEX 753169691Skan inline __complex__ float 754169691Skan __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } 755169691Skan 756169691Skan inline __complex__ double 757169691Skan __complex_log(__complex__ double __z) { return __builtin_clog(__z); } 758169691Skan 759169691Skan inline __complex__ long double 760169691Skan __complex_log(const __complex__ long double& __z) 761169691Skan { return __builtin_clogl(__z); } 762169691Skan 76397403Sobrien template<typename _Tp> 76497403Sobrien inline complex<_Tp> 765169691Skan log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } 766169691Skan#else 767169691Skan template<typename _Tp> 768169691Skan inline complex<_Tp> 769169691Skan log(const complex<_Tp>& __z) { return __complex_log(__z); } 770169691Skan#endif 771169691Skan 772169691Skan template<typename _Tp> 773169691Skan inline complex<_Tp> 77497403Sobrien log10(const complex<_Tp>& __z) 775132720Skan { return std::log(__z) / log(_Tp(10.0)); } 77697403Sobrien 777169691Skan // 26.2.8/10 sin(__z): Returns the sine of __z. 77897403Sobrien template<typename _Tp> 77997403Sobrien inline complex<_Tp> 780169691Skan __complex_sin(const complex<_Tp>& __z) 78197403Sobrien { 78297403Sobrien const _Tp __x = __z.real(); 78397403Sobrien const _Tp __y = __z.imag(); 78497403Sobrien return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 78597403Sobrien } 78697403Sobrien 787169691Skan#if _GLIBCXX_USE_C99_COMPLEX 788169691Skan inline __complex__ float 789169691Skan __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } 790169691Skan 791169691Skan inline __complex__ double 792169691Skan __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } 793169691Skan 794169691Skan inline __complex__ long double 795169691Skan __complex_sin(const __complex__ long double& __z) 796169691Skan { return __builtin_csinl(__z); } 797169691Skan 79897403Sobrien template<typename _Tp> 79997403Sobrien inline complex<_Tp> 800169691Skan sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } 801169691Skan#else 802169691Skan template<typename _Tp> 803169691Skan inline complex<_Tp> 804169691Skan sin(const complex<_Tp>& __z) { return __complex_sin(__z); } 805169691Skan#endif 806169691Skan 807169691Skan // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. 808169691Skan template<typename _Tp> 809169691Skan inline complex<_Tp> 810169691Skan __complex_sinh(const complex<_Tp>& __z) 81197403Sobrien { 81297403Sobrien const _Tp __x = __z.real(); 81397403Sobrien const _Tp __y = __z.imag(); 81497403Sobrien return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 81597403Sobrien } 81697403Sobrien 817169691Skan#if _GLIBCXX_USE_C99_COMPLEX 818169691Skan inline __complex__ float 819169691Skan __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } 820169691Skan 821169691Skan inline __complex__ double 822169691Skan __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } 823169691Skan 824169691Skan inline __complex__ long double 825169691Skan __complex_sinh(const __complex__ long double& __z) 826169691Skan { return __builtin_csinhl(__z); } 827169691Skan 82897403Sobrien template<typename _Tp> 829169691Skan inline complex<_Tp> 830169691Skan sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } 831169691Skan#else 832169691Skan template<typename _Tp> 833169691Skan inline complex<_Tp> 834169691Skan sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } 835169691Skan#endif 836169691Skan 837169691Skan // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. 838169691Skan // The branch cut is on the negative axis. 839169691Skan template<typename _Tp> 84097403Sobrien complex<_Tp> 841169691Skan __complex_sqrt(const complex<_Tp>& __z) 84297403Sobrien { 84397403Sobrien _Tp __x = __z.real(); 84497403Sobrien _Tp __y = __z.imag(); 84597403Sobrien 84697403Sobrien if (__x == _Tp()) 84797403Sobrien { 84897403Sobrien _Tp __t = sqrt(abs(__y) / 2); 84997403Sobrien return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 85097403Sobrien } 85197403Sobrien else 85297403Sobrien { 853132720Skan _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); 85497403Sobrien _Tp __u = __t / 2; 85597403Sobrien return __x > _Tp() 85697403Sobrien ? complex<_Tp>(__u, __y / __t) 85797403Sobrien : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 85897403Sobrien } 85997403Sobrien } 86097403Sobrien 861169691Skan#if _GLIBCXX_USE_C99_COMPLEX 862169691Skan inline __complex__ float 863169691Skan __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } 864169691Skan 865169691Skan inline __complex__ double 866169691Skan __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } 867169691Skan 868169691Skan inline __complex__ long double 869169691Skan __complex_sqrt(const __complex__ long double& __z) 870169691Skan { return __builtin_csqrtl(__z); } 871169691Skan 87297403Sobrien template<typename _Tp> 87397403Sobrien inline complex<_Tp> 874169691Skan sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } 875169691Skan#else 876169691Skan template<typename _Tp> 877169691Skan inline complex<_Tp> 878169691Skan sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } 879169691Skan#endif 88097403Sobrien 881169691Skan // 26.2.8/14 tan(__z): Return the complex tangent of __z. 882169691Skan 88397403Sobrien template<typename _Tp> 88497403Sobrien inline complex<_Tp> 885169691Skan __complex_tan(const complex<_Tp>& __z) 886169691Skan { return std::sin(__z) / std::cos(__z); } 88797403Sobrien 888169691Skan#if _GLIBCXX_USE_C99_COMPLEX 889169691Skan inline __complex__ float 890169691Skan __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } 891169691Skan 892169691Skan inline __complex__ double 893169691Skan __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } 894169691Skan 895169691Skan inline __complex__ long double 896169691Skan __complex_tan(const __complex__ long double& __z) 897169691Skan { return __builtin_ctanl(__z); } 898169691Skan 89997403Sobrien template<typename _Tp> 90097403Sobrien inline complex<_Tp> 901169691Skan tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } 902169691Skan#else 903169691Skan template<typename _Tp> 904169691Skan inline complex<_Tp> 905169691Skan tan(const complex<_Tp>& __z) { return __complex_tan(__z); } 906169691Skan#endif 907169691Skan 908169691Skan 909169691Skan // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. 910169691Skan 911169691Skan template<typename _Tp> 912169691Skan inline complex<_Tp> 913169691Skan __complex_tanh(const complex<_Tp>& __z) 914169691Skan { return std::sinh(__z) / std::cosh(__z); } 915169691Skan 916169691Skan#if _GLIBCXX_USE_C99_COMPLEX 917169691Skan inline __complex__ float 918169691Skan __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } 919169691Skan 920169691Skan inline __complex__ double 921169691Skan __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } 922169691Skan 923169691Skan inline __complex__ long double 924169691Skan __complex_tanh(const __complex__ long double& __z) 925169691Skan { return __builtin_ctanhl(__z); } 926169691Skan 927169691Skan template<typename _Tp> 928169691Skan inline complex<_Tp> 929169691Skan tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } 930169691Skan#else 931169691Skan template<typename _Tp> 932169691Skan inline complex<_Tp> 933169691Skan tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } 934169691Skan#endif 935169691Skan 936169691Skan 937169691Skan // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x 938169691Skan // raised to the __y-th power. The branch 939169691Skan // cut is on the negative axis. 940169691Skan template<typename _Tp> 941169691Skan inline complex<_Tp> 94297403Sobrien pow(const complex<_Tp>& __z, int __n) 943169691Skan { return std::__pow_helper(__z, __n); } 94497403Sobrien 94597403Sobrien template<typename _Tp> 946117397Skan complex<_Tp> 94797403Sobrien pow(const complex<_Tp>& __x, const _Tp& __y) 94897403Sobrien { 949169691Skan#ifndef _GLIBCXX_USE_C99_COMPLEX 950169691Skan if (__x == _Tp()) 951169691Skan return _Tp(); 952169691Skan#endif 953132720Skan if (__x.imag() == _Tp() && __x.real() > _Tp()) 954117397Skan return pow(__x.real(), __y); 955117397Skan 956132720Skan complex<_Tp> __t = std::log(__x); 957132720Skan return std::polar(exp(__y * __t.real()), __y * __t.imag()); 95897403Sobrien } 95997403Sobrien 96097403Sobrien template<typename _Tp> 96197403Sobrien inline complex<_Tp> 962169691Skan __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 963169691Skan { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } 964169691Skan 965169691Skan#if _GLIBCXX_USE_C99_COMPLEX 966169691Skan inline __complex__ float 967169691Skan __complex_pow(__complex__ float __x, __complex__ float __y) 968169691Skan { return __builtin_cpowf(__x, __y); } 969169691Skan 970169691Skan inline __complex__ double 971169691Skan __complex_pow(__complex__ double __x, __complex__ double __y) 972169691Skan { return __builtin_cpow(__x, __y); } 973169691Skan 974169691Skan inline __complex__ long double 975169691Skan __complex_pow(const __complex__ long double& __x, 976169691Skan const __complex__ long double& __y) 977169691Skan { return __builtin_cpowl(__x, __y); } 978169691Skan 979169691Skan template<typename _Tp> 980169691Skan inline complex<_Tp> 98197403Sobrien pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 982169691Skan { return __complex_pow(__x.__rep(), __y.__rep()); } 983169691Skan#else 984169691Skan template<typename _Tp> 985169691Skan inline complex<_Tp> 986169691Skan pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 987169691Skan { return __complex_pow(__x, __y); } 988169691Skan#endif 98997403Sobrien 99097403Sobrien template<typename _Tp> 99197403Sobrien inline complex<_Tp> 99297403Sobrien pow(const _Tp& __x, const complex<_Tp>& __y) 99397403Sobrien { 994132720Skan return __x > _Tp() ? std::polar(pow(__x, __y.real()), 995132720Skan __y.imag() * log(__x)) 996132720Skan : std::pow(complex<_Tp>(__x, _Tp()), __y); 99797403Sobrien } 99897403Sobrien 99997403Sobrien // 26.2.3 complex specializations 100097403Sobrien // complex<float> specialization 1001169691Skan template<> 1002169691Skan struct complex<float> 1003169691Skan { 1004169691Skan typedef float value_type; 1005169691Skan typedef __complex__ float _ComplexT; 1006146897Skan 1007169691Skan complex(_ComplexT __z) : _M_value(__z) { } 100897403Sobrien 1009169691Skan complex(float = 0.0f, float = 0.0f); 101097403Sobrien 1011169691Skan explicit complex(const complex<double>&); 1012169691Skan explicit complex(const complex<long double>&); 101397403Sobrien 1014169691Skan float& real(); 1015169691Skan const float& real() const; 1016169691Skan float& imag(); 1017169691Skan const float& imag() const; 101897403Sobrien 1019169691Skan complex<float>& operator=(float); 1020169691Skan complex<float>& operator+=(float); 1021169691Skan complex<float>& operator-=(float); 1022169691Skan complex<float>& operator*=(float); 1023169691Skan complex<float>& operator/=(float); 102497403Sobrien 1025169691Skan // Let's the compiler synthetize the copy and assignment 1026169691Skan // operator. It always does a pretty good job. 1027169691Skan // complex& operator= (const complex&); 1028169691Skan template<typename _Tp> 1029169691Skan complex<float>&operator=(const complex<_Tp>&); 1030169691Skan template<typename _Tp> 1031169691Skan complex<float>& operator+=(const complex<_Tp>&); 1032169691Skan template<class _Tp> 1033169691Skan complex<float>& operator-=(const complex<_Tp>&); 1034169691Skan template<class _Tp> 1035169691Skan complex<float>& operator*=(const complex<_Tp>&); 1036169691Skan template<class _Tp> 1037169691Skan complex<float>&operator/=(const complex<_Tp>&); 1038169691Skan 1039169691Skan const _ComplexT& __rep() const { return _M_value; } 1040169691Skan 1041169691Skan private: 1042169691Skan _ComplexT _M_value; 1043169691Skan }; 1044169691Skan 1045132720Skan inline float& 1046132720Skan complex<float>::real() 1047132720Skan { return __real__ _M_value; } 1048132720Skan 1049132720Skan inline const float& 105097403Sobrien complex<float>::real() const 105197403Sobrien { return __real__ _M_value; } 105297403Sobrien 1053132720Skan inline float& 1054132720Skan complex<float>::imag() 1055132720Skan { return __imag__ _M_value; } 1056132720Skan 1057132720Skan inline const float& 105897403Sobrien complex<float>::imag() const 105997403Sobrien { return __imag__ _M_value; } 106097403Sobrien 106197403Sobrien inline 106297403Sobrien complex<float>::complex(float r, float i) 106397403Sobrien { 106497403Sobrien __real__ _M_value = r; 106597403Sobrien __imag__ _M_value = i; 106697403Sobrien } 106797403Sobrien 106897403Sobrien inline complex<float>& 106997403Sobrien complex<float>::operator=(float __f) 107097403Sobrien { 107197403Sobrien __real__ _M_value = __f; 107297403Sobrien __imag__ _M_value = 0.0f; 107397403Sobrien return *this; 107497403Sobrien } 107597403Sobrien 107697403Sobrien inline complex<float>& 107797403Sobrien complex<float>::operator+=(float __f) 107897403Sobrien { 107997403Sobrien __real__ _M_value += __f; 108097403Sobrien return *this; 108197403Sobrien } 108297403Sobrien 108397403Sobrien inline complex<float>& 108497403Sobrien complex<float>::operator-=(float __f) 108597403Sobrien { 108697403Sobrien __real__ _M_value -= __f; 108797403Sobrien return *this; 108897403Sobrien } 108997403Sobrien 109097403Sobrien inline complex<float>& 109197403Sobrien complex<float>::operator*=(float __f) 109297403Sobrien { 109397403Sobrien _M_value *= __f; 109497403Sobrien return *this; 109597403Sobrien } 109697403Sobrien 109797403Sobrien inline complex<float>& 109897403Sobrien complex<float>::operator/=(float __f) 109997403Sobrien { 110097403Sobrien _M_value /= __f; 110197403Sobrien return *this; 110297403Sobrien } 110397403Sobrien 110497403Sobrien template<typename _Tp> 110597403Sobrien inline complex<float>& 110697403Sobrien complex<float>::operator=(const complex<_Tp>& __z) 110797403Sobrien { 110897403Sobrien __real__ _M_value = __z.real(); 110997403Sobrien __imag__ _M_value = __z.imag(); 111097403Sobrien return *this; 111197403Sobrien } 111297403Sobrien 111397403Sobrien template<typename _Tp> 111497403Sobrien inline complex<float>& 111597403Sobrien complex<float>::operator+=(const complex<_Tp>& __z) 111697403Sobrien { 111797403Sobrien __real__ _M_value += __z.real(); 111897403Sobrien __imag__ _M_value += __z.imag(); 111997403Sobrien return *this; 112097403Sobrien } 112197403Sobrien 112297403Sobrien template<typename _Tp> 112397403Sobrien inline complex<float>& 112497403Sobrien complex<float>::operator-=(const complex<_Tp>& __z) 112597403Sobrien { 112697403Sobrien __real__ _M_value -= __z.real(); 112797403Sobrien __imag__ _M_value -= __z.imag(); 112897403Sobrien return *this; 112997403Sobrien } 113097403Sobrien 113197403Sobrien template<typename _Tp> 113297403Sobrien inline complex<float>& 113397403Sobrien complex<float>::operator*=(const complex<_Tp>& __z) 113497403Sobrien { 113597403Sobrien _ComplexT __t; 113697403Sobrien __real__ __t = __z.real(); 113797403Sobrien __imag__ __t = __z.imag(); 113897403Sobrien _M_value *= __t; 113997403Sobrien return *this; 114097403Sobrien } 114197403Sobrien 114297403Sobrien template<typename _Tp> 114397403Sobrien inline complex<float>& 114497403Sobrien complex<float>::operator/=(const complex<_Tp>& __z) 114597403Sobrien { 114697403Sobrien _ComplexT __t; 114797403Sobrien __real__ __t = __z.real(); 114897403Sobrien __imag__ __t = __z.imag(); 114997403Sobrien _M_value /= __t; 115097403Sobrien return *this; 115197403Sobrien } 115297403Sobrien 115397403Sobrien // 26.2.3 complex specializations 115497403Sobrien // complex<double> specialization 1155169691Skan template<> 1156169691Skan struct complex<double> 1157169691Skan { 1158169691Skan typedef double value_type; 1159169691Skan typedef __complex__ double _ComplexT; 116097403Sobrien 1161169691Skan complex(_ComplexT __z) : _M_value(__z) { } 1162146897Skan 1163169691Skan complex(double = 0.0, double = 0.0); 1164132720Skan 1165169691Skan complex(const complex<float>&); 1166169691Skan explicit complex(const complex<long double>&); 116797403Sobrien 1168169691Skan double& real(); 1169169691Skan const double& real() const; 1170169691Skan double& imag(); 1171169691Skan const double& imag() const; 117297403Sobrien 1173169691Skan complex<double>& operator=(double); 1174169691Skan complex<double>& operator+=(double); 1175169691Skan complex<double>& operator-=(double); 1176169691Skan complex<double>& operator*=(double); 1177169691Skan complex<double>& operator/=(double); 117897403Sobrien 1179169691Skan // The compiler will synthetize this, efficiently. 1180169691Skan // complex& operator= (const complex&); 1181169691Skan template<typename _Tp> 1182169691Skan complex<double>& operator=(const complex<_Tp>&); 1183169691Skan template<typename _Tp> 1184169691Skan complex<double>& operator+=(const complex<_Tp>&); 1185169691Skan template<typename _Tp> 1186169691Skan complex<double>& operator-=(const complex<_Tp>&); 1187169691Skan template<typename _Tp> 1188169691Skan complex<double>& operator*=(const complex<_Tp>&); 1189169691Skan template<typename _Tp> 1190169691Skan complex<double>& operator/=(const complex<_Tp>&); 119197403Sobrien 1192169691Skan const _ComplexT& __rep() const { return _M_value; } 1193169691Skan 1194169691Skan private: 1195169691Skan _ComplexT _M_value; 1196169691Skan }; 1197169691Skan 1198132720Skan inline double& 1199132720Skan complex<double>::real() 1200132720Skan { return __real__ _M_value; } 1201132720Skan 1202132720Skan inline const double& 120397403Sobrien complex<double>::real() const 120497403Sobrien { return __real__ _M_value; } 120597403Sobrien 1206132720Skan inline double& 1207132720Skan complex<double>::imag() 1208132720Skan { return __imag__ _M_value; } 1209132720Skan 1210132720Skan inline const double& 121197403Sobrien complex<double>::imag() const 121297403Sobrien { return __imag__ _M_value; } 121397403Sobrien 121497403Sobrien inline 121597403Sobrien complex<double>::complex(double __r, double __i) 121697403Sobrien { 121797403Sobrien __real__ _M_value = __r; 121897403Sobrien __imag__ _M_value = __i; 121997403Sobrien } 122097403Sobrien 122197403Sobrien inline complex<double>& 122297403Sobrien complex<double>::operator=(double __d) 122397403Sobrien { 122497403Sobrien __real__ _M_value = __d; 122597403Sobrien __imag__ _M_value = 0.0; 122697403Sobrien return *this; 122797403Sobrien } 122897403Sobrien 122997403Sobrien inline complex<double>& 123097403Sobrien complex<double>::operator+=(double __d) 123197403Sobrien { 123297403Sobrien __real__ _M_value += __d; 123397403Sobrien return *this; 123497403Sobrien } 123597403Sobrien 123697403Sobrien inline complex<double>& 123797403Sobrien complex<double>::operator-=(double __d) 123897403Sobrien { 123997403Sobrien __real__ _M_value -= __d; 124097403Sobrien return *this; 124197403Sobrien } 124297403Sobrien 124397403Sobrien inline complex<double>& 124497403Sobrien complex<double>::operator*=(double __d) 124597403Sobrien { 124697403Sobrien _M_value *= __d; 124797403Sobrien return *this; 124897403Sobrien } 124997403Sobrien 125097403Sobrien inline complex<double>& 125197403Sobrien complex<double>::operator/=(double __d) 125297403Sobrien { 125397403Sobrien _M_value /= __d; 125497403Sobrien return *this; 125597403Sobrien } 125697403Sobrien 125797403Sobrien template<typename _Tp> 125897403Sobrien inline complex<double>& 125997403Sobrien complex<double>::operator=(const complex<_Tp>& __z) 126097403Sobrien { 126197403Sobrien __real__ _M_value = __z.real(); 126297403Sobrien __imag__ _M_value = __z.imag(); 126397403Sobrien return *this; 126497403Sobrien } 126597403Sobrien 126697403Sobrien template<typename _Tp> 126797403Sobrien inline complex<double>& 126897403Sobrien complex<double>::operator+=(const complex<_Tp>& __z) 126997403Sobrien { 127097403Sobrien __real__ _M_value += __z.real(); 127197403Sobrien __imag__ _M_value += __z.imag(); 127297403Sobrien return *this; 127397403Sobrien } 127497403Sobrien 127597403Sobrien template<typename _Tp> 127697403Sobrien inline complex<double>& 127797403Sobrien complex<double>::operator-=(const complex<_Tp>& __z) 127897403Sobrien { 127997403Sobrien __real__ _M_value -= __z.real(); 128097403Sobrien __imag__ _M_value -= __z.imag(); 128197403Sobrien return *this; 128297403Sobrien } 128397403Sobrien 128497403Sobrien template<typename _Tp> 128597403Sobrien inline complex<double>& 128697403Sobrien complex<double>::operator*=(const complex<_Tp>& __z) 128797403Sobrien { 128897403Sobrien _ComplexT __t; 128997403Sobrien __real__ __t = __z.real(); 129097403Sobrien __imag__ __t = __z.imag(); 129197403Sobrien _M_value *= __t; 129297403Sobrien return *this; 129397403Sobrien } 129497403Sobrien 129597403Sobrien template<typename _Tp> 129697403Sobrien inline complex<double>& 129797403Sobrien complex<double>::operator/=(const complex<_Tp>& __z) 129897403Sobrien { 129997403Sobrien _ComplexT __t; 130097403Sobrien __real__ __t = __z.real(); 130197403Sobrien __imag__ __t = __z.imag(); 130297403Sobrien _M_value /= __t; 130397403Sobrien return *this; 130497403Sobrien } 130597403Sobrien 130697403Sobrien // 26.2.3 complex specializations 130797403Sobrien // complex<long double> specialization 1308169691Skan template<> 1309169691Skan struct complex<long double> 1310169691Skan { 1311169691Skan typedef long double value_type; 1312169691Skan typedef __complex__ long double _ComplexT; 131397403Sobrien 1314169691Skan complex(_ComplexT __z) : _M_value(__z) { } 1315146897Skan 1316169691Skan complex(long double = 0.0L, long double = 0.0L); 131797403Sobrien 1318169691Skan complex(const complex<float>&); 1319169691Skan complex(const complex<double>&); 132097403Sobrien 1321169691Skan long double& real(); 1322169691Skan const long double& real() const; 1323169691Skan long double& imag(); 1324169691Skan const long double& imag() const; 132597403Sobrien 1326169691Skan complex<long double>& operator= (long double); 1327169691Skan complex<long double>& operator+= (long double); 1328169691Skan complex<long double>& operator-= (long double); 1329169691Skan complex<long double>& operator*= (long double); 1330169691Skan complex<long double>& operator/= (long double); 133197403Sobrien 1332169691Skan // The compiler knows how to do this efficiently 1333169691Skan // complex& operator= (const complex&); 1334169691Skan template<typename _Tp> 1335169691Skan complex<long double>& operator=(const complex<_Tp>&); 1336169691Skan template<typename _Tp> 1337169691Skan complex<long double>& operator+=(const complex<_Tp>&); 1338169691Skan template<typename _Tp> 1339169691Skan complex<long double>& operator-=(const complex<_Tp>&); 1340169691Skan template<typename _Tp> 1341169691Skan complex<long double>& operator*=(const complex<_Tp>&); 1342169691Skan template<typename _Tp> 1343169691Skan complex<long double>& operator/=(const complex<_Tp>&); 134497403Sobrien 1345169691Skan const _ComplexT& __rep() const { return _M_value; } 134697403Sobrien 1347169691Skan private: 1348169691Skan _ComplexT _M_value; 1349169691Skan }; 135097403Sobrien 135197403Sobrien inline 135297403Sobrien complex<long double>::complex(long double __r, long double __i) 135397403Sobrien { 135497403Sobrien __real__ _M_value = __r; 135597403Sobrien __imag__ _M_value = __i; 135697403Sobrien } 135797403Sobrien 1358132720Skan inline long double& 1359132720Skan complex<long double>::real() 1360132720Skan { return __real__ _M_value; } 1361132720Skan 1362132720Skan inline const long double& 136397403Sobrien complex<long double>::real() const 136497403Sobrien { return __real__ _M_value; } 136597403Sobrien 1366132720Skan inline long double& 1367132720Skan complex<long double>::imag() 1368132720Skan { return __imag__ _M_value; } 1369132720Skan 1370132720Skan inline const long double& 137197403Sobrien complex<long double>::imag() const 137297403Sobrien { return __imag__ _M_value; } 137397403Sobrien 137497403Sobrien inline complex<long double>& 137597403Sobrien complex<long double>::operator=(long double __r) 137697403Sobrien { 137797403Sobrien __real__ _M_value = __r; 137897403Sobrien __imag__ _M_value = 0.0L; 137997403Sobrien return *this; 138097403Sobrien } 138197403Sobrien 138297403Sobrien inline complex<long double>& 138397403Sobrien complex<long double>::operator+=(long double __r) 138497403Sobrien { 138597403Sobrien __real__ _M_value += __r; 138697403Sobrien return *this; 138797403Sobrien } 138897403Sobrien 138997403Sobrien inline complex<long double>& 139097403Sobrien complex<long double>::operator-=(long double __r) 139197403Sobrien { 139297403Sobrien __real__ _M_value -= __r; 139397403Sobrien return *this; 139497403Sobrien } 139597403Sobrien 139697403Sobrien inline complex<long double>& 139797403Sobrien complex<long double>::operator*=(long double __r) 139897403Sobrien { 139997403Sobrien _M_value *= __r; 140097403Sobrien return *this; 140197403Sobrien } 140297403Sobrien 140397403Sobrien inline complex<long double>& 140497403Sobrien complex<long double>::operator/=(long double __r) 140597403Sobrien { 140697403Sobrien _M_value /= __r; 140797403Sobrien return *this; 140897403Sobrien } 140997403Sobrien 141097403Sobrien template<typename _Tp> 141197403Sobrien inline complex<long double>& 141297403Sobrien complex<long double>::operator=(const complex<_Tp>& __z) 141397403Sobrien { 141497403Sobrien __real__ _M_value = __z.real(); 141597403Sobrien __imag__ _M_value = __z.imag(); 141697403Sobrien return *this; 141797403Sobrien } 141897403Sobrien 141997403Sobrien template<typename _Tp> 142097403Sobrien inline complex<long double>& 142197403Sobrien complex<long double>::operator+=(const complex<_Tp>& __z) 142297403Sobrien { 142397403Sobrien __real__ _M_value += __z.real(); 142497403Sobrien __imag__ _M_value += __z.imag(); 142597403Sobrien return *this; 142697403Sobrien } 142797403Sobrien 142897403Sobrien template<typename _Tp> 142997403Sobrien inline complex<long double>& 143097403Sobrien complex<long double>::operator-=(const complex<_Tp>& __z) 143197403Sobrien { 143297403Sobrien __real__ _M_value -= __z.real(); 143397403Sobrien __imag__ _M_value -= __z.imag(); 143497403Sobrien return *this; 143597403Sobrien } 143697403Sobrien 143797403Sobrien template<typename _Tp> 143897403Sobrien inline complex<long double>& 143997403Sobrien complex<long double>::operator*=(const complex<_Tp>& __z) 144097403Sobrien { 144197403Sobrien _ComplexT __t; 144297403Sobrien __real__ __t = __z.real(); 144397403Sobrien __imag__ __t = __z.imag(); 144497403Sobrien _M_value *= __t; 144597403Sobrien return *this; 144697403Sobrien } 144797403Sobrien 144897403Sobrien template<typename _Tp> 144997403Sobrien inline complex<long double>& 145097403Sobrien complex<long double>::operator/=(const complex<_Tp>& __z) 145197403Sobrien { 145297403Sobrien _ComplexT __t; 145397403Sobrien __real__ __t = __z.real(); 145497403Sobrien __imag__ __t = __z.imag(); 145597403Sobrien _M_value /= __t; 145697403Sobrien return *this; 145797403Sobrien } 145897403Sobrien 145997403Sobrien // These bits have to be at the end of this file, so that the 146097403Sobrien // specializations have all been defined. 146197403Sobrien // ??? No, they have to be there because of compiler limitation at 146297403Sobrien // inlining. It suffices that class specializations be defined. 146397403Sobrien inline 146497403Sobrien complex<float>::complex(const complex<double>& __z) 1465169691Skan : _M_value(__z.__rep()) { } 146697403Sobrien 146797403Sobrien inline 146897403Sobrien complex<float>::complex(const complex<long double>& __z) 1469169691Skan : _M_value(__z.__rep()) { } 147097403Sobrien 147197403Sobrien inline 147297403Sobrien complex<double>::complex(const complex<float>& __z) 1473169691Skan : _M_value(__z.__rep()) { } 147497403Sobrien 147597403Sobrien inline 147697403Sobrien complex<double>::complex(const complex<long double>& __z) 1477169691Skan : _M_value(__z.__rep()) { } 147897403Sobrien 147997403Sobrien inline 148097403Sobrien complex<long double>::complex(const complex<float>& __z) 1481169691Skan : _M_value(__z.__rep()) { } 148297403Sobrien 148397403Sobrien inline 148497403Sobrien complex<long double>::complex(const complex<double>& __z) 1485169691Skan : _M_value(__z.__rep()) { } 148697403Sobrien 1487169691Skan_GLIBCXX_END_NAMESPACE 1488169691Skan 1489132720Skan#endif /* _GLIBCXX_COMPLEX */ 1490