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