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