xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/std/std_complex.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // The template and inlines for the -*- C++ -*- complex number classes.
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4*404b540aSrobert // Free Software Foundation, Inc.
5*404b540aSrobert //
6*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
7*404b540aSrobert // software; you can redistribute it and/or modify it under the
8*404b540aSrobert // terms of the GNU General Public License as published by the
9*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
10*404b540aSrobert // any later version.
11*404b540aSrobert 
12*404b540aSrobert // This library is distributed in the hope that it will be useful,
13*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*404b540aSrobert // GNU General Public License for more details.
16*404b540aSrobert 
17*404b540aSrobert // You should have received a copy of the GNU General Public License along
18*404b540aSrobert // with this library; see the file COPYING.  If not, write to the Free
19*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20*404b540aSrobert // USA.
21*404b540aSrobert 
22*404b540aSrobert // As a special exception, you may use this file as part of a free software
23*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
24*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
25*404b540aSrobert // this file and link it with other files to produce an executable, this
26*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
27*404b540aSrobert // the GNU General Public License.  This exception does not however
28*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
29*404b540aSrobert // the GNU General Public License.
30*404b540aSrobert 
31*404b540aSrobert /** @file complex
32*404b540aSrobert  *  This is a Standard C++ Library header.
33*404b540aSrobert  */
34*404b540aSrobert 
35*404b540aSrobert //
36*404b540aSrobert // ISO C++ 14882: 26.2  Complex Numbers
37*404b540aSrobert // Note: this is not a conforming implementation.
38*404b540aSrobert // Initially implemented by Ulrich Drepper <drepper@cygnus.com>
39*404b540aSrobert // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
40*404b540aSrobert //
41*404b540aSrobert 
42*404b540aSrobert #ifndef _GLIBCXX_COMPLEX
43*404b540aSrobert #define _GLIBCXX_COMPLEX 1
44*404b540aSrobert 
45*404b540aSrobert #pragma GCC system_header
46*404b540aSrobert 
47*404b540aSrobert #include <bits/c++config.h>
48*404b540aSrobert #include <bits/cpp_type_traits.h>
49*404b540aSrobert #include <cmath>
50*404b540aSrobert #include <sstream>
51*404b540aSrobert 
52*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(std)
53*404b540aSrobert 
54*404b540aSrobert   // Forward declarations.
55*404b540aSrobert   template<typename _Tp> class complex;
56*404b540aSrobert   template<> class complex<float>;
57*404b540aSrobert   template<> class complex<double>;
58*404b540aSrobert   template<> class complex<long double>;
59*404b540aSrobert 
60*404b540aSrobert   ///  Return magnitude of @a z.
61*404b540aSrobert   template<typename _Tp> _Tp abs(const complex<_Tp>&);
62*404b540aSrobert   ///  Return phase angle of @a z.
63*404b540aSrobert   template<typename _Tp> _Tp arg(const complex<_Tp>&);
64*404b540aSrobert   ///  Return @a z magnitude squared.
65*404b540aSrobert   template<typename _Tp> _Tp norm(const complex<_Tp>&);
66*404b540aSrobert 
67*404b540aSrobert   ///  Return complex conjugate of @a z.
68*404b540aSrobert   template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
69*404b540aSrobert   ///  Return complex with magnitude @a rho and angle @a theta.
70*404b540aSrobert   template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
71*404b540aSrobert 
72*404b540aSrobert   // Transcendentals:
73*404b540aSrobert   /// Return complex cosine of @a z.
74*404b540aSrobert   template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
75*404b540aSrobert   /// Return complex hyperbolic cosine of @a z.
76*404b540aSrobert   template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
77*404b540aSrobert   /// Return complex base e exponential of @a z.
78*404b540aSrobert   template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
79*404b540aSrobert   /// Return complex natural logarithm of @a z.
80*404b540aSrobert   template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
81*404b540aSrobert   /// Return complex base 10 logarithm of @a z.
82*404b540aSrobert   template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
83*404b540aSrobert   /// Return complex cosine of @a z.
84*404b540aSrobert   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
85*404b540aSrobert   /// Return @a x to the @a y'th power.
86*404b540aSrobert   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
87*404b540aSrobert   /// Return @a x to the @a y'th power.
88*404b540aSrobert   template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&,
89*404b540aSrobert                                           const complex<_Tp>&);
90*404b540aSrobert   /// Return @a x to the @a y'th power.
91*404b540aSrobert   template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
92*404b540aSrobert   /// Return complex sine of @a z.
93*404b540aSrobert   template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
94*404b540aSrobert   /// Return complex hyperbolic sine of @a z.
95*404b540aSrobert   template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
96*404b540aSrobert   /// Return complex square root of @a z.
97*404b540aSrobert   template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
98*404b540aSrobert   /// Return complex tangent of @a z.
99*404b540aSrobert   template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
100*404b540aSrobert   /// Return complex hyperbolic tangent of @a z.
101*404b540aSrobert   template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
102*404b540aSrobert   //@}
103*404b540aSrobert 
104*404b540aSrobert 
105*404b540aSrobert   // 26.2.2  Primary template class complex
106*404b540aSrobert   /**
107*404b540aSrobert    *  Template to represent complex numbers.
108*404b540aSrobert    *
109*404b540aSrobert    *  Specializations for float, double, and long double are part of the
110*404b540aSrobert    *  library.  Results with any other type are not guaranteed.
111*404b540aSrobert    *
112*404b540aSrobert    *  @param  Tp  Type of real and imaginary values.
113*404b540aSrobert   */
114*404b540aSrobert   template<typename _Tp>
115*404b540aSrobert     struct complex
116*404b540aSrobert     {
117*404b540aSrobert       /// Value typedef.
118*404b540aSrobert       typedef _Tp value_type;
119*404b540aSrobert 
120*404b540aSrobert       ///  Default constructor.  First parameter is x, second parameter is y.
121*404b540aSrobert       ///  Unspecified parameters default to 0.
122*404b540aSrobert       complex(const _Tp& = _Tp(), const _Tp & = _Tp());
123*404b540aSrobert 
124*404b540aSrobert       // Lets the compiler synthesize the copy constructor
125*404b540aSrobert       // complex (const complex<_Tp>&);
126*404b540aSrobert       ///  Copy constructor.
127*404b540aSrobert       template<typename _Up>
128*404b540aSrobert         complex(const complex<_Up>&);
129*404b540aSrobert 
130*404b540aSrobert       ///  Return real part of complex number.
131*404b540aSrobert       _Tp& real();
132*404b540aSrobert       ///  Return real part of complex number.
133*404b540aSrobert       const _Tp& real() const;
134*404b540aSrobert       ///  Return imaginary part of complex number.
135*404b540aSrobert       _Tp& imag();
136*404b540aSrobert       ///  Return imaginary part of complex number.
137*404b540aSrobert       const _Tp& imag() const;
138*404b540aSrobert 
139*404b540aSrobert       /// Assign this complex number to scalar @a t.
140*404b540aSrobert       complex<_Tp>& operator=(const _Tp&);
141*404b540aSrobert       /// Add @a t to this complex number.
142*404b540aSrobert       complex<_Tp>& operator+=(const _Tp&);
143*404b540aSrobert       /// Subtract @a t from this complex number.
144*404b540aSrobert       complex<_Tp>& operator-=(const _Tp&);
145*404b540aSrobert       /// Multiply this complex number by @a t.
146*404b540aSrobert       complex<_Tp>& operator*=(const _Tp&);
147*404b540aSrobert       /// Divide this complex number by @a t.
148*404b540aSrobert       complex<_Tp>& operator/=(const _Tp&);
149*404b540aSrobert 
150*404b540aSrobert       // Lets the compiler synthesize the
151*404b540aSrobert       // copy and assignment operator
152*404b540aSrobert       // complex<_Tp>& operator= (const complex<_Tp>&);
153*404b540aSrobert       /// Assign this complex number to complex @a z.
154*404b540aSrobert       template<typename _Up>
155*404b540aSrobert         complex<_Tp>& operator=(const complex<_Up>&);
156*404b540aSrobert       /// Add @a z to this complex number.
157*404b540aSrobert       template<typename _Up>
158*404b540aSrobert         complex<_Tp>& operator+=(const complex<_Up>&);
159*404b540aSrobert       /// Subtract @a z from this complex number.
160*404b540aSrobert       template<typename _Up>
161*404b540aSrobert         complex<_Tp>& operator-=(const complex<_Up>&);
162*404b540aSrobert       /// Multiply this complex number by @a z.
163*404b540aSrobert       template<typename _Up>
164*404b540aSrobert         complex<_Tp>& operator*=(const complex<_Up>&);
165*404b540aSrobert       /// Divide this complex number by @a z.
166*404b540aSrobert       template<typename _Up>
167*404b540aSrobert         complex<_Tp>& operator/=(const complex<_Up>&);
168*404b540aSrobert 
169*404b540aSrobert       const complex& __rep() const;
170*404b540aSrobert 
171*404b540aSrobert     private:
172*404b540aSrobert       _Tp _M_real;
173*404b540aSrobert       _Tp _M_imag;
174*404b540aSrobert     };
175*404b540aSrobert 
176*404b540aSrobert   template<typename _Tp>
177*404b540aSrobert     inline _Tp&
real()178*404b540aSrobert     complex<_Tp>::real() { return _M_real; }
179*404b540aSrobert 
180*404b540aSrobert   template<typename _Tp>
181*404b540aSrobert     inline const _Tp&
real()182*404b540aSrobert     complex<_Tp>::real() const { return _M_real; }
183*404b540aSrobert 
184*404b540aSrobert   template<typename _Tp>
185*404b540aSrobert     inline _Tp&
imag()186*404b540aSrobert     complex<_Tp>::imag() { return _M_imag; }
187*404b540aSrobert 
188*404b540aSrobert   template<typename _Tp>
189*404b540aSrobert     inline const _Tp&
imag()190*404b540aSrobert     complex<_Tp>::imag() const { return _M_imag; }
191*404b540aSrobert 
192*404b540aSrobert   template<typename _Tp>
193*404b540aSrobert     inline
complex(const _Tp & __r,const _Tp & __i)194*404b540aSrobert     complex<_Tp>::complex(const _Tp& __r, const _Tp& __i)
195*404b540aSrobert     : _M_real(__r), _M_imag(__i) { }
196*404b540aSrobert 
197*404b540aSrobert   template<typename _Tp>
198*404b540aSrobert     template<typename _Up>
199*404b540aSrobert     inline
complex(const complex<_Up> & __z)200*404b540aSrobert     complex<_Tp>::complex(const complex<_Up>& __z)
201*404b540aSrobert     : _M_real(__z.real()), _M_imag(__z.imag()) { }
202*404b540aSrobert 
203*404b540aSrobert   template<typename _Tp>
204*404b540aSrobert     complex<_Tp>&
205*404b540aSrobert     complex<_Tp>::operator=(const _Tp& __t)
206*404b540aSrobert     {
207*404b540aSrobert      _M_real = __t;
208*404b540aSrobert      _M_imag = _Tp();
209*404b540aSrobert      return *this;
210*404b540aSrobert     }
211*404b540aSrobert 
212*404b540aSrobert   // 26.2.5/1
213*404b540aSrobert   template<typename _Tp>
214*404b540aSrobert     inline complex<_Tp>&
215*404b540aSrobert     complex<_Tp>::operator+=(const _Tp& __t)
216*404b540aSrobert     {
217*404b540aSrobert       _M_real += __t;
218*404b540aSrobert       return *this;
219*404b540aSrobert     }
220*404b540aSrobert 
221*404b540aSrobert   // 26.2.5/3
222*404b540aSrobert   template<typename _Tp>
223*404b540aSrobert     inline complex<_Tp>&
224*404b540aSrobert     complex<_Tp>::operator-=(const _Tp& __t)
225*404b540aSrobert     {
226*404b540aSrobert       _M_real -= __t;
227*404b540aSrobert       return *this;
228*404b540aSrobert     }
229*404b540aSrobert 
230*404b540aSrobert   // 26.2.5/5
231*404b540aSrobert   template<typename _Tp>
232*404b540aSrobert     complex<_Tp>&
233*404b540aSrobert     complex<_Tp>::operator*=(const _Tp& __t)
234*404b540aSrobert     {
235*404b540aSrobert       _M_real *= __t;
236*404b540aSrobert       _M_imag *= __t;
237*404b540aSrobert       return *this;
238*404b540aSrobert     }
239*404b540aSrobert 
240*404b540aSrobert   // 26.2.5/7
241*404b540aSrobert   template<typename _Tp>
242*404b540aSrobert     complex<_Tp>&
243*404b540aSrobert     complex<_Tp>::operator/=(const _Tp& __t)
244*404b540aSrobert     {
245*404b540aSrobert       _M_real /= __t;
246*404b540aSrobert       _M_imag /= __t;
247*404b540aSrobert       return *this;
248*404b540aSrobert     }
249*404b540aSrobert 
250*404b540aSrobert   template<typename _Tp>
251*404b540aSrobert     template<typename _Up>
252*404b540aSrobert     complex<_Tp>&
253*404b540aSrobert     complex<_Tp>::operator=(const complex<_Up>& __z)
254*404b540aSrobert     {
255*404b540aSrobert       _M_real = __z.real();
256*404b540aSrobert       _M_imag = __z.imag();
257*404b540aSrobert       return *this;
258*404b540aSrobert     }
259*404b540aSrobert 
260*404b540aSrobert   // 26.2.5/9
261*404b540aSrobert   template<typename _Tp>
262*404b540aSrobert     template<typename _Up>
263*404b540aSrobert     complex<_Tp>&
264*404b540aSrobert     complex<_Tp>::operator+=(const complex<_Up>& __z)
265*404b540aSrobert     {
266*404b540aSrobert       _M_real += __z.real();
267*404b540aSrobert       _M_imag += __z.imag();
268*404b540aSrobert       return *this;
269*404b540aSrobert     }
270*404b540aSrobert 
271*404b540aSrobert   // 26.2.5/11
272*404b540aSrobert   template<typename _Tp>
273*404b540aSrobert     template<typename _Up>
274*404b540aSrobert     complex<_Tp>&
275*404b540aSrobert     complex<_Tp>::operator-=(const complex<_Up>& __z)
276*404b540aSrobert     {
277*404b540aSrobert       _M_real -= __z.real();
278*404b540aSrobert       _M_imag -= __z.imag();
279*404b540aSrobert       return *this;
280*404b540aSrobert     }
281*404b540aSrobert 
282*404b540aSrobert   // 26.2.5/13
283*404b540aSrobert   // XXX: This is a grammar school implementation.
284*404b540aSrobert   template<typename _Tp>
285*404b540aSrobert     template<typename _Up>
286*404b540aSrobert     complex<_Tp>&
287*404b540aSrobert     complex<_Tp>::operator*=(const complex<_Up>& __z)
288*404b540aSrobert     {
289*404b540aSrobert       const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
290*404b540aSrobert       _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
291*404b540aSrobert       _M_real = __r;
292*404b540aSrobert       return *this;
293*404b540aSrobert     }
294*404b540aSrobert 
295*404b540aSrobert   // 26.2.5/15
296*404b540aSrobert   // XXX: This is a grammar school implementation.
297*404b540aSrobert   template<typename _Tp>
298*404b540aSrobert     template<typename _Up>
299*404b540aSrobert     complex<_Tp>&
300*404b540aSrobert     complex<_Tp>::operator/=(const complex<_Up>& __z)
301*404b540aSrobert     {
302*404b540aSrobert       const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
303*404b540aSrobert       const _Tp __n = std::norm(__z);
304*404b540aSrobert       _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
305*404b540aSrobert       _M_real = __r / __n;
306*404b540aSrobert       return *this;
307*404b540aSrobert     }
308*404b540aSrobert 
309*404b540aSrobert   template<typename _Tp>
310*404b540aSrobert     inline const complex<_Tp>&
__rep()311*404b540aSrobert     complex<_Tp>::__rep() const { return *this; }
312*404b540aSrobert 
313*404b540aSrobert   // Operators:
314*404b540aSrobert   //@{
315*404b540aSrobert   ///  Return new complex value @a x plus @a y.
316*404b540aSrobert   template<typename _Tp>
317*404b540aSrobert     inline complex<_Tp>
318*404b540aSrobert     operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
319*404b540aSrobert     {
320*404b540aSrobert       complex<_Tp> __r = __x;
321*404b540aSrobert       __r += __y;
322*404b540aSrobert       return __r;
323*404b540aSrobert     }
324*404b540aSrobert 
325*404b540aSrobert   template<typename _Tp>
326*404b540aSrobert     inline complex<_Tp>
327*404b540aSrobert     operator+(const complex<_Tp>& __x, const _Tp& __y)
328*404b540aSrobert     {
329*404b540aSrobert       complex<_Tp> __r = __x;
330*404b540aSrobert       __r.real() += __y;
331*404b540aSrobert       return __r;
332*404b540aSrobert     }
333*404b540aSrobert 
334*404b540aSrobert   template<typename _Tp>
335*404b540aSrobert     inline complex<_Tp>
336*404b540aSrobert     operator+(const _Tp& __x, const complex<_Tp>& __y)
337*404b540aSrobert     {
338*404b540aSrobert       complex<_Tp> __r = __y;
339*404b540aSrobert       __r.real() += __x;
340*404b540aSrobert       return __r;
341*404b540aSrobert     }
342*404b540aSrobert   //@}
343*404b540aSrobert 
344*404b540aSrobert   //@{
345*404b540aSrobert   ///  Return new complex value @a x minus @a y.
346*404b540aSrobert   template<typename _Tp>
347*404b540aSrobert     inline complex<_Tp>
348*404b540aSrobert     operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
349*404b540aSrobert     {
350*404b540aSrobert       complex<_Tp> __r = __x;
351*404b540aSrobert       __r -= __y;
352*404b540aSrobert       return __r;
353*404b540aSrobert     }
354*404b540aSrobert 
355*404b540aSrobert   template<typename _Tp>
356*404b540aSrobert     inline complex<_Tp>
357*404b540aSrobert     operator-(const complex<_Tp>& __x, const _Tp& __y)
358*404b540aSrobert     {
359*404b540aSrobert       complex<_Tp> __r = __x;
360*404b540aSrobert       __r.real() -= __y;
361*404b540aSrobert       return __r;
362*404b540aSrobert     }
363*404b540aSrobert 
364*404b540aSrobert   template<typename _Tp>
365*404b540aSrobert     inline complex<_Tp>
366*404b540aSrobert     operator-(const _Tp& __x, const complex<_Tp>& __y)
367*404b540aSrobert     {
368*404b540aSrobert       complex<_Tp> __r(__x, -__y.imag());
369*404b540aSrobert       __r.real() -= __y.real();
370*404b540aSrobert       return __r;
371*404b540aSrobert     }
372*404b540aSrobert   //@}
373*404b540aSrobert 
374*404b540aSrobert   //@{
375*404b540aSrobert   ///  Return new complex value @a x times @a y.
376*404b540aSrobert   template<typename _Tp>
377*404b540aSrobert     inline complex<_Tp>
378*404b540aSrobert     operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
379*404b540aSrobert     {
380*404b540aSrobert       complex<_Tp> __r = __x;
381*404b540aSrobert       __r *= __y;
382*404b540aSrobert       return __r;
383*404b540aSrobert     }
384*404b540aSrobert 
385*404b540aSrobert   template<typename _Tp>
386*404b540aSrobert     inline complex<_Tp>
387*404b540aSrobert     operator*(const complex<_Tp>& __x, const _Tp& __y)
388*404b540aSrobert     {
389*404b540aSrobert       complex<_Tp> __r = __x;
390*404b540aSrobert       __r *= __y;
391*404b540aSrobert       return __r;
392*404b540aSrobert     }
393*404b540aSrobert 
394*404b540aSrobert   template<typename _Tp>
395*404b540aSrobert     inline complex<_Tp>
396*404b540aSrobert     operator*(const _Tp& __x, const complex<_Tp>& __y)
397*404b540aSrobert     {
398*404b540aSrobert       complex<_Tp> __r = __y;
399*404b540aSrobert       __r *= __x;
400*404b540aSrobert       return __r;
401*404b540aSrobert     }
402*404b540aSrobert   //@}
403*404b540aSrobert 
404*404b540aSrobert   //@{
405*404b540aSrobert   ///  Return new complex value @a x divided by @a y.
406*404b540aSrobert   template<typename _Tp>
407*404b540aSrobert     inline complex<_Tp>
408*404b540aSrobert     operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
409*404b540aSrobert     {
410*404b540aSrobert       complex<_Tp> __r = __x;
411*404b540aSrobert       __r /= __y;
412*404b540aSrobert       return __r;
413*404b540aSrobert     }
414*404b540aSrobert 
415*404b540aSrobert   template<typename _Tp>
416*404b540aSrobert     inline complex<_Tp>
417*404b540aSrobert     operator/(const complex<_Tp>& __x, const _Tp& __y)
418*404b540aSrobert     {
419*404b540aSrobert       complex<_Tp> __r = __x;
420*404b540aSrobert       __r /= __y;
421*404b540aSrobert       return __r;
422*404b540aSrobert     }
423*404b540aSrobert 
424*404b540aSrobert   template<typename _Tp>
425*404b540aSrobert     inline complex<_Tp>
426*404b540aSrobert     operator/(const _Tp& __x, const complex<_Tp>& __y)
427*404b540aSrobert     {
428*404b540aSrobert       complex<_Tp> __r = __x;
429*404b540aSrobert       __r /= __y;
430*404b540aSrobert       return __r;
431*404b540aSrobert     }
432*404b540aSrobert   //@}
433*404b540aSrobert 
434*404b540aSrobert   ///  Return @a x.
435*404b540aSrobert   template<typename _Tp>
436*404b540aSrobert     inline complex<_Tp>
437*404b540aSrobert     operator+(const complex<_Tp>& __x)
438*404b540aSrobert     { return __x; }
439*404b540aSrobert 
440*404b540aSrobert   ///  Return complex negation of @a x.
441*404b540aSrobert   template<typename _Tp>
442*404b540aSrobert     inline complex<_Tp>
443*404b540aSrobert     operator-(const complex<_Tp>& __x)
444*404b540aSrobert     {  return complex<_Tp>(-__x.real(), -__x.imag()); }
445*404b540aSrobert 
446*404b540aSrobert   //@{
447*404b540aSrobert   ///  Return true if @a x is equal to @a y.
448*404b540aSrobert   template<typename _Tp>
449*404b540aSrobert     inline bool
450*404b540aSrobert     operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
451*404b540aSrobert     { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
452*404b540aSrobert 
453*404b540aSrobert   template<typename _Tp>
454*404b540aSrobert     inline bool
455*404b540aSrobert     operator==(const complex<_Tp>& __x, const _Tp& __y)
456*404b540aSrobert     { return __x.real() == __y && __x.imag() == _Tp(); }
457*404b540aSrobert 
458*404b540aSrobert   template<typename _Tp>
459*404b540aSrobert     inline bool
460*404b540aSrobert     operator==(const _Tp& __x, const complex<_Tp>& __y)
461*404b540aSrobert     { return __x == __y.real() && _Tp() == __y.imag(); }
462*404b540aSrobert   //@}
463*404b540aSrobert 
464*404b540aSrobert   //@{
465*404b540aSrobert   ///  Return false if @a x is equal to @a y.
466*404b540aSrobert   template<typename _Tp>
467*404b540aSrobert     inline bool
468*404b540aSrobert     operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
469*404b540aSrobert     { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
470*404b540aSrobert 
471*404b540aSrobert   template<typename _Tp>
472*404b540aSrobert     inline bool
473*404b540aSrobert     operator!=(const complex<_Tp>& __x, const _Tp& __y)
474*404b540aSrobert     { return __x.real() != __y || __x.imag() != _Tp(); }
475*404b540aSrobert 
476*404b540aSrobert   template<typename _Tp>
477*404b540aSrobert     inline bool
478*404b540aSrobert     operator!=(const _Tp& __x, const complex<_Tp>& __y)
479*404b540aSrobert     { return __x != __y.real() || _Tp() != __y.imag(); }
480*404b540aSrobert   //@}
481*404b540aSrobert 
482*404b540aSrobert   ///  Extraction operator for complex values.
483*404b540aSrobert   template<typename _Tp, typename _CharT, class _Traits>
484*404b540aSrobert     basic_istream<_CharT, _Traits>&
485*404b540aSrobert     operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
486*404b540aSrobert     {
487*404b540aSrobert       _Tp __re_x, __im_x;
488*404b540aSrobert       _CharT __ch;
489*404b540aSrobert       __is >> __ch;
490*404b540aSrobert       if (__ch == '(')
491*404b540aSrobert 	{
492*404b540aSrobert 	  __is >> __re_x >> __ch;
493*404b540aSrobert 	  if (__ch == ',')
494*404b540aSrobert 	    {
495*404b540aSrobert 	      __is >> __im_x >> __ch;
496*404b540aSrobert 	      if (__ch == ')')
497*404b540aSrobert 		__x = complex<_Tp>(__re_x, __im_x);
498*404b540aSrobert 	      else
499*404b540aSrobert 		__is.setstate(ios_base::failbit);
500*404b540aSrobert 	    }
501*404b540aSrobert 	  else if (__ch == ')')
502*404b540aSrobert 	    __x = __re_x;
503*404b540aSrobert 	  else
504*404b540aSrobert 	    __is.setstate(ios_base::failbit);
505*404b540aSrobert 	}
506*404b540aSrobert       else
507*404b540aSrobert 	{
508*404b540aSrobert 	  __is.putback(__ch);
509*404b540aSrobert 	  __is >> __re_x;
510*404b540aSrobert 	  __x = __re_x;
511*404b540aSrobert 	}
512*404b540aSrobert       return __is;
513*404b540aSrobert     }
514*404b540aSrobert 
515*404b540aSrobert   ///  Insertion operator for complex values.
516*404b540aSrobert   template<typename _Tp, typename _CharT, class _Traits>
517*404b540aSrobert     basic_ostream<_CharT, _Traits>&
518*404b540aSrobert     operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
519*404b540aSrobert     {
520*404b540aSrobert       basic_ostringstream<_CharT, _Traits> __s;
521*404b540aSrobert       __s.flags(__os.flags());
522*404b540aSrobert       __s.imbue(__os.getloc());
523*404b540aSrobert       __s.precision(__os.precision());
524*404b540aSrobert       __s << '(' << __x.real() << ',' << __x.imag() << ')';
525*404b540aSrobert       return __os << __s.str();
526*404b540aSrobert     }
527*404b540aSrobert 
528*404b540aSrobert   // Values
529*404b540aSrobert   template<typename _Tp>
530*404b540aSrobert     inline _Tp&
real(complex<_Tp> & __z)531*404b540aSrobert     real(complex<_Tp>& __z)
532*404b540aSrobert     { return __z.real(); }
533*404b540aSrobert 
534*404b540aSrobert   template<typename _Tp>
535*404b540aSrobert     inline const _Tp&
real(const complex<_Tp> & __z)536*404b540aSrobert     real(const complex<_Tp>& __z)
537*404b540aSrobert     { return __z.real(); }
538*404b540aSrobert 
539*404b540aSrobert   template<typename _Tp>
540*404b540aSrobert     inline _Tp&
imag(complex<_Tp> & __z)541*404b540aSrobert     imag(complex<_Tp>& __z)
542*404b540aSrobert     { return __z.imag(); }
543*404b540aSrobert 
544*404b540aSrobert   template<typename _Tp>
545*404b540aSrobert     inline const _Tp&
imag(const complex<_Tp> & __z)546*404b540aSrobert     imag(const complex<_Tp>& __z)
547*404b540aSrobert     { return __z.imag(); }
548*404b540aSrobert 
549*404b540aSrobert   // 26.2.7/3 abs(__z):  Returns the magnitude of __z.
550*404b540aSrobert   template<typename _Tp>
551*404b540aSrobert     inline _Tp
__complex_abs(const complex<_Tp> & __z)552*404b540aSrobert     __complex_abs(const complex<_Tp>& __z)
553*404b540aSrobert     {
554*404b540aSrobert       _Tp __x = __z.real();
555*404b540aSrobert       _Tp __y = __z.imag();
556*404b540aSrobert       const _Tp __s = std::max(abs(__x), abs(__y));
557*404b540aSrobert       if (__s == _Tp())  // well ...
558*404b540aSrobert         return __s;
559*404b540aSrobert       __x /= __s;
560*404b540aSrobert       __y /= __s;
561*404b540aSrobert       return __s * sqrt(__x * __x + __y * __y);
562*404b540aSrobert     }
563*404b540aSrobert 
564*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
565*404b540aSrobert   inline float
__complex_abs(__complex__ float __z)566*404b540aSrobert   __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); }
567*404b540aSrobert 
568*404b540aSrobert   inline double
__complex_abs(__complex__ double __z)569*404b540aSrobert   __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); }
570*404b540aSrobert 
571*404b540aSrobert   inline long double
__complex_abs(const __complex__ long double & __z)572*404b540aSrobert   __complex_abs(const __complex__ long double& __z)
573*404b540aSrobert   { return __builtin_cabsl(__z); }
574*404b540aSrobert 
575*404b540aSrobert   template<typename _Tp>
576*404b540aSrobert     inline _Tp
abs(const complex<_Tp> & __z)577*404b540aSrobert     abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); }
578*404b540aSrobert #else
579*404b540aSrobert   template<typename _Tp>
580*404b540aSrobert     inline _Tp
abs(const complex<_Tp> & __z)581*404b540aSrobert     abs(const complex<_Tp>& __z) { return __complex_abs(__z); }
582*404b540aSrobert #endif
583*404b540aSrobert 
584*404b540aSrobert 
585*404b540aSrobert   // 26.2.7/4: arg(__z): Returns the phase angle of __z.
586*404b540aSrobert   template<typename _Tp>
587*404b540aSrobert     inline _Tp
__complex_arg(const complex<_Tp> & __z)588*404b540aSrobert     __complex_arg(const complex<_Tp>& __z)
589*404b540aSrobert     { return  atan2(__z.imag(), __z.real()); }
590*404b540aSrobert 
591*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
592*404b540aSrobert   inline float
__complex_arg(__complex__ float __z)593*404b540aSrobert   __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); }
594*404b540aSrobert 
595*404b540aSrobert   inline double
__complex_arg(__complex__ double __z)596*404b540aSrobert   __complex_arg(__complex__ double __z) { return __builtin_carg(__z); }
597*404b540aSrobert 
598*404b540aSrobert   inline long double
__complex_arg(const __complex__ long double & __z)599*404b540aSrobert   __complex_arg(const __complex__ long double& __z)
600*404b540aSrobert   { return __builtin_cargl(__z); }
601*404b540aSrobert 
602*404b540aSrobert   template<typename _Tp>
603*404b540aSrobert     inline _Tp
arg(const complex<_Tp> & __z)604*404b540aSrobert     arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); }
605*404b540aSrobert #else
606*404b540aSrobert   template<typename _Tp>
607*404b540aSrobert     inline _Tp
arg(const complex<_Tp> & __z)608*404b540aSrobert     arg(const complex<_Tp>& __z) { return __complex_arg(__z); }
609*404b540aSrobert #endif
610*404b540aSrobert 
611*404b540aSrobert   // 26.2.7/5: norm(__z) returns the squared magintude of __z.
612*404b540aSrobert   //     As defined, norm() is -not- a norm is the common mathematical
613*404b540aSrobert   //     sens used in numerics.  The helper class _Norm_helper<> tries to
614*404b540aSrobert   //     distinguish between builtin floating point and the rest, so as
615*404b540aSrobert   //     to deliver an answer as close as possible to the real value.
616*404b540aSrobert   template<bool>
617*404b540aSrobert     struct _Norm_helper
618*404b540aSrobert     {
619*404b540aSrobert       template<typename _Tp>
_S_do_it_Norm_helper620*404b540aSrobert         static inline _Tp _S_do_it(const complex<_Tp>& __z)
621*404b540aSrobert         {
622*404b540aSrobert           const _Tp __x = __z.real();
623*404b540aSrobert           const _Tp __y = __z.imag();
624*404b540aSrobert           return __x * __x + __y * __y;
625*404b540aSrobert         }
626*404b540aSrobert     };
627*404b540aSrobert 
628*404b540aSrobert   template<>
629*404b540aSrobert     struct _Norm_helper<true>
630*404b540aSrobert     {
631*404b540aSrobert       template<typename _Tp>
632*404b540aSrobert         static inline _Tp _S_do_it(const complex<_Tp>& __z)
633*404b540aSrobert         {
634*404b540aSrobert           _Tp __res = std::abs(__z);
635*404b540aSrobert           return __res * __res;
636*404b540aSrobert         }
637*404b540aSrobert     };
638*404b540aSrobert 
639*404b540aSrobert   template<typename _Tp>
640*404b540aSrobert     inline _Tp
641*404b540aSrobert     norm(const complex<_Tp>& __z)
642*404b540aSrobert     {
643*404b540aSrobert       return _Norm_helper<__is_floating<_Tp>::__value
644*404b540aSrobert 	&& !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
645*404b540aSrobert     }
646*404b540aSrobert 
647*404b540aSrobert   template<typename _Tp>
648*404b540aSrobert     inline complex<_Tp>
649*404b540aSrobert     polar(const _Tp& __rho, const _Tp& __theta)
650*404b540aSrobert     { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
651*404b540aSrobert 
652*404b540aSrobert   template<typename _Tp>
653*404b540aSrobert     inline complex<_Tp>
654*404b540aSrobert     conj(const complex<_Tp>& __z)
655*404b540aSrobert     { return complex<_Tp>(__z.real(), -__z.imag()); }
656*404b540aSrobert 
657*404b540aSrobert   // Transcendentals
658*404b540aSrobert 
659*404b540aSrobert   // 26.2.8/1 cos(__z):  Returns the cosine of __z.
660*404b540aSrobert   template<typename _Tp>
661*404b540aSrobert     inline complex<_Tp>
662*404b540aSrobert     __complex_cos(const complex<_Tp>& __z)
663*404b540aSrobert     {
664*404b540aSrobert       const _Tp __x = __z.real();
665*404b540aSrobert       const _Tp __y = __z.imag();
666*404b540aSrobert       return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
667*404b540aSrobert     }
668*404b540aSrobert 
669*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
670*404b540aSrobert   inline __complex__ float
671*404b540aSrobert   __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); }
672*404b540aSrobert 
673*404b540aSrobert   inline __complex__ double
674*404b540aSrobert   __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); }
675*404b540aSrobert 
676*404b540aSrobert   inline __complex__ long double
677*404b540aSrobert   __complex_cos(const __complex__ long double& __z)
678*404b540aSrobert   { return __builtin_ccosl(__z); }
679*404b540aSrobert 
680*404b540aSrobert   template<typename _Tp>
681*404b540aSrobert     inline complex<_Tp>
682*404b540aSrobert     cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); }
683*404b540aSrobert #else
684*404b540aSrobert   template<typename _Tp>
685*404b540aSrobert     inline complex<_Tp>
686*404b540aSrobert     cos(const complex<_Tp>& __z) { return __complex_cos(__z); }
687*404b540aSrobert #endif
688*404b540aSrobert 
689*404b540aSrobert   // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z.
690*404b540aSrobert   template<typename _Tp>
691*404b540aSrobert     inline complex<_Tp>
692*404b540aSrobert     __complex_cosh(const complex<_Tp>& __z)
693*404b540aSrobert     {
694*404b540aSrobert       const _Tp __x = __z.real();
695*404b540aSrobert       const _Tp __y = __z.imag();
696*404b540aSrobert       return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
697*404b540aSrobert     }
698*404b540aSrobert 
699*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
700*404b540aSrobert   inline __complex__ float
701*404b540aSrobert   __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); }
702*404b540aSrobert 
703*404b540aSrobert   inline __complex__ double
704*404b540aSrobert   __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); }
705*404b540aSrobert 
706*404b540aSrobert   inline __complex__ long double
707*404b540aSrobert   __complex_cosh(const __complex__ long double& __z)
708*404b540aSrobert   { return __builtin_ccoshl(__z); }
709*404b540aSrobert 
710*404b540aSrobert   template<typename _Tp>
711*404b540aSrobert     inline complex<_Tp>
712*404b540aSrobert     cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); }
713*404b540aSrobert #else
714*404b540aSrobert   template<typename _Tp>
715*404b540aSrobert     inline complex<_Tp>
716*404b540aSrobert     cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); }
717*404b540aSrobert #endif
718*404b540aSrobert 
719*404b540aSrobert   // 26.2.8/3 exp(__z): Returns the complex base e exponential of x
720*404b540aSrobert   template<typename _Tp>
721*404b540aSrobert     inline complex<_Tp>
722*404b540aSrobert     __complex_exp(const complex<_Tp>& __z)
723*404b540aSrobert     { return std::polar(exp(__z.real()), __z.imag()); }
724*404b540aSrobert 
725*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
726*404b540aSrobert   inline __complex__ float
727*404b540aSrobert   __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); }
728*404b540aSrobert 
729*404b540aSrobert   inline __complex__ double
730*404b540aSrobert   __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); }
731*404b540aSrobert 
732*404b540aSrobert   inline __complex__ long double
733*404b540aSrobert   __complex_exp(const __complex__ long double& __z)
734*404b540aSrobert   { return __builtin_cexpl(__z); }
735*404b540aSrobert 
736*404b540aSrobert   template<typename _Tp>
737*404b540aSrobert     inline complex<_Tp>
738*404b540aSrobert     exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); }
739*404b540aSrobert #else
740*404b540aSrobert   template<typename _Tp>
741*404b540aSrobert     inline complex<_Tp>
742*404b540aSrobert     exp(const complex<_Tp>& __z) { return __complex_exp(__z); }
743*404b540aSrobert #endif
744*404b540aSrobert 
745*404b540aSrobert   // 26.2.8/5 log(__z): Reurns the natural complex logaritm of __z.
746*404b540aSrobert   //                    The branch cut is along the negative axis.
747*404b540aSrobert   template<typename _Tp>
748*404b540aSrobert     inline complex<_Tp>
749*404b540aSrobert     __complex_log(const complex<_Tp>& __z)
750*404b540aSrobert     { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
751*404b540aSrobert 
752*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
753*404b540aSrobert   inline __complex__ float
754*404b540aSrobert   __complex_log(__complex__ float __z) { return __builtin_clogf(__z); }
755*404b540aSrobert 
756*404b540aSrobert   inline __complex__ double
757*404b540aSrobert   __complex_log(__complex__ double __z) { return __builtin_clog(__z); }
758*404b540aSrobert 
759*404b540aSrobert   inline __complex__ long double
760*404b540aSrobert   __complex_log(const __complex__ long double& __z)
761*404b540aSrobert   { return __builtin_clogl(__z); }
762*404b540aSrobert 
763*404b540aSrobert   template<typename _Tp>
764*404b540aSrobert     inline complex<_Tp>
765*404b540aSrobert     log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); }
766*404b540aSrobert #else
767*404b540aSrobert   template<typename _Tp>
768*404b540aSrobert     inline complex<_Tp>
769*404b540aSrobert     log(const complex<_Tp>& __z) { return __complex_log(__z); }
770*404b540aSrobert #endif
771*404b540aSrobert 
772*404b540aSrobert   template<typename _Tp>
773*404b540aSrobert     inline complex<_Tp>
774*404b540aSrobert     log10(const complex<_Tp>& __z)
775*404b540aSrobert     { return std::log(__z) / log(_Tp(10.0)); }
776*404b540aSrobert 
777*404b540aSrobert   // 26.2.8/10 sin(__z): Returns the sine of __z.
778*404b540aSrobert   template<typename _Tp>
779*404b540aSrobert     inline complex<_Tp>
780*404b540aSrobert     __complex_sin(const complex<_Tp>& __z)
781*404b540aSrobert     {
782*404b540aSrobert       const _Tp __x = __z.real();
783*404b540aSrobert       const _Tp __y = __z.imag();
784*404b540aSrobert       return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y));
785*404b540aSrobert     }
786*404b540aSrobert 
787*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
788*404b540aSrobert   inline __complex__ float
789*404b540aSrobert   __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); }
790*404b540aSrobert 
791*404b540aSrobert   inline __complex__ double
792*404b540aSrobert   __complex_sin(__complex__ double __z) { return __builtin_csin(__z); }
793*404b540aSrobert 
794*404b540aSrobert   inline __complex__ long double
795*404b540aSrobert   __complex_sin(const __complex__ long double& __z)
796*404b540aSrobert   { return __builtin_csinl(__z); }
797*404b540aSrobert 
798*404b540aSrobert   template<typename _Tp>
799*404b540aSrobert     inline complex<_Tp>
800*404b540aSrobert     sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); }
801*404b540aSrobert #else
802*404b540aSrobert   template<typename _Tp>
803*404b540aSrobert     inline complex<_Tp>
804*404b540aSrobert     sin(const complex<_Tp>& __z) { return __complex_sin(__z); }
805*404b540aSrobert #endif
806*404b540aSrobert 
807*404b540aSrobert   // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z.
808*404b540aSrobert   template<typename _Tp>
809*404b540aSrobert     inline complex<_Tp>
810*404b540aSrobert     __complex_sinh(const complex<_Tp>& __z)
811*404b540aSrobert     {
812*404b540aSrobert       const _Tp __x = __z.real();
813*404b540aSrobert       const _Tp  __y = __z.imag();
814*404b540aSrobert       return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
815*404b540aSrobert     }
816*404b540aSrobert 
817*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
818*404b540aSrobert   inline __complex__ float
819*404b540aSrobert   __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); }
820*404b540aSrobert 
821*404b540aSrobert   inline __complex__ double
822*404b540aSrobert   __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); }
823*404b540aSrobert 
824*404b540aSrobert   inline __complex__ long double
825*404b540aSrobert   __complex_sinh(const __complex__ long double& __z)
826*404b540aSrobert   { return __builtin_csinhl(__z); }
827*404b540aSrobert 
828*404b540aSrobert   template<typename _Tp>
829*404b540aSrobert     inline complex<_Tp>
830*404b540aSrobert     sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); }
831*404b540aSrobert #else
832*404b540aSrobert   template<typename _Tp>
833*404b540aSrobert     inline complex<_Tp>
834*404b540aSrobert     sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); }
835*404b540aSrobert #endif
836*404b540aSrobert 
837*404b540aSrobert   // 26.2.8/13 sqrt(__z): Returns the complex square root of __z.
838*404b540aSrobert   //                     The branch cut is on the negative axis.
839*404b540aSrobert   template<typename _Tp>
840*404b540aSrobert     complex<_Tp>
841*404b540aSrobert     __complex_sqrt(const complex<_Tp>& __z)
842*404b540aSrobert     {
843*404b540aSrobert       _Tp __x = __z.real();
844*404b540aSrobert       _Tp __y = __z.imag();
845*404b540aSrobert 
846*404b540aSrobert       if (__x == _Tp())
847*404b540aSrobert         {
848*404b540aSrobert           _Tp __t = sqrt(abs(__y) / 2);
849*404b540aSrobert           return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
850*404b540aSrobert         }
851*404b540aSrobert       else
852*404b540aSrobert         {
853*404b540aSrobert           _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
854*404b540aSrobert           _Tp __u = __t / 2;
855*404b540aSrobert           return __x > _Tp()
856*404b540aSrobert             ? complex<_Tp>(__u, __y / __t)
857*404b540aSrobert             : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
858*404b540aSrobert         }
859*404b540aSrobert     }
860*404b540aSrobert 
861*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
862*404b540aSrobert   inline __complex__ float
863*404b540aSrobert   __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); }
864*404b540aSrobert 
865*404b540aSrobert   inline __complex__ double
866*404b540aSrobert   __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); }
867*404b540aSrobert 
868*404b540aSrobert   inline __complex__ long double
869*404b540aSrobert   __complex_sqrt(const __complex__ long double& __z)
870*404b540aSrobert   { return __builtin_csqrtl(__z); }
871*404b540aSrobert 
872*404b540aSrobert   template<typename _Tp>
873*404b540aSrobert     inline complex<_Tp>
874*404b540aSrobert     sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); }
875*404b540aSrobert #else
876*404b540aSrobert   template<typename _Tp>
877*404b540aSrobert     inline complex<_Tp>
878*404b540aSrobert     sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); }
879*404b540aSrobert #endif
880*404b540aSrobert 
881*404b540aSrobert   // 26.2.8/14 tan(__z):  Return the complex tangent of __z.
882*404b540aSrobert 
883*404b540aSrobert   template<typename _Tp>
884*404b540aSrobert     inline complex<_Tp>
885*404b540aSrobert     __complex_tan(const complex<_Tp>& __z)
886*404b540aSrobert     { return std::sin(__z) / std::cos(__z); }
887*404b540aSrobert 
888*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
889*404b540aSrobert   inline __complex__ float
890*404b540aSrobert   __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); }
891*404b540aSrobert 
892*404b540aSrobert   inline __complex__ double
893*404b540aSrobert   __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); }
894*404b540aSrobert 
895*404b540aSrobert   inline __complex__ long double
896*404b540aSrobert   __complex_tan(const __complex__ long double& __z)
897*404b540aSrobert   { return __builtin_ctanl(__z); }
898*404b540aSrobert 
899*404b540aSrobert   template<typename _Tp>
900*404b540aSrobert     inline complex<_Tp>
901*404b540aSrobert     tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); }
902*404b540aSrobert #else
903*404b540aSrobert   template<typename _Tp>
904*404b540aSrobert     inline complex<_Tp>
905*404b540aSrobert     tan(const complex<_Tp>& __z) { return __complex_tan(__z); }
906*404b540aSrobert #endif
907*404b540aSrobert 
908*404b540aSrobert 
909*404b540aSrobert   // 26.2.8/15 tanh(__z):  Returns the hyperbolic tangent of __z.
910*404b540aSrobert 
911*404b540aSrobert   template<typename _Tp>
912*404b540aSrobert     inline complex<_Tp>
913*404b540aSrobert     __complex_tanh(const complex<_Tp>& __z)
914*404b540aSrobert     { return std::sinh(__z) / std::cosh(__z); }
915*404b540aSrobert 
916*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
917*404b540aSrobert   inline __complex__ float
918*404b540aSrobert   __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); }
919*404b540aSrobert 
920*404b540aSrobert   inline __complex__ double
921*404b540aSrobert   __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); }
922*404b540aSrobert 
923*404b540aSrobert   inline __complex__ long double
924*404b540aSrobert   __complex_tanh(const __complex__ long double& __z)
925*404b540aSrobert   { return __builtin_ctanhl(__z); }
926*404b540aSrobert 
927*404b540aSrobert   template<typename _Tp>
928*404b540aSrobert     inline complex<_Tp>
929*404b540aSrobert     tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); }
930*404b540aSrobert #else
931*404b540aSrobert   template<typename _Tp>
932*404b540aSrobert     inline complex<_Tp>
933*404b540aSrobert     tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); }
934*404b540aSrobert #endif
935*404b540aSrobert 
936*404b540aSrobert 
937*404b540aSrobert   // 26.2.8/9  pow(__x, __y): Returns the complex power base of __x
938*404b540aSrobert   //                          raised to the __y-th power.  The branch
939*404b540aSrobert   //                          cut is on the negative axis.
940*404b540aSrobert   template<typename _Tp>
941*404b540aSrobert     inline complex<_Tp>
942*404b540aSrobert     pow(const complex<_Tp>& __z, int __n)
943*404b540aSrobert     { return std::__pow_helper(__z, __n); }
944*404b540aSrobert 
945*404b540aSrobert   template<typename _Tp>
946*404b540aSrobert     complex<_Tp>
947*404b540aSrobert     pow(const complex<_Tp>& __x, const _Tp& __y)
948*404b540aSrobert     {
949*404b540aSrobert #ifndef _GLIBCXX_USE_C99_COMPLEX
950*404b540aSrobert       if (__x == _Tp())
951*404b540aSrobert 	return _Tp();
952*404b540aSrobert #endif
953*404b540aSrobert       if (__x.imag() == _Tp() && __x.real() > _Tp())
954*404b540aSrobert         return pow(__x.real(), __y);
955*404b540aSrobert 
956*404b540aSrobert       complex<_Tp> __t = std::log(__x);
957*404b540aSrobert       return std::polar(exp(__y * __t.real()), __y * __t.imag());
958*404b540aSrobert     }
959*404b540aSrobert 
960*404b540aSrobert   template<typename _Tp>
961*404b540aSrobert     inline complex<_Tp>
962*404b540aSrobert     __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
963*404b540aSrobert     { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); }
964*404b540aSrobert 
965*404b540aSrobert #if _GLIBCXX_USE_C99_COMPLEX
966*404b540aSrobert   inline __complex__ float
967*404b540aSrobert   __complex_pow(__complex__ float __x, __complex__ float __y)
968*404b540aSrobert   { return __builtin_cpowf(__x, __y); }
969*404b540aSrobert 
970*404b540aSrobert   inline __complex__ double
971*404b540aSrobert   __complex_pow(__complex__ double __x, __complex__ double __y)
972*404b540aSrobert   { return __builtin_cpow(__x, __y); }
973*404b540aSrobert 
974*404b540aSrobert   inline __complex__ long double
975*404b540aSrobert   __complex_pow(const __complex__ long double& __x,
976*404b540aSrobert 		const __complex__ long double& __y)
977*404b540aSrobert   { return __builtin_cpowl(__x, __y); }
978*404b540aSrobert 
979*404b540aSrobert   template<typename _Tp>
980*404b540aSrobert     inline complex<_Tp>
981*404b540aSrobert     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
982*404b540aSrobert     { return __complex_pow(__x.__rep(), __y.__rep()); }
983*404b540aSrobert #else
984*404b540aSrobert   template<typename _Tp>
985*404b540aSrobert     inline complex<_Tp>
986*404b540aSrobert     pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
987*404b540aSrobert     { return __complex_pow(__x, __y); }
988*404b540aSrobert #endif
989*404b540aSrobert 
990*404b540aSrobert   template<typename _Tp>
991*404b540aSrobert     inline complex<_Tp>
992*404b540aSrobert     pow(const _Tp& __x, const complex<_Tp>& __y)
993*404b540aSrobert     {
994*404b540aSrobert       return __x > _Tp() ? std::polar(pow(__x, __y.real()),
995*404b540aSrobert 				      __y.imag() * log(__x))
996*404b540aSrobert 	                 : std::pow(complex<_Tp>(__x, _Tp()), __y);
997*404b540aSrobert     }
998*404b540aSrobert 
999*404b540aSrobert   // 26.2.3  complex specializations
1000*404b540aSrobert   // complex<float> specialization
1001*404b540aSrobert   template<>
1002*404b540aSrobert     struct complex<float>
1003*404b540aSrobert     {
1004*404b540aSrobert       typedef float value_type;
1005*404b540aSrobert       typedef __complex__ float _ComplexT;
1006*404b540aSrobert 
1007*404b540aSrobert       complex(_ComplexT __z) : _M_value(__z) { }
1008*404b540aSrobert 
1009*404b540aSrobert       complex(float = 0.0f, float = 0.0f);
1010*404b540aSrobert 
1011*404b540aSrobert       explicit complex(const complex<double>&);
1012*404b540aSrobert       explicit complex(const complex<long double>&);
1013*404b540aSrobert 
1014*404b540aSrobert       float& real();
1015*404b540aSrobert       const float& real() const;
1016*404b540aSrobert       float& imag();
1017*404b540aSrobert       const float& imag() const;
1018*404b540aSrobert 
1019*404b540aSrobert       complex<float>& operator=(float);
1020*404b540aSrobert       complex<float>& operator+=(float);
1021*404b540aSrobert       complex<float>& operator-=(float);
1022*404b540aSrobert       complex<float>& operator*=(float);
1023*404b540aSrobert       complex<float>& operator/=(float);
1024*404b540aSrobert 
1025*404b540aSrobert       // Let's the compiler synthetize the copy and assignment
1026*404b540aSrobert       // operator.  It always does a pretty good job.
1027*404b540aSrobert       // complex& operator= (const complex&);
1028*404b540aSrobert       template<typename _Tp>
1029*404b540aSrobert         complex<float>&operator=(const complex<_Tp>&);
1030*404b540aSrobert       template<typename _Tp>
1031*404b540aSrobert         complex<float>& operator+=(const complex<_Tp>&);
1032*404b540aSrobert       template<class _Tp>
1033*404b540aSrobert         complex<float>& operator-=(const complex<_Tp>&);
1034*404b540aSrobert       template<class _Tp>
1035*404b540aSrobert         complex<float>& operator*=(const complex<_Tp>&);
1036*404b540aSrobert       template<class _Tp>
1037*404b540aSrobert         complex<float>&operator/=(const complex<_Tp>&);
1038*404b540aSrobert 
1039*404b540aSrobert       const _ComplexT& __rep() const { return _M_value; }
1040*404b540aSrobert 
1041*404b540aSrobert     private:
1042*404b540aSrobert       _ComplexT _M_value;
1043*404b540aSrobert     };
1044*404b540aSrobert 
1045*404b540aSrobert   inline float&
1046*404b540aSrobert   complex<float>::real()
1047*404b540aSrobert   { return __real__ _M_value; }
1048*404b540aSrobert 
1049*404b540aSrobert   inline const float&
1050*404b540aSrobert   complex<float>::real() const
1051*404b540aSrobert   { return __real__ _M_value; }
1052*404b540aSrobert 
1053*404b540aSrobert   inline float&
1054*404b540aSrobert   complex<float>::imag()
1055*404b540aSrobert   { return __imag__ _M_value; }
1056*404b540aSrobert 
1057*404b540aSrobert   inline const float&
1058*404b540aSrobert   complex<float>::imag() const
1059*404b540aSrobert   { return __imag__ _M_value; }
1060*404b540aSrobert 
1061*404b540aSrobert   inline
1062*404b540aSrobert   complex<float>::complex(float r, float i)
1063*404b540aSrobert   {
1064*404b540aSrobert     __real__ _M_value = r;
1065*404b540aSrobert     __imag__ _M_value = i;
1066*404b540aSrobert   }
1067*404b540aSrobert 
1068*404b540aSrobert   inline complex<float>&
1069*404b540aSrobert   complex<float>::operator=(float __f)
1070*404b540aSrobert   {
1071*404b540aSrobert     __real__ _M_value = __f;
1072*404b540aSrobert     __imag__ _M_value = 0.0f;
1073*404b540aSrobert     return *this;
1074*404b540aSrobert   }
1075*404b540aSrobert 
1076*404b540aSrobert   inline complex<float>&
1077*404b540aSrobert   complex<float>::operator+=(float __f)
1078*404b540aSrobert   {
1079*404b540aSrobert     __real__ _M_value += __f;
1080*404b540aSrobert     return *this;
1081*404b540aSrobert   }
1082*404b540aSrobert 
1083*404b540aSrobert   inline complex<float>&
1084*404b540aSrobert   complex<float>::operator-=(float __f)
1085*404b540aSrobert   {
1086*404b540aSrobert     __real__ _M_value -= __f;
1087*404b540aSrobert     return *this;
1088*404b540aSrobert   }
1089*404b540aSrobert 
1090*404b540aSrobert   inline complex<float>&
1091*404b540aSrobert   complex<float>::operator*=(float __f)
1092*404b540aSrobert   {
1093*404b540aSrobert     _M_value *= __f;
1094*404b540aSrobert     return *this;
1095*404b540aSrobert   }
1096*404b540aSrobert 
1097*404b540aSrobert   inline complex<float>&
1098*404b540aSrobert   complex<float>::operator/=(float __f)
1099*404b540aSrobert   {
1100*404b540aSrobert     _M_value /= __f;
1101*404b540aSrobert     return *this;
1102*404b540aSrobert   }
1103*404b540aSrobert 
1104*404b540aSrobert   template<typename _Tp>
1105*404b540aSrobert   inline complex<float>&
1106*404b540aSrobert   complex<float>::operator=(const complex<_Tp>& __z)
1107*404b540aSrobert   {
1108*404b540aSrobert     __real__ _M_value = __z.real();
1109*404b540aSrobert     __imag__ _M_value = __z.imag();
1110*404b540aSrobert     return *this;
1111*404b540aSrobert   }
1112*404b540aSrobert 
1113*404b540aSrobert   template<typename _Tp>
1114*404b540aSrobert   inline complex<float>&
1115*404b540aSrobert   complex<float>::operator+=(const complex<_Tp>& __z)
1116*404b540aSrobert   {
1117*404b540aSrobert     __real__ _M_value += __z.real();
1118*404b540aSrobert     __imag__ _M_value += __z.imag();
1119*404b540aSrobert     return *this;
1120*404b540aSrobert   }
1121*404b540aSrobert 
1122*404b540aSrobert   template<typename _Tp>
1123*404b540aSrobert     inline complex<float>&
1124*404b540aSrobert     complex<float>::operator-=(const complex<_Tp>& __z)
1125*404b540aSrobert     {
1126*404b540aSrobert      __real__ _M_value -= __z.real();
1127*404b540aSrobert      __imag__ _M_value -= __z.imag();
1128*404b540aSrobert      return *this;
1129*404b540aSrobert     }
1130*404b540aSrobert 
1131*404b540aSrobert   template<typename _Tp>
1132*404b540aSrobert     inline complex<float>&
1133*404b540aSrobert     complex<float>::operator*=(const complex<_Tp>& __z)
1134*404b540aSrobert     {
1135*404b540aSrobert       _ComplexT __t;
1136*404b540aSrobert       __real__ __t = __z.real();
1137*404b540aSrobert       __imag__ __t = __z.imag();
1138*404b540aSrobert       _M_value *= __t;
1139*404b540aSrobert       return *this;
1140*404b540aSrobert     }
1141*404b540aSrobert 
1142*404b540aSrobert   template<typename _Tp>
1143*404b540aSrobert     inline complex<float>&
1144*404b540aSrobert     complex<float>::operator/=(const complex<_Tp>& __z)
1145*404b540aSrobert     {
1146*404b540aSrobert       _ComplexT __t;
1147*404b540aSrobert       __real__ __t = __z.real();
1148*404b540aSrobert       __imag__ __t = __z.imag();
1149*404b540aSrobert       _M_value /= __t;
1150*404b540aSrobert       return *this;
1151*404b540aSrobert     }
1152*404b540aSrobert 
1153*404b540aSrobert   // 26.2.3  complex specializations
1154*404b540aSrobert   // complex<double> specialization
1155*404b540aSrobert   template<>
1156*404b540aSrobert     struct complex<double>
1157*404b540aSrobert     {
1158*404b540aSrobert       typedef double value_type;
1159*404b540aSrobert       typedef __complex__ double _ComplexT;
1160*404b540aSrobert 
1161*404b540aSrobert       complex(_ComplexT __z) : _M_value(__z) { }
1162*404b540aSrobert 
1163*404b540aSrobert       complex(double = 0.0, double = 0.0);
1164*404b540aSrobert 
1165*404b540aSrobert       complex(const complex<float>&);
1166*404b540aSrobert       explicit complex(const complex<long double>&);
1167*404b540aSrobert 
1168*404b540aSrobert       double& real();
1169*404b540aSrobert       const double& real() const;
1170*404b540aSrobert       double& imag();
1171*404b540aSrobert       const double& imag() const;
1172*404b540aSrobert 
1173*404b540aSrobert       complex<double>& operator=(double);
1174*404b540aSrobert       complex<double>& operator+=(double);
1175*404b540aSrobert       complex<double>& operator-=(double);
1176*404b540aSrobert       complex<double>& operator*=(double);
1177*404b540aSrobert       complex<double>& operator/=(double);
1178*404b540aSrobert 
1179*404b540aSrobert       // The compiler will synthetize this, efficiently.
1180*404b540aSrobert       // complex& operator= (const complex&);
1181*404b540aSrobert       template<typename _Tp>
1182*404b540aSrobert         complex<double>& operator=(const complex<_Tp>&);
1183*404b540aSrobert       template<typename _Tp>
1184*404b540aSrobert         complex<double>& operator+=(const complex<_Tp>&);
1185*404b540aSrobert       template<typename _Tp>
1186*404b540aSrobert         complex<double>& operator-=(const complex<_Tp>&);
1187*404b540aSrobert       template<typename _Tp>
1188*404b540aSrobert         complex<double>& operator*=(const complex<_Tp>&);
1189*404b540aSrobert       template<typename _Tp>
1190*404b540aSrobert         complex<double>& operator/=(const complex<_Tp>&);
1191*404b540aSrobert 
1192*404b540aSrobert       const _ComplexT& __rep() const { return _M_value; }
1193*404b540aSrobert 
1194*404b540aSrobert     private:
1195*404b540aSrobert       _ComplexT _M_value;
1196*404b540aSrobert     };
1197*404b540aSrobert 
1198*404b540aSrobert   inline double&
1199*404b540aSrobert   complex<double>::real()
1200*404b540aSrobert   { return __real__ _M_value; }
1201*404b540aSrobert 
1202*404b540aSrobert   inline const double&
1203*404b540aSrobert   complex<double>::real() const
1204*404b540aSrobert   { return __real__ _M_value; }
1205*404b540aSrobert 
1206*404b540aSrobert   inline double&
1207*404b540aSrobert   complex<double>::imag()
1208*404b540aSrobert   { return __imag__ _M_value; }
1209*404b540aSrobert 
1210*404b540aSrobert   inline const double&
1211*404b540aSrobert   complex<double>::imag() const
1212*404b540aSrobert   { return __imag__ _M_value; }
1213*404b540aSrobert 
1214*404b540aSrobert   inline
1215*404b540aSrobert   complex<double>::complex(double __r, double __i)
1216*404b540aSrobert   {
1217*404b540aSrobert     __real__ _M_value = __r;
1218*404b540aSrobert     __imag__ _M_value = __i;
1219*404b540aSrobert   }
1220*404b540aSrobert 
1221*404b540aSrobert   inline complex<double>&
1222*404b540aSrobert   complex<double>::operator=(double __d)
1223*404b540aSrobert   {
1224*404b540aSrobert     __real__ _M_value = __d;
1225*404b540aSrobert     __imag__ _M_value = 0.0;
1226*404b540aSrobert     return *this;
1227*404b540aSrobert   }
1228*404b540aSrobert 
1229*404b540aSrobert   inline complex<double>&
1230*404b540aSrobert   complex<double>::operator+=(double __d)
1231*404b540aSrobert   {
1232*404b540aSrobert     __real__ _M_value += __d;
1233*404b540aSrobert     return *this;
1234*404b540aSrobert   }
1235*404b540aSrobert 
1236*404b540aSrobert   inline complex<double>&
1237*404b540aSrobert   complex<double>::operator-=(double __d)
1238*404b540aSrobert   {
1239*404b540aSrobert     __real__ _M_value -= __d;
1240*404b540aSrobert     return *this;
1241*404b540aSrobert   }
1242*404b540aSrobert 
1243*404b540aSrobert   inline complex<double>&
1244*404b540aSrobert   complex<double>::operator*=(double __d)
1245*404b540aSrobert   {
1246*404b540aSrobert     _M_value *= __d;
1247*404b540aSrobert     return *this;
1248*404b540aSrobert   }
1249*404b540aSrobert 
1250*404b540aSrobert   inline complex<double>&
1251*404b540aSrobert   complex<double>::operator/=(double __d)
1252*404b540aSrobert   {
1253*404b540aSrobert     _M_value /= __d;
1254*404b540aSrobert     return *this;
1255*404b540aSrobert   }
1256*404b540aSrobert 
1257*404b540aSrobert   template<typename _Tp>
1258*404b540aSrobert     inline complex<double>&
1259*404b540aSrobert     complex<double>::operator=(const complex<_Tp>& __z)
1260*404b540aSrobert     {
1261*404b540aSrobert       __real__ _M_value = __z.real();
1262*404b540aSrobert       __imag__ _M_value = __z.imag();
1263*404b540aSrobert       return *this;
1264*404b540aSrobert     }
1265*404b540aSrobert 
1266*404b540aSrobert   template<typename _Tp>
1267*404b540aSrobert     inline complex<double>&
1268*404b540aSrobert     complex<double>::operator+=(const complex<_Tp>& __z)
1269*404b540aSrobert     {
1270*404b540aSrobert       __real__ _M_value += __z.real();
1271*404b540aSrobert       __imag__ _M_value += __z.imag();
1272*404b540aSrobert       return *this;
1273*404b540aSrobert     }
1274*404b540aSrobert 
1275*404b540aSrobert   template<typename _Tp>
1276*404b540aSrobert     inline complex<double>&
1277*404b540aSrobert     complex<double>::operator-=(const complex<_Tp>& __z)
1278*404b540aSrobert     {
1279*404b540aSrobert       __real__ _M_value -= __z.real();
1280*404b540aSrobert       __imag__ _M_value -= __z.imag();
1281*404b540aSrobert       return *this;
1282*404b540aSrobert     }
1283*404b540aSrobert 
1284*404b540aSrobert   template<typename _Tp>
1285*404b540aSrobert     inline complex<double>&
1286*404b540aSrobert     complex<double>::operator*=(const complex<_Tp>& __z)
1287*404b540aSrobert     {
1288*404b540aSrobert       _ComplexT __t;
1289*404b540aSrobert       __real__ __t = __z.real();
1290*404b540aSrobert       __imag__ __t = __z.imag();
1291*404b540aSrobert       _M_value *= __t;
1292*404b540aSrobert       return *this;
1293*404b540aSrobert     }
1294*404b540aSrobert 
1295*404b540aSrobert   template<typename _Tp>
1296*404b540aSrobert     inline complex<double>&
1297*404b540aSrobert     complex<double>::operator/=(const complex<_Tp>& __z)
1298*404b540aSrobert     {
1299*404b540aSrobert       _ComplexT __t;
1300*404b540aSrobert       __real__ __t = __z.real();
1301*404b540aSrobert       __imag__ __t = __z.imag();
1302*404b540aSrobert       _M_value /= __t;
1303*404b540aSrobert       return *this;
1304*404b540aSrobert     }
1305*404b540aSrobert 
1306*404b540aSrobert   // 26.2.3  complex specializations
1307*404b540aSrobert   // complex<long double> specialization
1308*404b540aSrobert   template<>
1309*404b540aSrobert     struct complex<long double>
1310*404b540aSrobert     {
1311*404b540aSrobert       typedef long double value_type;
1312*404b540aSrobert       typedef __complex__ long double _ComplexT;
1313*404b540aSrobert 
1314*404b540aSrobert       complex(_ComplexT __z) : _M_value(__z) { }
1315*404b540aSrobert 
1316*404b540aSrobert       complex(long double = 0.0L, long double = 0.0L);
1317*404b540aSrobert 
1318*404b540aSrobert       complex(const complex<float>&);
1319*404b540aSrobert       complex(const complex<double>&);
1320*404b540aSrobert 
1321*404b540aSrobert       long double& real();
1322*404b540aSrobert       const long double& real() const;
1323*404b540aSrobert       long double& imag();
1324*404b540aSrobert       const long double& imag() const;
1325*404b540aSrobert 
1326*404b540aSrobert       complex<long double>& operator= (long double);
1327*404b540aSrobert       complex<long double>& operator+= (long double);
1328*404b540aSrobert       complex<long double>& operator-= (long double);
1329*404b540aSrobert       complex<long double>& operator*= (long double);
1330*404b540aSrobert       complex<long double>& operator/= (long double);
1331*404b540aSrobert 
1332*404b540aSrobert       // The compiler knows how to do this efficiently
1333*404b540aSrobert       // complex& operator= (const complex&);
1334*404b540aSrobert       template<typename _Tp>
1335*404b540aSrobert         complex<long double>& operator=(const complex<_Tp>&);
1336*404b540aSrobert       template<typename _Tp>
1337*404b540aSrobert         complex<long double>& operator+=(const complex<_Tp>&);
1338*404b540aSrobert       template<typename _Tp>
1339*404b540aSrobert         complex<long double>& operator-=(const complex<_Tp>&);
1340*404b540aSrobert       template<typename _Tp>
1341*404b540aSrobert         complex<long double>& operator*=(const complex<_Tp>&);
1342*404b540aSrobert       template<typename _Tp>
1343*404b540aSrobert         complex<long double>& operator/=(const complex<_Tp>&);
1344*404b540aSrobert 
1345*404b540aSrobert       const _ComplexT& __rep() const { return _M_value; }
1346*404b540aSrobert 
1347*404b540aSrobert     private:
1348*404b540aSrobert       _ComplexT _M_value;
1349*404b540aSrobert     };
1350*404b540aSrobert 
1351*404b540aSrobert   inline
1352*404b540aSrobert   complex<long double>::complex(long double __r, long double __i)
1353*404b540aSrobert   {
1354*404b540aSrobert     __real__ _M_value = __r;
1355*404b540aSrobert     __imag__ _M_value = __i;
1356*404b540aSrobert   }
1357*404b540aSrobert 
1358*404b540aSrobert   inline long double&
1359*404b540aSrobert   complex<long double>::real()
1360*404b540aSrobert   { return __real__ _M_value; }
1361*404b540aSrobert 
1362*404b540aSrobert   inline const long double&
1363*404b540aSrobert   complex<long double>::real() const
1364*404b540aSrobert   { return __real__ _M_value; }
1365*404b540aSrobert 
1366*404b540aSrobert   inline long double&
1367*404b540aSrobert   complex<long double>::imag()
1368*404b540aSrobert   { return __imag__ _M_value; }
1369*404b540aSrobert 
1370*404b540aSrobert   inline const long double&
1371*404b540aSrobert   complex<long double>::imag() const
1372*404b540aSrobert   { return __imag__ _M_value; }
1373*404b540aSrobert 
1374*404b540aSrobert   inline complex<long double>&
1375*404b540aSrobert   complex<long double>::operator=(long double __r)
1376*404b540aSrobert   {
1377*404b540aSrobert     __real__ _M_value = __r;
1378*404b540aSrobert     __imag__ _M_value = 0.0L;
1379*404b540aSrobert     return *this;
1380*404b540aSrobert   }
1381*404b540aSrobert 
1382*404b540aSrobert   inline complex<long double>&
1383*404b540aSrobert   complex<long double>::operator+=(long double __r)
1384*404b540aSrobert   {
1385*404b540aSrobert     __real__ _M_value += __r;
1386*404b540aSrobert     return *this;
1387*404b540aSrobert   }
1388*404b540aSrobert 
1389*404b540aSrobert   inline complex<long double>&
1390*404b540aSrobert   complex<long double>::operator-=(long double __r)
1391*404b540aSrobert   {
1392*404b540aSrobert     __real__ _M_value -= __r;
1393*404b540aSrobert     return *this;
1394*404b540aSrobert   }
1395*404b540aSrobert 
1396*404b540aSrobert   inline complex<long double>&
1397*404b540aSrobert   complex<long double>::operator*=(long double __r)
1398*404b540aSrobert   {
1399*404b540aSrobert     _M_value *= __r;
1400*404b540aSrobert     return *this;
1401*404b540aSrobert   }
1402*404b540aSrobert 
1403*404b540aSrobert   inline complex<long double>&
1404*404b540aSrobert   complex<long double>::operator/=(long double __r)
1405*404b540aSrobert   {
1406*404b540aSrobert     _M_value /= __r;
1407*404b540aSrobert     return *this;
1408*404b540aSrobert   }
1409*404b540aSrobert 
1410*404b540aSrobert   template<typename _Tp>
1411*404b540aSrobert     inline complex<long double>&
1412*404b540aSrobert     complex<long double>::operator=(const complex<_Tp>& __z)
1413*404b540aSrobert     {
1414*404b540aSrobert       __real__ _M_value = __z.real();
1415*404b540aSrobert       __imag__ _M_value = __z.imag();
1416*404b540aSrobert       return *this;
1417*404b540aSrobert     }
1418*404b540aSrobert 
1419*404b540aSrobert   template<typename _Tp>
1420*404b540aSrobert     inline complex<long double>&
1421*404b540aSrobert     complex<long double>::operator+=(const complex<_Tp>& __z)
1422*404b540aSrobert     {
1423*404b540aSrobert       __real__ _M_value += __z.real();
1424*404b540aSrobert       __imag__ _M_value += __z.imag();
1425*404b540aSrobert       return *this;
1426*404b540aSrobert     }
1427*404b540aSrobert 
1428*404b540aSrobert   template<typename _Tp>
1429*404b540aSrobert     inline complex<long double>&
1430*404b540aSrobert     complex<long double>::operator-=(const complex<_Tp>& __z)
1431*404b540aSrobert     {
1432*404b540aSrobert       __real__ _M_value -= __z.real();
1433*404b540aSrobert       __imag__ _M_value -= __z.imag();
1434*404b540aSrobert       return *this;
1435*404b540aSrobert     }
1436*404b540aSrobert 
1437*404b540aSrobert   template<typename _Tp>
1438*404b540aSrobert     inline complex<long double>&
1439*404b540aSrobert     complex<long double>::operator*=(const complex<_Tp>& __z)
1440*404b540aSrobert     {
1441*404b540aSrobert       _ComplexT __t;
1442*404b540aSrobert       __real__ __t = __z.real();
1443*404b540aSrobert       __imag__ __t = __z.imag();
1444*404b540aSrobert       _M_value *= __t;
1445*404b540aSrobert       return *this;
1446*404b540aSrobert     }
1447*404b540aSrobert 
1448*404b540aSrobert   template<typename _Tp>
1449*404b540aSrobert     inline complex<long double>&
1450*404b540aSrobert     complex<long double>::operator/=(const complex<_Tp>& __z)
1451*404b540aSrobert     {
1452*404b540aSrobert       _ComplexT __t;
1453*404b540aSrobert       __real__ __t = __z.real();
1454*404b540aSrobert       __imag__ __t = __z.imag();
1455*404b540aSrobert       _M_value /= __t;
1456*404b540aSrobert       return *this;
1457*404b540aSrobert     }
1458*404b540aSrobert 
1459*404b540aSrobert   // These bits have to be at the end of this file, so that the
1460*404b540aSrobert   // specializations have all been defined.
1461*404b540aSrobert   // ??? No, they have to be there because of compiler limitation at
1462*404b540aSrobert   // inlining.  It suffices that class specializations be defined.
1463*404b540aSrobert   inline
1464*404b540aSrobert   complex<float>::complex(const complex<double>& __z)
1465*404b540aSrobert   : _M_value(__z.__rep()) { }
1466*404b540aSrobert 
1467*404b540aSrobert   inline
1468*404b540aSrobert   complex<float>::complex(const complex<long double>& __z)
1469*404b540aSrobert   : _M_value(__z.__rep()) { }
1470*404b540aSrobert 
1471*404b540aSrobert   inline
1472*404b540aSrobert   complex<double>::complex(const complex<float>& __z)
1473*404b540aSrobert   : _M_value(__z.__rep()) { }
1474*404b540aSrobert 
1475*404b540aSrobert   inline
1476*404b540aSrobert   complex<double>::complex(const complex<long double>& __z)
1477*404b540aSrobert     : _M_value(__z.__rep()) { }
1478*404b540aSrobert 
1479*404b540aSrobert   inline
1480*404b540aSrobert   complex<long double>::complex(const complex<float>& __z)
1481*404b540aSrobert   : _M_value(__z.__rep()) { }
1482*404b540aSrobert 
1483*404b540aSrobert   inline
1484*404b540aSrobert   complex<long double>::complex(const complex<double>& __z)
1485*404b540aSrobert   : _M_value(__z.__rep()) { }
1486*404b540aSrobert 
1487*404b540aSrobert _GLIBCXX_END_NAMESPACE
1488*404b540aSrobert 
1489*404b540aSrobert #endif	/* _GLIBCXX_COMPLEX */
1490