xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/std/complex (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino// The template and inlines for the -*- C++ -*- complex number classes.
2e4b17023SJohn Marino
3*5ce9237cSJohn Marino// Copyright (C) 1997-2013 Free Software Foundation, Inc.
4e4b17023SJohn Marino//
5e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library.  This library is free
6e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the
7e4b17023SJohn Marino// terms of the GNU General Public License as published by the
8e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option)
9e4b17023SJohn Marino// any later version.
10e4b17023SJohn Marino
11e4b17023SJohn Marino// This library is distributed in the hope that it will be useful,
12e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of
13e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e4b17023SJohn Marino// GNU General Public License for more details.
15e4b17023SJohn Marino
16e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional
17e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version
18e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation.
19e4b17023SJohn Marino
20e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and
21e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program;
22e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23e4b17023SJohn Marino// <http://www.gnu.org/licenses/>.
24e4b17023SJohn Marino
25e4b17023SJohn Marino/** @file include/complex
26e4b17023SJohn Marino *  This is a Standard C++ Library header.
27e4b17023SJohn Marino */
28e4b17023SJohn Marino
29e4b17023SJohn Marino//
30e4b17023SJohn Marino// ISO C++ 14882: 26.2  Complex Numbers
31e4b17023SJohn Marino// Note: this is not a conforming implementation.
32e4b17023SJohn Marino// Initially implemented by Ulrich Drepper <drepper@cygnus.com>
33e4b17023SJohn Marino// Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
34e4b17023SJohn Marino//
35e4b17023SJohn Marino
36e4b17023SJohn Marino#ifndef _GLIBCXX_COMPLEX
37e4b17023SJohn Marino#define _GLIBCXX_COMPLEX 1
38e4b17023SJohn Marino
39e4b17023SJohn Marino#pragma GCC system_header
40e4b17023SJohn Marino
41e4b17023SJohn Marino#include <bits/c++config.h>
42e4b17023SJohn Marino#include <bits/cpp_type_traits.h>
43e4b17023SJohn Marino#include <ext/type_traits.h>
44e4b17023SJohn Marino#include <cmath>
45e4b17023SJohn Marino#include <sstream>
46e4b17023SJohn Marino
47e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
48e4b17023SJohn Marino{
49e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION
50e4b17023SJohn Marino
51e4b17023SJohn Marino  /**
52e4b17023SJohn Marino   * @defgroup complex_numbers Complex Numbers
53e4b17023SJohn Marino   * @ingroup numerics
54e4b17023SJohn Marino   *
55e4b17023SJohn Marino   * Classes and functions for complex numbers.
56e4b17023SJohn Marino   * @{
57e4b17023SJohn Marino   */
58e4b17023SJohn Marino
59e4b17023SJohn Marino  // Forward declarations.
60e4b17023SJohn Marino  template<typename _Tp> class complex;
61e4b17023SJohn Marino  template<> class complex<float>;
62e4b17023SJohn Marino  template<> class complex<double>;
63e4b17023SJohn Marino  template<> class complex<long double>;
64e4b17023SJohn Marino
65e4b17023SJohn Marino  ///  Return magnitude of @a z.
66e4b17023SJohn Marino  template<typename _Tp> _Tp abs(const complex<_Tp>&);
67e4b17023SJohn Marino  ///  Return phase angle of @a z.
68e4b17023SJohn Marino  template<typename _Tp> _Tp arg(const complex<_Tp>&);
69e4b17023SJohn Marino  ///  Return @a z magnitude squared.
70e4b17023SJohn Marino  template<typename _Tp> _Tp norm(const complex<_Tp>&);
71e4b17023SJohn Marino
72e4b17023SJohn Marino  ///  Return complex conjugate of @a z.
73e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&);
74e4b17023SJohn Marino  ///  Return complex with magnitude @a rho and angle @a theta.
75e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0);
76e4b17023SJohn Marino
77e4b17023SJohn Marino  // Transcendentals:
78e4b17023SJohn Marino  /// Return complex cosine of @a z.
79e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&);
80e4b17023SJohn Marino  /// Return complex hyperbolic cosine of @a z.
81e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&);
82e4b17023SJohn Marino  /// Return complex base e exponential of @a z.
83e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&);
84e4b17023SJohn Marino  /// Return complex natural logarithm of @a z.
85e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> log(const complex<_Tp>&);
86e4b17023SJohn Marino  /// Return complex base 10 logarithm of @a z.
87e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&);
88e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__
89e4b17023SJohn Marino  // DR 844.
90e4b17023SJohn Marino  /// Return @a x to the @a y'th power.
91e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int);
92e4b17023SJohn Marino#endif
93e4b17023SJohn Marino  /// Return @a x to the @a y'th power.
94e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&);
95e4b17023SJohn Marino  /// Return @a x to the @a y'th power.
96e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&,
97e4b17023SJohn Marino                                          const complex<_Tp>&);
98e4b17023SJohn Marino  /// Return @a x to the @a y'th power.
99e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&);
100e4b17023SJohn Marino  /// Return complex sine of @a z.
101e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&);
102e4b17023SJohn Marino  /// Return complex hyperbolic sine of @a z.
103e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&);
104e4b17023SJohn Marino  /// Return complex square root of @a z.
105e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&);
106e4b17023SJohn Marino  /// Return complex tangent of @a z.
107e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&);
108e4b17023SJohn Marino  /// Return complex hyperbolic tangent of @a z.
109e4b17023SJohn Marino  template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&);
110e4b17023SJohn Marino
111e4b17023SJohn Marino
112e4b17023SJohn Marino  // 26.2.2  Primary template class complex
113e4b17023SJohn Marino  /**
114e4b17023SJohn Marino   *  Template to represent complex numbers.
115e4b17023SJohn Marino   *
116e4b17023SJohn Marino   *  Specializations for float, double, and long double are part of the
117e4b17023SJohn Marino   *  library.  Results with any other type are not guaranteed.
118e4b17023SJohn Marino   *
119e4b17023SJohn Marino   *  @param  Tp  Type of real and imaginary values.
120e4b17023SJohn Marino  */
121e4b17023SJohn Marino  template<typename _Tp>
122e4b17023SJohn Marino    struct complex
123e4b17023SJohn Marino    {
124e4b17023SJohn Marino      /// Value typedef.
125e4b17023SJohn Marino      typedef _Tp value_type;
126e4b17023SJohn Marino
127e4b17023SJohn Marino      ///  Default constructor.  First parameter is x, second parameter is y.
128e4b17023SJohn Marino      ///  Unspecified parameters default to 0.
129e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp())
130e4b17023SJohn Marino      : _M_real(__r), _M_imag(__i) { }
131e4b17023SJohn Marino
132e4b17023SJohn Marino      // Lets the compiler synthesize the copy constructor
133e4b17023SJohn Marino      // complex (const complex<_Tp>&);
134e4b17023SJohn Marino      ///  Copy constructor.
135e4b17023SJohn Marino      template<typename _Up>
136e4b17023SJohn Marino        _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z)
137e4b17023SJohn Marino	: _M_real(__z.real()), _M_imag(__z.imag()) { }
138e4b17023SJohn Marino
139e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
140e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
141e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
142e4b17023SJohn Marino      constexpr _Tp
143e4b17023SJohn Marino      real() { return _M_real; }
144e4b17023SJohn Marino
145e4b17023SJohn Marino      constexpr _Tp
146e4b17023SJohn Marino      imag() { return _M_imag; }
147e4b17023SJohn Marino#else
148e4b17023SJohn Marino      ///  Return real part of complex number.
149e4b17023SJohn Marino      _Tp&
150e4b17023SJohn Marino      real() { return _M_real; }
151e4b17023SJohn Marino
152e4b17023SJohn Marino      ///  Return real part of complex number.
153e4b17023SJohn Marino      const _Tp&
154e4b17023SJohn Marino      real() const { return _M_real; }
155e4b17023SJohn Marino
156e4b17023SJohn Marino      ///  Return imaginary part of complex number.
157e4b17023SJohn Marino      _Tp&
158e4b17023SJohn Marino      imag() { return _M_imag; }
159e4b17023SJohn Marino
160e4b17023SJohn Marino      ///  Return imaginary part of complex number.
161e4b17023SJohn Marino      const _Tp&
162e4b17023SJohn Marino      imag() const { return _M_imag; }
163e4b17023SJohn Marino#endif
164e4b17023SJohn Marino
165e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
166e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
167e4b17023SJohn Marino      void
168e4b17023SJohn Marino      real(_Tp __val) { _M_real = __val; }
169e4b17023SJohn Marino
170e4b17023SJohn Marino      void
171e4b17023SJohn Marino      imag(_Tp __val) { _M_imag = __val; }
172e4b17023SJohn Marino
173e4b17023SJohn Marino      /// Assign this complex number to scalar @a t.
174e4b17023SJohn Marino      complex<_Tp>& operator=(const _Tp&);
175e4b17023SJohn Marino
176e4b17023SJohn Marino      /// Add @a t to this complex number.
177e4b17023SJohn Marino      // 26.2.5/1
178e4b17023SJohn Marino      complex<_Tp>&
179e4b17023SJohn Marino      operator+=(const _Tp& __t)
180e4b17023SJohn Marino      {
181e4b17023SJohn Marino	_M_real += __t;
182e4b17023SJohn Marino	return *this;
183e4b17023SJohn Marino      }
184e4b17023SJohn Marino
185e4b17023SJohn Marino      /// Subtract @a t from this complex number.
186e4b17023SJohn Marino      // 26.2.5/3
187e4b17023SJohn Marino      complex<_Tp>&
188e4b17023SJohn Marino      operator-=(const _Tp& __t)
189e4b17023SJohn Marino      {
190e4b17023SJohn Marino	_M_real -= __t;
191e4b17023SJohn Marino	return *this;
192e4b17023SJohn Marino      }
193e4b17023SJohn Marino
194e4b17023SJohn Marino      /// Multiply this complex number by @a t.
195e4b17023SJohn Marino      complex<_Tp>& operator*=(const _Tp&);
196e4b17023SJohn Marino      /// Divide this complex number by @a t.
197e4b17023SJohn Marino      complex<_Tp>& operator/=(const _Tp&);
198e4b17023SJohn Marino
199e4b17023SJohn Marino      // Lets the compiler synthesize the
200e4b17023SJohn Marino      // copy and assignment operator
201e4b17023SJohn Marino      // complex<_Tp>& operator= (const complex<_Tp>&);
202e4b17023SJohn Marino      /// Assign this complex number to complex @a z.
203e4b17023SJohn Marino      template<typename _Up>
204e4b17023SJohn Marino        complex<_Tp>& operator=(const complex<_Up>&);
205e4b17023SJohn Marino      /// Add @a z to this complex number.
206e4b17023SJohn Marino      template<typename _Up>
207e4b17023SJohn Marino        complex<_Tp>& operator+=(const complex<_Up>&);
208e4b17023SJohn Marino      /// Subtract @a z from this complex number.
209e4b17023SJohn Marino      template<typename _Up>
210e4b17023SJohn Marino        complex<_Tp>& operator-=(const complex<_Up>&);
211e4b17023SJohn Marino      /// Multiply this complex number by @a z.
212e4b17023SJohn Marino      template<typename _Up>
213e4b17023SJohn Marino        complex<_Tp>& operator*=(const complex<_Up>&);
214e4b17023SJohn Marino      /// Divide this complex number by @a z.
215e4b17023SJohn Marino      template<typename _Up>
216e4b17023SJohn Marino        complex<_Tp>& operator/=(const complex<_Up>&);
217e4b17023SJohn Marino
218e4b17023SJohn Marino      _GLIBCXX_USE_CONSTEXPR complex __rep() const
219e4b17023SJohn Marino      { return *this; }
220e4b17023SJohn Marino
221e4b17023SJohn Marino    private:
222e4b17023SJohn Marino      _Tp _M_real;
223e4b17023SJohn Marino      _Tp _M_imag;
224e4b17023SJohn Marino    };
225e4b17023SJohn Marino
226e4b17023SJohn Marino  template<typename _Tp>
227e4b17023SJohn Marino    complex<_Tp>&
228e4b17023SJohn Marino    complex<_Tp>::operator=(const _Tp& __t)
229e4b17023SJohn Marino    {
230e4b17023SJohn Marino     _M_real = __t;
231e4b17023SJohn Marino     _M_imag = _Tp();
232e4b17023SJohn Marino     return *this;
233e4b17023SJohn Marino    }
234e4b17023SJohn Marino
235e4b17023SJohn Marino  // 26.2.5/5
236e4b17023SJohn Marino  template<typename _Tp>
237e4b17023SJohn Marino    complex<_Tp>&
238e4b17023SJohn Marino    complex<_Tp>::operator*=(const _Tp& __t)
239e4b17023SJohn Marino    {
240e4b17023SJohn Marino      _M_real *= __t;
241e4b17023SJohn Marino      _M_imag *= __t;
242e4b17023SJohn Marino      return *this;
243e4b17023SJohn Marino    }
244e4b17023SJohn Marino
245e4b17023SJohn Marino  // 26.2.5/7
246e4b17023SJohn Marino  template<typename _Tp>
247e4b17023SJohn Marino    complex<_Tp>&
248e4b17023SJohn Marino    complex<_Tp>::operator/=(const _Tp& __t)
249e4b17023SJohn Marino    {
250e4b17023SJohn Marino      _M_real /= __t;
251e4b17023SJohn Marino      _M_imag /= __t;
252e4b17023SJohn Marino      return *this;
253e4b17023SJohn Marino    }
254e4b17023SJohn Marino
255e4b17023SJohn Marino  template<typename _Tp>
256e4b17023SJohn Marino    template<typename _Up>
257e4b17023SJohn Marino    complex<_Tp>&
258e4b17023SJohn Marino    complex<_Tp>::operator=(const complex<_Up>& __z)
259e4b17023SJohn Marino    {
260e4b17023SJohn Marino      _M_real = __z.real();
261e4b17023SJohn Marino      _M_imag = __z.imag();
262e4b17023SJohn Marino      return *this;
263e4b17023SJohn Marino    }
264e4b17023SJohn Marino
265e4b17023SJohn Marino  // 26.2.5/9
266e4b17023SJohn Marino  template<typename _Tp>
267e4b17023SJohn Marino    template<typename _Up>
268e4b17023SJohn Marino    complex<_Tp>&
269e4b17023SJohn Marino    complex<_Tp>::operator+=(const complex<_Up>& __z)
270e4b17023SJohn Marino    {
271e4b17023SJohn Marino      _M_real += __z.real();
272e4b17023SJohn Marino      _M_imag += __z.imag();
273e4b17023SJohn Marino      return *this;
274e4b17023SJohn Marino    }
275e4b17023SJohn Marino
276e4b17023SJohn Marino  // 26.2.5/11
277e4b17023SJohn Marino  template<typename _Tp>
278e4b17023SJohn Marino    template<typename _Up>
279e4b17023SJohn Marino    complex<_Tp>&
280e4b17023SJohn Marino    complex<_Tp>::operator-=(const complex<_Up>& __z)
281e4b17023SJohn Marino    {
282e4b17023SJohn Marino      _M_real -= __z.real();
283e4b17023SJohn Marino      _M_imag -= __z.imag();
284e4b17023SJohn Marino      return *this;
285e4b17023SJohn Marino    }
286e4b17023SJohn Marino
287e4b17023SJohn Marino  // 26.2.5/13
288e4b17023SJohn Marino  // XXX: This is a grammar school implementation.
289e4b17023SJohn Marino  template<typename _Tp>
290e4b17023SJohn Marino    template<typename _Up>
291e4b17023SJohn Marino    complex<_Tp>&
292e4b17023SJohn Marino    complex<_Tp>::operator*=(const complex<_Up>& __z)
293e4b17023SJohn Marino    {
294e4b17023SJohn Marino      const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
295e4b17023SJohn Marino      _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
296e4b17023SJohn Marino      _M_real = __r;
297e4b17023SJohn Marino      return *this;
298e4b17023SJohn Marino    }
299e4b17023SJohn Marino
300e4b17023SJohn Marino  // 26.2.5/15
301e4b17023SJohn Marino  // XXX: This is a grammar school implementation.
302e4b17023SJohn Marino  template<typename _Tp>
303e4b17023SJohn Marino    template<typename _Up>
304e4b17023SJohn Marino    complex<_Tp>&
305e4b17023SJohn Marino    complex<_Tp>::operator/=(const complex<_Up>& __z)
306e4b17023SJohn Marino    {
307e4b17023SJohn Marino      const _Tp __r =  _M_real * __z.real() + _M_imag * __z.imag();
308e4b17023SJohn Marino      const _Tp __n = std::norm(__z);
309e4b17023SJohn Marino      _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n;
310e4b17023SJohn Marino      _M_real = __r / __n;
311e4b17023SJohn Marino      return *this;
312e4b17023SJohn Marino    }
313e4b17023SJohn Marino
314e4b17023SJohn Marino  // Operators:
315e4b17023SJohn Marino  //@{
316e4b17023SJohn Marino  ///  Return new complex value @a x plus @a y.
317e4b17023SJohn Marino  template<typename _Tp>
318e4b17023SJohn Marino    inline complex<_Tp>
319e4b17023SJohn Marino    operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
320e4b17023SJohn Marino    {
321e4b17023SJohn Marino      complex<_Tp> __r = __x;
322e4b17023SJohn Marino      __r += __y;
323e4b17023SJohn Marino      return __r;
324e4b17023SJohn Marino    }
325e4b17023SJohn Marino
326e4b17023SJohn Marino  template<typename _Tp>
327e4b17023SJohn Marino    inline complex<_Tp>
328e4b17023SJohn Marino    operator+(const complex<_Tp>& __x, const _Tp& __y)
329e4b17023SJohn Marino    {
330e4b17023SJohn Marino      complex<_Tp> __r = __x;
331e4b17023SJohn Marino      __r += __y;
332e4b17023SJohn Marino      return __r;
333e4b17023SJohn Marino    }
334e4b17023SJohn Marino
335e4b17023SJohn Marino  template<typename _Tp>
336e4b17023SJohn Marino    inline complex<_Tp>
337e4b17023SJohn Marino    operator+(const _Tp& __x, const complex<_Tp>& __y)
338e4b17023SJohn Marino    {
339e4b17023SJohn Marino      complex<_Tp> __r = __y;
340e4b17023SJohn Marino      __r += __x;
341e4b17023SJohn Marino      return __r;
342e4b17023SJohn Marino    }
343e4b17023SJohn Marino  //@}
344e4b17023SJohn Marino
345e4b17023SJohn Marino  //@{
346e4b17023SJohn Marino  ///  Return new complex value @a x minus @a y.
347e4b17023SJohn Marino  template<typename _Tp>
348e4b17023SJohn Marino    inline complex<_Tp>
349e4b17023SJohn Marino    operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
350e4b17023SJohn Marino    {
351e4b17023SJohn Marino      complex<_Tp> __r = __x;
352e4b17023SJohn Marino      __r -= __y;
353e4b17023SJohn Marino      return __r;
354e4b17023SJohn Marino    }
355e4b17023SJohn Marino
356e4b17023SJohn Marino  template<typename _Tp>
357e4b17023SJohn Marino    inline complex<_Tp>
358e4b17023SJohn Marino    operator-(const complex<_Tp>& __x, const _Tp& __y)
359e4b17023SJohn Marino    {
360e4b17023SJohn Marino      complex<_Tp> __r = __x;
361e4b17023SJohn Marino      __r -= __y;
362e4b17023SJohn Marino      return __r;
363e4b17023SJohn Marino    }
364e4b17023SJohn Marino
365e4b17023SJohn Marino  template<typename _Tp>
366e4b17023SJohn Marino    inline complex<_Tp>
367e4b17023SJohn Marino    operator-(const _Tp& __x, const complex<_Tp>& __y)
368e4b17023SJohn Marino    {
369e4b17023SJohn Marino      complex<_Tp> __r(__x, -__y.imag());
370e4b17023SJohn Marino      __r -= __y.real();
371e4b17023SJohn Marino      return __r;
372e4b17023SJohn Marino    }
373e4b17023SJohn Marino  //@}
374e4b17023SJohn Marino
375e4b17023SJohn Marino  //@{
376e4b17023SJohn Marino  ///  Return new complex value @a x times @a y.
377e4b17023SJohn Marino  template<typename _Tp>
378e4b17023SJohn Marino    inline complex<_Tp>
379e4b17023SJohn Marino    operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
380e4b17023SJohn Marino    {
381e4b17023SJohn Marino      complex<_Tp> __r = __x;
382e4b17023SJohn Marino      __r *= __y;
383e4b17023SJohn Marino      return __r;
384e4b17023SJohn Marino    }
385e4b17023SJohn Marino
386e4b17023SJohn Marino  template<typename _Tp>
387e4b17023SJohn Marino    inline complex<_Tp>
388e4b17023SJohn Marino    operator*(const complex<_Tp>& __x, const _Tp& __y)
389e4b17023SJohn Marino    {
390e4b17023SJohn Marino      complex<_Tp> __r = __x;
391e4b17023SJohn Marino      __r *= __y;
392e4b17023SJohn Marino      return __r;
393e4b17023SJohn Marino    }
394e4b17023SJohn Marino
395e4b17023SJohn Marino  template<typename _Tp>
396e4b17023SJohn Marino    inline complex<_Tp>
397e4b17023SJohn Marino    operator*(const _Tp& __x, const complex<_Tp>& __y)
398e4b17023SJohn Marino    {
399e4b17023SJohn Marino      complex<_Tp> __r = __y;
400e4b17023SJohn Marino      __r *= __x;
401e4b17023SJohn Marino      return __r;
402e4b17023SJohn Marino    }
403e4b17023SJohn Marino  //@}
404e4b17023SJohn Marino
405e4b17023SJohn Marino  //@{
406e4b17023SJohn Marino  ///  Return new complex value @a x divided by @a y.
407e4b17023SJohn Marino  template<typename _Tp>
408e4b17023SJohn Marino    inline complex<_Tp>
409e4b17023SJohn Marino    operator/(const complex<_Tp>& __x, const complex<_Tp>& __y)
410e4b17023SJohn Marino    {
411e4b17023SJohn Marino      complex<_Tp> __r = __x;
412e4b17023SJohn Marino      __r /= __y;
413e4b17023SJohn Marino      return __r;
414e4b17023SJohn Marino    }
415e4b17023SJohn Marino
416e4b17023SJohn Marino  template<typename _Tp>
417e4b17023SJohn Marino    inline complex<_Tp>
418e4b17023SJohn Marino    operator/(const complex<_Tp>& __x, const _Tp& __y)
419e4b17023SJohn Marino    {
420e4b17023SJohn Marino      complex<_Tp> __r = __x;
421e4b17023SJohn Marino      __r /= __y;
422e4b17023SJohn Marino      return __r;
423e4b17023SJohn Marino    }
424e4b17023SJohn Marino
425e4b17023SJohn Marino  template<typename _Tp>
426e4b17023SJohn Marino    inline complex<_Tp>
427e4b17023SJohn Marino    operator/(const _Tp& __x, const complex<_Tp>& __y)
428e4b17023SJohn Marino    {
429e4b17023SJohn Marino      complex<_Tp> __r = __x;
430e4b17023SJohn Marino      __r /= __y;
431e4b17023SJohn Marino      return __r;
432e4b17023SJohn Marino    }
433e4b17023SJohn Marino  //@}
434e4b17023SJohn Marino
435e4b17023SJohn Marino  ///  Return @a x.
436e4b17023SJohn Marino  template<typename _Tp>
437e4b17023SJohn Marino    inline complex<_Tp>
438e4b17023SJohn Marino    operator+(const complex<_Tp>& __x)
439e4b17023SJohn Marino    { return __x; }
440e4b17023SJohn Marino
441e4b17023SJohn Marino  ///  Return complex negation of @a x.
442e4b17023SJohn Marino  template<typename _Tp>
443e4b17023SJohn Marino    inline complex<_Tp>
444e4b17023SJohn Marino    operator-(const complex<_Tp>& __x)
445e4b17023SJohn Marino    {  return complex<_Tp>(-__x.real(), -__x.imag()); }
446e4b17023SJohn Marino
447e4b17023SJohn Marino  //@{
448e4b17023SJohn Marino  ///  Return true if @a x is equal to @a y.
449e4b17023SJohn Marino  template<typename _Tp>
450e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
451e4b17023SJohn Marino    operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
452e4b17023SJohn Marino    { return __x.real() == __y.real() && __x.imag() == __y.imag(); }
453e4b17023SJohn Marino
454e4b17023SJohn Marino  template<typename _Tp>
455e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
456e4b17023SJohn Marino    operator==(const complex<_Tp>& __x, const _Tp& __y)
457e4b17023SJohn Marino    { return __x.real() == __y && __x.imag() == _Tp(); }
458e4b17023SJohn Marino
459e4b17023SJohn Marino  template<typename _Tp>
460e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
461e4b17023SJohn Marino    operator==(const _Tp& __x, const complex<_Tp>& __y)
462e4b17023SJohn Marino    { return __x == __y.real() && _Tp() == __y.imag(); }
463e4b17023SJohn Marino  //@}
464e4b17023SJohn Marino
465e4b17023SJohn Marino  //@{
466e4b17023SJohn Marino  ///  Return false if @a x is equal to @a y.
467e4b17023SJohn Marino  template<typename _Tp>
468e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
469e4b17023SJohn Marino    operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
470e4b17023SJohn Marino    { return __x.real() != __y.real() || __x.imag() != __y.imag(); }
471e4b17023SJohn Marino
472e4b17023SJohn Marino  template<typename _Tp>
473e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
474e4b17023SJohn Marino    operator!=(const complex<_Tp>& __x, const _Tp& __y)
475e4b17023SJohn Marino    { return __x.real() != __y || __x.imag() != _Tp(); }
476e4b17023SJohn Marino
477e4b17023SJohn Marino  template<typename _Tp>
478e4b17023SJohn Marino    inline _GLIBCXX_CONSTEXPR bool
479e4b17023SJohn Marino    operator!=(const _Tp& __x, const complex<_Tp>& __y)
480e4b17023SJohn Marino    { return __x != __y.real() || _Tp() != __y.imag(); }
481e4b17023SJohn Marino  //@}
482e4b17023SJohn Marino
483e4b17023SJohn Marino  ///  Extraction operator for complex values.
484e4b17023SJohn Marino  template<typename _Tp, typename _CharT, class _Traits>
485e4b17023SJohn Marino    basic_istream<_CharT, _Traits>&
486e4b17023SJohn Marino    operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
487e4b17023SJohn Marino    {
488e4b17023SJohn Marino      _Tp __re_x, __im_x;
489e4b17023SJohn Marino      _CharT __ch;
490e4b17023SJohn Marino      __is >> __ch;
491e4b17023SJohn Marino      if (__ch == '(')
492e4b17023SJohn Marino	{
493e4b17023SJohn Marino	  __is >> __re_x >> __ch;
494e4b17023SJohn Marino	  if (__ch == ',')
495e4b17023SJohn Marino	    {
496e4b17023SJohn Marino	      __is >> __im_x >> __ch;
497e4b17023SJohn Marino	      if (__ch == ')')
498e4b17023SJohn Marino		__x = complex<_Tp>(__re_x, __im_x);
499e4b17023SJohn Marino	      else
500e4b17023SJohn Marino		__is.setstate(ios_base::failbit);
501e4b17023SJohn Marino	    }
502e4b17023SJohn Marino	  else if (__ch == ')')
503e4b17023SJohn Marino	    __x = __re_x;
504e4b17023SJohn Marino	  else
505e4b17023SJohn Marino	    __is.setstate(ios_base::failbit);
506e4b17023SJohn Marino	}
507e4b17023SJohn Marino      else
508e4b17023SJohn Marino	{
509e4b17023SJohn Marino	  __is.putback(__ch);
510e4b17023SJohn Marino	  __is >> __re_x;
511e4b17023SJohn Marino	  __x = __re_x;
512e4b17023SJohn Marino	}
513e4b17023SJohn Marino      return __is;
514e4b17023SJohn Marino    }
515e4b17023SJohn Marino
516e4b17023SJohn Marino  ///  Insertion operator for complex values.
517e4b17023SJohn Marino  template<typename _Tp, typename _CharT, class _Traits>
518e4b17023SJohn Marino    basic_ostream<_CharT, _Traits>&
519e4b17023SJohn Marino    operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
520e4b17023SJohn Marino    {
521e4b17023SJohn Marino      basic_ostringstream<_CharT, _Traits> __s;
522e4b17023SJohn Marino      __s.flags(__os.flags());
523e4b17023SJohn Marino      __s.imbue(__os.getloc());
524e4b17023SJohn Marino      __s.precision(__os.precision());
525e4b17023SJohn Marino      __s << '(' << __x.real() << ',' << __x.imag() << ')';
526e4b17023SJohn Marino      return __os << __s.str();
527e4b17023SJohn Marino    }
528e4b17023SJohn Marino
529e4b17023SJohn Marino  // Values
530e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
531e4b17023SJohn Marino  template<typename _Tp>
532e4b17023SJohn Marino    constexpr _Tp
533e4b17023SJohn Marino    real(const complex<_Tp>& __z)
534e4b17023SJohn Marino    { return __z.real(); }
535e4b17023SJohn Marino
536e4b17023SJohn Marino  template<typename _Tp>
537e4b17023SJohn Marino    constexpr _Tp
538e4b17023SJohn Marino    imag(const complex<_Tp>& __z)
539e4b17023SJohn Marino    { return __z.imag(); }
540e4b17023SJohn Marino#else
541e4b17023SJohn Marino  template<typename _Tp>
542e4b17023SJohn Marino    inline _Tp&
543e4b17023SJohn Marino    real(complex<_Tp>& __z)
544e4b17023SJohn Marino    { return __z.real(); }
545e4b17023SJohn Marino
546e4b17023SJohn Marino  template<typename _Tp>
547e4b17023SJohn Marino    inline const _Tp&
548e4b17023SJohn Marino    real(const complex<_Tp>& __z)
549e4b17023SJohn Marino    { return __z.real(); }
550e4b17023SJohn Marino
551e4b17023SJohn Marino  template<typename _Tp>
552e4b17023SJohn Marino    inline _Tp&
553e4b17023SJohn Marino    imag(complex<_Tp>& __z)
554e4b17023SJohn Marino    { return __z.imag(); }
555e4b17023SJohn Marino
556e4b17023SJohn Marino  template<typename _Tp>
557e4b17023SJohn Marino    inline const _Tp&
558e4b17023SJohn Marino    imag(const complex<_Tp>& __z)
559e4b17023SJohn Marino    { return __z.imag(); }
560e4b17023SJohn Marino#endif
561e4b17023SJohn Marino
562e4b17023SJohn Marino  // 26.2.7/3 abs(__z):  Returns the magnitude of __z.
563e4b17023SJohn Marino  template<typename _Tp>
564e4b17023SJohn Marino    inline _Tp
565e4b17023SJohn Marino    __complex_abs(const complex<_Tp>& __z)
566e4b17023SJohn Marino    {
567e4b17023SJohn Marino      _Tp __x = __z.real();
568e4b17023SJohn Marino      _Tp __y = __z.imag();
569e4b17023SJohn Marino      const _Tp __s = std::max(abs(__x), abs(__y));
570e4b17023SJohn Marino      if (__s == _Tp())  // well ...
571e4b17023SJohn Marino        return __s;
572e4b17023SJohn Marino      __x /= __s;
573e4b17023SJohn Marino      __y /= __s;
574e4b17023SJohn Marino      return __s * sqrt(__x * __x + __y * __y);
575e4b17023SJohn Marino    }
576e4b17023SJohn Marino
577e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
578e4b17023SJohn Marino  inline float
579e4b17023SJohn Marino  __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); }
580e4b17023SJohn Marino
581e4b17023SJohn Marino  inline double
582e4b17023SJohn Marino  __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); }
583e4b17023SJohn Marino
584e4b17023SJohn Marino  inline long double
585e4b17023SJohn Marino  __complex_abs(const __complex__ long double& __z)
586e4b17023SJohn Marino  { return __builtin_cabsl(__z); }
587e4b17023SJohn Marino
588e4b17023SJohn Marino  template<typename _Tp>
589e4b17023SJohn Marino    inline _Tp
590e4b17023SJohn Marino    abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); }
591e4b17023SJohn Marino#else
592e4b17023SJohn Marino  template<typename _Tp>
593e4b17023SJohn Marino    inline _Tp
594e4b17023SJohn Marino    abs(const complex<_Tp>& __z) { return __complex_abs(__z); }
595e4b17023SJohn Marino#endif
596e4b17023SJohn Marino
597e4b17023SJohn Marino
598e4b17023SJohn Marino  // 26.2.7/4: arg(__z): Returns the phase angle of __z.
599e4b17023SJohn Marino  template<typename _Tp>
600e4b17023SJohn Marino    inline _Tp
601e4b17023SJohn Marino    __complex_arg(const complex<_Tp>& __z)
602e4b17023SJohn Marino    { return  atan2(__z.imag(), __z.real()); }
603e4b17023SJohn Marino
604e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
605e4b17023SJohn Marino  inline float
606e4b17023SJohn Marino  __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); }
607e4b17023SJohn Marino
608e4b17023SJohn Marino  inline double
609e4b17023SJohn Marino  __complex_arg(__complex__ double __z) { return __builtin_carg(__z); }
610e4b17023SJohn Marino
611e4b17023SJohn Marino  inline long double
612e4b17023SJohn Marino  __complex_arg(const __complex__ long double& __z)
613e4b17023SJohn Marino  { return __builtin_cargl(__z); }
614e4b17023SJohn Marino
615e4b17023SJohn Marino  template<typename _Tp>
616e4b17023SJohn Marino    inline _Tp
617e4b17023SJohn Marino    arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); }
618e4b17023SJohn Marino#else
619e4b17023SJohn Marino  template<typename _Tp>
620e4b17023SJohn Marino    inline _Tp
621e4b17023SJohn Marino    arg(const complex<_Tp>& __z) { return __complex_arg(__z); }
622e4b17023SJohn Marino#endif
623e4b17023SJohn Marino
624e4b17023SJohn Marino  // 26.2.7/5: norm(__z) returns the squared magnitude of __z.
625e4b17023SJohn Marino  //     As defined, norm() is -not- a norm is the common mathematical
626e4b17023SJohn Marino  //     sens used in numerics.  The helper class _Norm_helper<> tries to
627e4b17023SJohn Marino  //     distinguish between builtin floating point and the rest, so as
628e4b17023SJohn Marino  //     to deliver an answer as close as possible to the real value.
629e4b17023SJohn Marino  template<bool>
630e4b17023SJohn Marino    struct _Norm_helper
631e4b17023SJohn Marino    {
632e4b17023SJohn Marino      template<typename _Tp>
633e4b17023SJohn Marino        static inline _Tp _S_do_it(const complex<_Tp>& __z)
634e4b17023SJohn Marino        {
635e4b17023SJohn Marino          const _Tp __x = __z.real();
636e4b17023SJohn Marino          const _Tp __y = __z.imag();
637e4b17023SJohn Marino          return __x * __x + __y * __y;
638e4b17023SJohn Marino        }
639e4b17023SJohn Marino    };
640e4b17023SJohn Marino
641e4b17023SJohn Marino  template<>
642e4b17023SJohn Marino    struct _Norm_helper<true>
643e4b17023SJohn Marino    {
644e4b17023SJohn Marino      template<typename _Tp>
645e4b17023SJohn Marino        static inline _Tp _S_do_it(const complex<_Tp>& __z)
646e4b17023SJohn Marino        {
647e4b17023SJohn Marino          _Tp __res = std::abs(__z);
648e4b17023SJohn Marino          return __res * __res;
649e4b17023SJohn Marino        }
650e4b17023SJohn Marino    };
651e4b17023SJohn Marino
652e4b17023SJohn Marino  template<typename _Tp>
653e4b17023SJohn Marino    inline _Tp
654e4b17023SJohn Marino    norm(const complex<_Tp>& __z)
655e4b17023SJohn Marino    {
656e4b17023SJohn Marino      return _Norm_helper<__is_floating<_Tp>::__value
657e4b17023SJohn Marino	&& !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
658e4b17023SJohn Marino    }
659e4b17023SJohn Marino
660e4b17023SJohn Marino  template<typename _Tp>
661e4b17023SJohn Marino    inline complex<_Tp>
662e4b17023SJohn Marino    polar(const _Tp& __rho, const _Tp& __theta)
663e4b17023SJohn Marino    { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
664e4b17023SJohn Marino
665e4b17023SJohn Marino  template<typename _Tp>
666e4b17023SJohn Marino    inline complex<_Tp>
667e4b17023SJohn Marino    conj(const complex<_Tp>& __z)
668e4b17023SJohn Marino    { return complex<_Tp>(__z.real(), -__z.imag()); }
669e4b17023SJohn Marino
670e4b17023SJohn Marino  // Transcendentals
671e4b17023SJohn Marino
672e4b17023SJohn Marino  // 26.2.8/1 cos(__z):  Returns the cosine of __z.
673e4b17023SJohn Marino  template<typename _Tp>
674e4b17023SJohn Marino    inline complex<_Tp>
675e4b17023SJohn Marino    __complex_cos(const complex<_Tp>& __z)
676e4b17023SJohn Marino    {
677e4b17023SJohn Marino      const _Tp __x = __z.real();
678e4b17023SJohn Marino      const _Tp __y = __z.imag();
679e4b17023SJohn Marino      return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y));
680e4b17023SJohn Marino    }
681e4b17023SJohn Marino
682e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
683e4b17023SJohn Marino  inline __complex__ float
684e4b17023SJohn Marino  __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); }
685e4b17023SJohn Marino
686e4b17023SJohn Marino  inline __complex__ double
687e4b17023SJohn Marino  __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); }
688e4b17023SJohn Marino
689e4b17023SJohn Marino  inline __complex__ long double
690e4b17023SJohn Marino  __complex_cos(const __complex__ long double& __z)
691e4b17023SJohn Marino  { return __builtin_ccosl(__z); }
692e4b17023SJohn Marino
693e4b17023SJohn Marino  template<typename _Tp>
694e4b17023SJohn Marino    inline complex<_Tp>
695e4b17023SJohn Marino    cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); }
696e4b17023SJohn Marino#else
697e4b17023SJohn Marino  template<typename _Tp>
698e4b17023SJohn Marino    inline complex<_Tp>
699e4b17023SJohn Marino    cos(const complex<_Tp>& __z) { return __complex_cos(__z); }
700e4b17023SJohn Marino#endif
701e4b17023SJohn Marino
702e4b17023SJohn Marino  // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z.
703e4b17023SJohn Marino  template<typename _Tp>
704e4b17023SJohn Marino    inline complex<_Tp>
705e4b17023SJohn Marino    __complex_cosh(const complex<_Tp>& __z)
706e4b17023SJohn Marino    {
707e4b17023SJohn Marino      const _Tp __x = __z.real();
708e4b17023SJohn Marino      const _Tp __y = __z.imag();
709e4b17023SJohn Marino      return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y));
710e4b17023SJohn Marino    }
711e4b17023SJohn Marino
712e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
713e4b17023SJohn Marino  inline __complex__ float
714e4b17023SJohn Marino  __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); }
715e4b17023SJohn Marino
716e4b17023SJohn Marino  inline __complex__ double
717e4b17023SJohn Marino  __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); }
718e4b17023SJohn Marino
719e4b17023SJohn Marino  inline __complex__ long double
720e4b17023SJohn Marino  __complex_cosh(const __complex__ long double& __z)
721e4b17023SJohn Marino  { return __builtin_ccoshl(__z); }
722e4b17023SJohn Marino
723e4b17023SJohn Marino  template<typename _Tp>
724e4b17023SJohn Marino    inline complex<_Tp>
725e4b17023SJohn Marino    cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); }
726e4b17023SJohn Marino#else
727e4b17023SJohn Marino  template<typename _Tp>
728e4b17023SJohn Marino    inline complex<_Tp>
729e4b17023SJohn Marino    cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); }
730e4b17023SJohn Marino#endif
731e4b17023SJohn Marino
732e4b17023SJohn Marino  // 26.2.8/3 exp(__z): Returns the complex base e exponential of x
733e4b17023SJohn Marino  template<typename _Tp>
734e4b17023SJohn Marino    inline complex<_Tp>
735e4b17023SJohn Marino    __complex_exp(const complex<_Tp>& __z)
736e4b17023SJohn Marino    { return std::polar(exp(__z.real()), __z.imag()); }
737e4b17023SJohn Marino
738e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
739e4b17023SJohn Marino  inline __complex__ float
740e4b17023SJohn Marino  __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); }
741e4b17023SJohn Marino
742e4b17023SJohn Marino  inline __complex__ double
743e4b17023SJohn Marino  __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); }
744e4b17023SJohn Marino
745e4b17023SJohn Marino  inline __complex__ long double
746e4b17023SJohn Marino  __complex_exp(const __complex__ long double& __z)
747e4b17023SJohn Marino  { return __builtin_cexpl(__z); }
748e4b17023SJohn Marino
749e4b17023SJohn Marino  template<typename _Tp>
750e4b17023SJohn Marino    inline complex<_Tp>
751e4b17023SJohn Marino    exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); }
752e4b17023SJohn Marino#else
753e4b17023SJohn Marino  template<typename _Tp>
754e4b17023SJohn Marino    inline complex<_Tp>
755e4b17023SJohn Marino    exp(const complex<_Tp>& __z) { return __complex_exp(__z); }
756e4b17023SJohn Marino#endif
757e4b17023SJohn Marino
758e4b17023SJohn Marino  // 26.2.8/5 log(__z): Returns the natural complex logarithm of __z.
759e4b17023SJohn Marino  //                    The branch cut is along the negative axis.
760e4b17023SJohn Marino  template<typename _Tp>
761e4b17023SJohn Marino    inline complex<_Tp>
762e4b17023SJohn Marino    __complex_log(const complex<_Tp>& __z)
763e4b17023SJohn Marino    { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
764e4b17023SJohn Marino
765e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
766e4b17023SJohn Marino  inline __complex__ float
767e4b17023SJohn Marino  __complex_log(__complex__ float __z) { return __builtin_clogf(__z); }
768e4b17023SJohn Marino
769e4b17023SJohn Marino  inline __complex__ double
770e4b17023SJohn Marino  __complex_log(__complex__ double __z) { return __builtin_clog(__z); }
771e4b17023SJohn Marino
772e4b17023SJohn Marino  inline __complex__ long double
773e4b17023SJohn Marino  __complex_log(const __complex__ long double& __z)
774e4b17023SJohn Marino  { return __builtin_clogl(__z); }
775e4b17023SJohn Marino
776e4b17023SJohn Marino  template<typename _Tp>
777e4b17023SJohn Marino    inline complex<_Tp>
778e4b17023SJohn Marino    log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); }
779e4b17023SJohn Marino#else
780e4b17023SJohn Marino  template<typename _Tp>
781e4b17023SJohn Marino    inline complex<_Tp>
782e4b17023SJohn Marino    log(const complex<_Tp>& __z) { return __complex_log(__z); }
783e4b17023SJohn Marino#endif
784e4b17023SJohn Marino
785e4b17023SJohn Marino  template<typename _Tp>
786e4b17023SJohn Marino    inline complex<_Tp>
787e4b17023SJohn Marino    log10(const complex<_Tp>& __z)
788e4b17023SJohn Marino    { return std::log(__z) / log(_Tp(10.0)); }
789e4b17023SJohn Marino
790e4b17023SJohn Marino  // 26.2.8/10 sin(__z): Returns the sine of __z.
791e4b17023SJohn Marino  template<typename _Tp>
792e4b17023SJohn Marino    inline complex<_Tp>
793e4b17023SJohn Marino    __complex_sin(const complex<_Tp>& __z)
794e4b17023SJohn Marino    {
795e4b17023SJohn Marino      const _Tp __x = __z.real();
796e4b17023SJohn Marino      const _Tp __y = __z.imag();
797e4b17023SJohn Marino      return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y));
798e4b17023SJohn Marino    }
799e4b17023SJohn Marino
800e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
801e4b17023SJohn Marino  inline __complex__ float
802e4b17023SJohn Marino  __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); }
803e4b17023SJohn Marino
804e4b17023SJohn Marino  inline __complex__ double
805e4b17023SJohn Marino  __complex_sin(__complex__ double __z) { return __builtin_csin(__z); }
806e4b17023SJohn Marino
807e4b17023SJohn Marino  inline __complex__ long double
808e4b17023SJohn Marino  __complex_sin(const __complex__ long double& __z)
809e4b17023SJohn Marino  { return __builtin_csinl(__z); }
810e4b17023SJohn Marino
811e4b17023SJohn Marino  template<typename _Tp>
812e4b17023SJohn Marino    inline complex<_Tp>
813e4b17023SJohn Marino    sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); }
814e4b17023SJohn Marino#else
815e4b17023SJohn Marino  template<typename _Tp>
816e4b17023SJohn Marino    inline complex<_Tp>
817e4b17023SJohn Marino    sin(const complex<_Tp>& __z) { return __complex_sin(__z); }
818e4b17023SJohn Marino#endif
819e4b17023SJohn Marino
820e4b17023SJohn Marino  // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z.
821e4b17023SJohn Marino  template<typename _Tp>
822e4b17023SJohn Marino    inline complex<_Tp>
823e4b17023SJohn Marino    __complex_sinh(const complex<_Tp>& __z)
824e4b17023SJohn Marino    {
825e4b17023SJohn Marino      const _Tp __x = __z.real();
826e4b17023SJohn Marino      const _Tp  __y = __z.imag();
827e4b17023SJohn Marino      return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y));
828e4b17023SJohn Marino    }
829e4b17023SJohn Marino
830e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
831e4b17023SJohn Marino  inline __complex__ float
832e4b17023SJohn Marino  __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); }
833e4b17023SJohn Marino
834e4b17023SJohn Marino  inline __complex__ double
835e4b17023SJohn Marino  __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); }
836e4b17023SJohn Marino
837e4b17023SJohn Marino  inline __complex__ long double
838e4b17023SJohn Marino  __complex_sinh(const __complex__ long double& __z)
839e4b17023SJohn Marino  { return __builtin_csinhl(__z); }
840e4b17023SJohn Marino
841e4b17023SJohn Marino  template<typename _Tp>
842e4b17023SJohn Marino    inline complex<_Tp>
843e4b17023SJohn Marino    sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); }
844e4b17023SJohn Marino#else
845e4b17023SJohn Marino  template<typename _Tp>
846e4b17023SJohn Marino    inline complex<_Tp>
847e4b17023SJohn Marino    sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); }
848e4b17023SJohn Marino#endif
849e4b17023SJohn Marino
850e4b17023SJohn Marino  // 26.2.8/13 sqrt(__z): Returns the complex square root of __z.
851e4b17023SJohn Marino  //                     The branch cut is on the negative axis.
852e4b17023SJohn Marino  template<typename _Tp>
853e4b17023SJohn Marino    complex<_Tp>
854e4b17023SJohn Marino    __complex_sqrt(const complex<_Tp>& __z)
855e4b17023SJohn Marino    {
856e4b17023SJohn Marino      _Tp __x = __z.real();
857e4b17023SJohn Marino      _Tp __y = __z.imag();
858e4b17023SJohn Marino
859e4b17023SJohn Marino      if (__x == _Tp())
860e4b17023SJohn Marino        {
861e4b17023SJohn Marino          _Tp __t = sqrt(abs(__y) / 2);
862e4b17023SJohn Marino          return complex<_Tp>(__t, __y < _Tp() ? -__t : __t);
863e4b17023SJohn Marino        }
864e4b17023SJohn Marino      else
865e4b17023SJohn Marino        {
866e4b17023SJohn Marino          _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x)));
867e4b17023SJohn Marino          _Tp __u = __t / 2;
868e4b17023SJohn Marino          return __x > _Tp()
869e4b17023SJohn Marino            ? complex<_Tp>(__u, __y / __t)
870e4b17023SJohn Marino            : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u);
871e4b17023SJohn Marino        }
872e4b17023SJohn Marino    }
873e4b17023SJohn Marino
874e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
875e4b17023SJohn Marino  inline __complex__ float
876e4b17023SJohn Marino  __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); }
877e4b17023SJohn Marino
878e4b17023SJohn Marino  inline __complex__ double
879e4b17023SJohn Marino  __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); }
880e4b17023SJohn Marino
881e4b17023SJohn Marino  inline __complex__ long double
882e4b17023SJohn Marino  __complex_sqrt(const __complex__ long double& __z)
883e4b17023SJohn Marino  { return __builtin_csqrtl(__z); }
884e4b17023SJohn Marino
885e4b17023SJohn Marino  template<typename _Tp>
886e4b17023SJohn Marino    inline complex<_Tp>
887e4b17023SJohn Marino    sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); }
888e4b17023SJohn Marino#else
889e4b17023SJohn Marino  template<typename _Tp>
890e4b17023SJohn Marino    inline complex<_Tp>
891e4b17023SJohn Marino    sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); }
892e4b17023SJohn Marino#endif
893e4b17023SJohn Marino
894e4b17023SJohn Marino  // 26.2.8/14 tan(__z):  Return the complex tangent of __z.
895e4b17023SJohn Marino
896e4b17023SJohn Marino  template<typename _Tp>
897e4b17023SJohn Marino    inline complex<_Tp>
898e4b17023SJohn Marino    __complex_tan(const complex<_Tp>& __z)
899e4b17023SJohn Marino    { return std::sin(__z) / std::cos(__z); }
900e4b17023SJohn Marino
901e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
902e4b17023SJohn Marino  inline __complex__ float
903e4b17023SJohn Marino  __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); }
904e4b17023SJohn Marino
905e4b17023SJohn Marino  inline __complex__ double
906e4b17023SJohn Marino  __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); }
907e4b17023SJohn Marino
908e4b17023SJohn Marino  inline __complex__ long double
909e4b17023SJohn Marino  __complex_tan(const __complex__ long double& __z)
910e4b17023SJohn Marino  { return __builtin_ctanl(__z); }
911e4b17023SJohn Marino
912e4b17023SJohn Marino  template<typename _Tp>
913e4b17023SJohn Marino    inline complex<_Tp>
914e4b17023SJohn Marino    tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); }
915e4b17023SJohn Marino#else
916e4b17023SJohn Marino  template<typename _Tp>
917e4b17023SJohn Marino    inline complex<_Tp>
918e4b17023SJohn Marino    tan(const complex<_Tp>& __z) { return __complex_tan(__z); }
919e4b17023SJohn Marino#endif
920e4b17023SJohn Marino
921e4b17023SJohn Marino
922e4b17023SJohn Marino  // 26.2.8/15 tanh(__z):  Returns the hyperbolic tangent of __z.
923e4b17023SJohn Marino
924e4b17023SJohn Marino  template<typename _Tp>
925e4b17023SJohn Marino    inline complex<_Tp>
926e4b17023SJohn Marino    __complex_tanh(const complex<_Tp>& __z)
927e4b17023SJohn Marino    { return std::sinh(__z) / std::cosh(__z); }
928e4b17023SJohn Marino
929e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
930e4b17023SJohn Marino  inline __complex__ float
931e4b17023SJohn Marino  __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); }
932e4b17023SJohn Marino
933e4b17023SJohn Marino  inline __complex__ double
934e4b17023SJohn Marino  __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); }
935e4b17023SJohn Marino
936e4b17023SJohn Marino  inline __complex__ long double
937e4b17023SJohn Marino  __complex_tanh(const __complex__ long double& __z)
938e4b17023SJohn Marino  { return __builtin_ctanhl(__z); }
939e4b17023SJohn Marino
940e4b17023SJohn Marino  template<typename _Tp>
941e4b17023SJohn Marino    inline complex<_Tp>
942e4b17023SJohn Marino    tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); }
943e4b17023SJohn Marino#else
944e4b17023SJohn Marino  template<typename _Tp>
945e4b17023SJohn Marino    inline complex<_Tp>
946e4b17023SJohn Marino    tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); }
947e4b17023SJohn Marino#endif
948e4b17023SJohn Marino
949e4b17023SJohn Marino
950e4b17023SJohn Marino  // 26.2.8/9  pow(__x, __y): Returns the complex power base of __x
951e4b17023SJohn Marino  //                          raised to the __y-th power.  The branch
952e4b17023SJohn Marino  //                          cut is on the negative axis.
953e4b17023SJohn Marino#ifndef __GXX_EXPERIMENTAL_CXX0X__
954e4b17023SJohn Marino  template<typename _Tp>
955e4b17023SJohn Marino    complex<_Tp>
956e4b17023SJohn Marino    __complex_pow_unsigned(complex<_Tp> __x, unsigned __n)
957e4b17023SJohn Marino    {
958e4b17023SJohn Marino      complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1);
959e4b17023SJohn Marino
960e4b17023SJohn Marino      while (__n >>= 1)
961e4b17023SJohn Marino        {
962e4b17023SJohn Marino          __x *= __x;
963e4b17023SJohn Marino          if (__n % 2)
964e4b17023SJohn Marino            __y *= __x;
965e4b17023SJohn Marino        }
966e4b17023SJohn Marino
967e4b17023SJohn Marino      return __y;
968e4b17023SJohn Marino    }
969e4b17023SJohn Marino
970e4b17023SJohn Marino  // _GLIBCXX_RESOLVE_LIB_DEFECTS
971e4b17023SJohn Marino  // DR 844. complex pow return type is ambiguous.
972e4b17023SJohn Marino  template<typename _Tp>
973e4b17023SJohn Marino    inline complex<_Tp>
974e4b17023SJohn Marino    pow(const complex<_Tp>& __z, int __n)
975e4b17023SJohn Marino    {
976e4b17023SJohn Marino      return __n < 0
977*5ce9237cSJohn Marino	? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n)
978e4b17023SJohn Marino        : std::__complex_pow_unsigned(__z, __n);
979e4b17023SJohn Marino    }
980e4b17023SJohn Marino#endif
981e4b17023SJohn Marino
982e4b17023SJohn Marino  template<typename _Tp>
983e4b17023SJohn Marino    complex<_Tp>
984e4b17023SJohn Marino    pow(const complex<_Tp>& __x, const _Tp& __y)
985e4b17023SJohn Marino    {
986e4b17023SJohn Marino#ifndef _GLIBCXX_USE_C99_COMPLEX
987e4b17023SJohn Marino      if (__x == _Tp())
988e4b17023SJohn Marino	return _Tp();
989e4b17023SJohn Marino#endif
990e4b17023SJohn Marino      if (__x.imag() == _Tp() && __x.real() > _Tp())
991e4b17023SJohn Marino        return pow(__x.real(), __y);
992e4b17023SJohn Marino
993e4b17023SJohn Marino      complex<_Tp> __t = std::log(__x);
994e4b17023SJohn Marino      return std::polar(exp(__y * __t.real()), __y * __t.imag());
995e4b17023SJohn Marino    }
996e4b17023SJohn Marino
997e4b17023SJohn Marino  template<typename _Tp>
998e4b17023SJohn Marino    inline complex<_Tp>
999e4b17023SJohn Marino    __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1000e4b17023SJohn Marino    { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); }
1001e4b17023SJohn Marino
1002e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
1003e4b17023SJohn Marino  inline __complex__ float
1004e4b17023SJohn Marino  __complex_pow(__complex__ float __x, __complex__ float __y)
1005e4b17023SJohn Marino  { return __builtin_cpowf(__x, __y); }
1006e4b17023SJohn Marino
1007e4b17023SJohn Marino  inline __complex__ double
1008e4b17023SJohn Marino  __complex_pow(__complex__ double __x, __complex__ double __y)
1009e4b17023SJohn Marino  { return __builtin_cpow(__x, __y); }
1010e4b17023SJohn Marino
1011e4b17023SJohn Marino  inline __complex__ long double
1012e4b17023SJohn Marino  __complex_pow(const __complex__ long double& __x,
1013e4b17023SJohn Marino		const __complex__ long double& __y)
1014e4b17023SJohn Marino  { return __builtin_cpowl(__x, __y); }
1015e4b17023SJohn Marino
1016e4b17023SJohn Marino  template<typename _Tp>
1017e4b17023SJohn Marino    inline complex<_Tp>
1018e4b17023SJohn Marino    pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1019e4b17023SJohn Marino    { return __complex_pow(__x.__rep(), __y.__rep()); }
1020e4b17023SJohn Marino#else
1021e4b17023SJohn Marino  template<typename _Tp>
1022e4b17023SJohn Marino    inline complex<_Tp>
1023e4b17023SJohn Marino    pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1024e4b17023SJohn Marino    { return __complex_pow(__x, __y); }
1025e4b17023SJohn Marino#endif
1026e4b17023SJohn Marino
1027e4b17023SJohn Marino  template<typename _Tp>
1028e4b17023SJohn Marino    inline complex<_Tp>
1029e4b17023SJohn Marino    pow(const _Tp& __x, const complex<_Tp>& __y)
1030e4b17023SJohn Marino    {
1031e4b17023SJohn Marino      return __x > _Tp() ? std::polar(pow(__x, __y.real()),
1032e4b17023SJohn Marino				      __y.imag() * log(__x))
1033e4b17023SJohn Marino	                 : std::pow(complex<_Tp>(__x), __y);
1034e4b17023SJohn Marino    }
1035e4b17023SJohn Marino
1036e4b17023SJohn Marino  /// 26.2.3  complex specializations
1037e4b17023SJohn Marino  /// complex<float> specialization
1038e4b17023SJohn Marino  template<>
1039e4b17023SJohn Marino    struct complex<float>
1040e4b17023SJohn Marino    {
1041e4b17023SJohn Marino      typedef float value_type;
1042e4b17023SJohn Marino      typedef __complex__ float _ComplexT;
1043e4b17023SJohn Marino
1044e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
1045e4b17023SJohn Marino
1046e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f)
1047e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1048e4b17023SJohn Marino      : _M_value{ __r, __i } { }
1049e4b17023SJohn Marino#else
1050e4b17023SJohn Marino      {
1051e4b17023SJohn Marino	__real__ _M_value = __r;
1052e4b17023SJohn Marino	__imag__ _M_value = __i;
1053e4b17023SJohn Marino      }
1054e4b17023SJohn Marino#endif
1055e4b17023SJohn Marino
1056e4b17023SJohn Marino      explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&);
1057e4b17023SJohn Marino      explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
1058e4b17023SJohn Marino
1059e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1060e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1061e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1062e4b17023SJohn Marino      constexpr float
1063e4b17023SJohn Marino      real() { return __real__ _M_value; }
1064e4b17023SJohn Marino
1065e4b17023SJohn Marino      constexpr float
1066e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1067e4b17023SJohn Marino#else
1068e4b17023SJohn Marino      float&
1069e4b17023SJohn Marino      real() { return __real__ _M_value; }
1070e4b17023SJohn Marino
1071e4b17023SJohn Marino      const float&
1072e4b17023SJohn Marino      real() const { return __real__ _M_value; }
1073e4b17023SJohn Marino
1074e4b17023SJohn Marino      float&
1075e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1076e4b17023SJohn Marino
1077e4b17023SJohn Marino      const float&
1078e4b17023SJohn Marino      imag() const { return __imag__ _M_value; }
1079e4b17023SJohn Marino#endif
1080e4b17023SJohn Marino
1081e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1082e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1083e4b17023SJohn Marino      void
1084e4b17023SJohn Marino      real(float __val) { __real__ _M_value = __val; }
1085e4b17023SJohn Marino
1086e4b17023SJohn Marino      void
1087e4b17023SJohn Marino      imag(float __val) { __imag__ _M_value = __val; }
1088e4b17023SJohn Marino
1089e4b17023SJohn Marino      complex&
1090e4b17023SJohn Marino      operator=(float __f)
1091e4b17023SJohn Marino      {
1092e4b17023SJohn Marino	_M_value = __f;
1093e4b17023SJohn Marino	return *this;
1094e4b17023SJohn Marino      }
1095e4b17023SJohn Marino
1096e4b17023SJohn Marino      complex&
1097e4b17023SJohn Marino      operator+=(float __f)
1098e4b17023SJohn Marino      {
1099e4b17023SJohn Marino	_M_value += __f;
1100e4b17023SJohn Marino	return *this;
1101e4b17023SJohn Marino      }
1102e4b17023SJohn Marino
1103e4b17023SJohn Marino      complex&
1104e4b17023SJohn Marino      operator-=(float __f)
1105e4b17023SJohn Marino      {
1106e4b17023SJohn Marino	_M_value -= __f;
1107e4b17023SJohn Marino	return *this;
1108e4b17023SJohn Marino      }
1109e4b17023SJohn Marino
1110e4b17023SJohn Marino      complex&
1111e4b17023SJohn Marino      operator*=(float __f)
1112e4b17023SJohn Marino      {
1113e4b17023SJohn Marino	_M_value *= __f;
1114e4b17023SJohn Marino	return *this;
1115e4b17023SJohn Marino      }
1116e4b17023SJohn Marino
1117e4b17023SJohn Marino      complex&
1118e4b17023SJohn Marino      operator/=(float __f)
1119e4b17023SJohn Marino      {
1120e4b17023SJohn Marino	_M_value /= __f;
1121e4b17023SJohn Marino	return *this;
1122e4b17023SJohn Marino      }
1123e4b17023SJohn Marino
1124e4b17023SJohn Marino      // Let the compiler synthesize the copy and assignment
1125e4b17023SJohn Marino      // operator.  It always does a pretty good job.
1126e4b17023SJohn Marino      // complex& operator=(const complex&);
1127e4b17023SJohn Marino
1128e4b17023SJohn Marino      template<typename _Tp>
1129e4b17023SJohn Marino        complex&
1130e4b17023SJohn Marino        operator=(const complex<_Tp>&  __z)
1131e4b17023SJohn Marino	{
1132e4b17023SJohn Marino	  __real__ _M_value = __z.real();
1133e4b17023SJohn Marino	  __imag__ _M_value = __z.imag();
1134e4b17023SJohn Marino	  return *this;
1135e4b17023SJohn Marino	}
1136e4b17023SJohn Marino
1137e4b17023SJohn Marino      template<typename _Tp>
1138e4b17023SJohn Marino        complex&
1139e4b17023SJohn Marino        operator+=(const complex<_Tp>& __z)
1140e4b17023SJohn Marino	{
1141e4b17023SJohn Marino	  __real__ _M_value += __z.real();
1142e4b17023SJohn Marino	  __imag__ _M_value += __z.imag();
1143e4b17023SJohn Marino	  return *this;
1144e4b17023SJohn Marino	}
1145e4b17023SJohn Marino
1146e4b17023SJohn Marino      template<class _Tp>
1147e4b17023SJohn Marino        complex&
1148e4b17023SJohn Marino        operator-=(const complex<_Tp>& __z)
1149e4b17023SJohn Marino	{
1150e4b17023SJohn Marino	  __real__ _M_value -= __z.real();
1151e4b17023SJohn Marino	  __imag__ _M_value -= __z.imag();
1152e4b17023SJohn Marino	  return *this;
1153e4b17023SJohn Marino	}
1154e4b17023SJohn Marino
1155e4b17023SJohn Marino      template<class _Tp>
1156e4b17023SJohn Marino        complex&
1157e4b17023SJohn Marino        operator*=(const complex<_Tp>& __z)
1158e4b17023SJohn Marino	{
1159e4b17023SJohn Marino	  _ComplexT __t;
1160e4b17023SJohn Marino	  __real__ __t = __z.real();
1161e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1162e4b17023SJohn Marino	  _M_value *= __t;
1163e4b17023SJohn Marino	  return *this;
1164e4b17023SJohn Marino	}
1165e4b17023SJohn Marino
1166e4b17023SJohn Marino      template<class _Tp>
1167e4b17023SJohn Marino        complex&
1168e4b17023SJohn Marino        operator/=(const complex<_Tp>& __z)
1169e4b17023SJohn Marino	{
1170e4b17023SJohn Marino	  _ComplexT __t;
1171e4b17023SJohn Marino	  __real__ __t = __z.real();
1172e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1173e4b17023SJohn Marino	  _M_value /= __t;
1174e4b17023SJohn Marino	  return *this;
1175e4b17023SJohn Marino	}
1176e4b17023SJohn Marino
1177e4b17023SJohn Marino      _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; }
1178e4b17023SJohn Marino
1179e4b17023SJohn Marino    private:
1180e4b17023SJohn Marino      _ComplexT _M_value;
1181e4b17023SJohn Marino    };
1182e4b17023SJohn Marino
1183e4b17023SJohn Marino  /// 26.2.3  complex specializations
1184e4b17023SJohn Marino  /// complex<double> specialization
1185e4b17023SJohn Marino  template<>
1186e4b17023SJohn Marino    struct complex<double>
1187e4b17023SJohn Marino    {
1188e4b17023SJohn Marino      typedef double value_type;
1189e4b17023SJohn Marino      typedef __complex__ double _ComplexT;
1190e4b17023SJohn Marino
1191e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
1192e4b17023SJohn Marino
1193e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0)
1194e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1195e4b17023SJohn Marino      : _M_value{ __r, __i } { }
1196e4b17023SJohn Marino#else
1197e4b17023SJohn Marino      {
1198e4b17023SJohn Marino	__real__ _M_value = __r;
1199e4b17023SJohn Marino	__imag__ _M_value = __i;
1200e4b17023SJohn Marino      }
1201e4b17023SJohn Marino#endif
1202e4b17023SJohn Marino
1203e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
1204e4b17023SJohn Marino      : _M_value(__z.__rep()) { }
1205e4b17023SJohn Marino
1206e4b17023SJohn Marino      explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&);
1207e4b17023SJohn Marino
1208e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1209e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1210e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1211e4b17023SJohn Marino      constexpr double
1212e4b17023SJohn Marino      real() { return __real__ _M_value; }
1213e4b17023SJohn Marino
1214e4b17023SJohn Marino      constexpr double
1215e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1216e4b17023SJohn Marino#else
1217e4b17023SJohn Marino      double&
1218e4b17023SJohn Marino      real() { return __real__ _M_value; }
1219e4b17023SJohn Marino
1220e4b17023SJohn Marino      const double&
1221e4b17023SJohn Marino      real() const { return __real__ _M_value; }
1222e4b17023SJohn Marino
1223e4b17023SJohn Marino      double&
1224e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1225e4b17023SJohn Marino
1226e4b17023SJohn Marino      const double&
1227e4b17023SJohn Marino      imag() const { return __imag__ _M_value; }
1228e4b17023SJohn Marino#endif
1229e4b17023SJohn Marino
1230e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1231e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1232e4b17023SJohn Marino      void
1233e4b17023SJohn Marino      real(double __val) { __real__ _M_value = __val; }
1234e4b17023SJohn Marino
1235e4b17023SJohn Marino      void
1236e4b17023SJohn Marino      imag(double __val) { __imag__ _M_value = __val; }
1237e4b17023SJohn Marino
1238e4b17023SJohn Marino      complex&
1239e4b17023SJohn Marino      operator=(double __d)
1240e4b17023SJohn Marino      {
1241e4b17023SJohn Marino	_M_value = __d;
1242e4b17023SJohn Marino	return *this;
1243e4b17023SJohn Marino      }
1244e4b17023SJohn Marino
1245e4b17023SJohn Marino      complex&
1246e4b17023SJohn Marino      operator+=(double __d)
1247e4b17023SJohn Marino      {
1248e4b17023SJohn Marino	_M_value += __d;
1249e4b17023SJohn Marino	return *this;
1250e4b17023SJohn Marino      }
1251e4b17023SJohn Marino
1252e4b17023SJohn Marino      complex&
1253e4b17023SJohn Marino      operator-=(double __d)
1254e4b17023SJohn Marino      {
1255e4b17023SJohn Marino	_M_value -= __d;
1256e4b17023SJohn Marino	return *this;
1257e4b17023SJohn Marino      }
1258e4b17023SJohn Marino
1259e4b17023SJohn Marino      complex&
1260e4b17023SJohn Marino      operator*=(double __d)
1261e4b17023SJohn Marino      {
1262e4b17023SJohn Marino	_M_value *= __d;
1263e4b17023SJohn Marino	return *this;
1264e4b17023SJohn Marino      }
1265e4b17023SJohn Marino
1266e4b17023SJohn Marino      complex&
1267e4b17023SJohn Marino      operator/=(double __d)
1268e4b17023SJohn Marino      {
1269e4b17023SJohn Marino	_M_value /= __d;
1270e4b17023SJohn Marino	return *this;
1271e4b17023SJohn Marino      }
1272e4b17023SJohn Marino
1273e4b17023SJohn Marino      // The compiler will synthesize this, efficiently.
1274e4b17023SJohn Marino      // complex& operator=(const complex&);
1275e4b17023SJohn Marino
1276e4b17023SJohn Marino      template<typename _Tp>
1277e4b17023SJohn Marino        complex&
1278e4b17023SJohn Marino        operator=(const complex<_Tp>& __z)
1279e4b17023SJohn Marino	{
1280e4b17023SJohn Marino	  __real__ _M_value = __z.real();
1281e4b17023SJohn Marino	  __imag__ _M_value = __z.imag();
1282e4b17023SJohn Marino	  return *this;
1283e4b17023SJohn Marino	}
1284e4b17023SJohn Marino
1285e4b17023SJohn Marino      template<typename _Tp>
1286e4b17023SJohn Marino        complex&
1287e4b17023SJohn Marino        operator+=(const complex<_Tp>& __z)
1288e4b17023SJohn Marino	{
1289e4b17023SJohn Marino	  __real__ _M_value += __z.real();
1290e4b17023SJohn Marino	  __imag__ _M_value += __z.imag();
1291e4b17023SJohn Marino	  return *this;
1292e4b17023SJohn Marino	}
1293e4b17023SJohn Marino
1294e4b17023SJohn Marino      template<typename _Tp>
1295e4b17023SJohn Marino        complex&
1296e4b17023SJohn Marino        operator-=(const complex<_Tp>& __z)
1297e4b17023SJohn Marino	{
1298e4b17023SJohn Marino	  __real__ _M_value -= __z.real();
1299e4b17023SJohn Marino	  __imag__ _M_value -= __z.imag();
1300e4b17023SJohn Marino	  return *this;
1301e4b17023SJohn Marino	}
1302e4b17023SJohn Marino
1303e4b17023SJohn Marino      template<typename _Tp>
1304e4b17023SJohn Marino        complex&
1305e4b17023SJohn Marino        operator*=(const complex<_Tp>& __z)
1306e4b17023SJohn Marino	{
1307e4b17023SJohn Marino	  _ComplexT __t;
1308e4b17023SJohn Marino	  __real__ __t = __z.real();
1309e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1310e4b17023SJohn Marino	  _M_value *= __t;
1311e4b17023SJohn Marino	  return *this;
1312e4b17023SJohn Marino	}
1313e4b17023SJohn Marino
1314e4b17023SJohn Marino      template<typename _Tp>
1315e4b17023SJohn Marino        complex&
1316e4b17023SJohn Marino        operator/=(const complex<_Tp>& __z)
1317e4b17023SJohn Marino	{
1318e4b17023SJohn Marino	  _ComplexT __t;
1319e4b17023SJohn Marino	  __real__ __t = __z.real();
1320e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1321e4b17023SJohn Marino	  _M_value /= __t;
1322e4b17023SJohn Marino	  return *this;
1323e4b17023SJohn Marino	}
1324e4b17023SJohn Marino
1325e4b17023SJohn Marino      _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; }
1326e4b17023SJohn Marino
1327e4b17023SJohn Marino    private:
1328e4b17023SJohn Marino      _ComplexT _M_value;
1329e4b17023SJohn Marino    };
1330e4b17023SJohn Marino
1331e4b17023SJohn Marino  /// 26.2.3  complex specializations
1332e4b17023SJohn Marino  /// complex<long double> specialization
1333e4b17023SJohn Marino  template<>
1334e4b17023SJohn Marino    struct complex<long double>
1335e4b17023SJohn Marino    {
1336e4b17023SJohn Marino      typedef long double value_type;
1337e4b17023SJohn Marino      typedef __complex__ long double _ComplexT;
1338e4b17023SJohn Marino
1339e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { }
1340e4b17023SJohn Marino
1341e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(long double __r = 0.0L,
1342e4b17023SJohn Marino				 long double __i = 0.0L)
1343e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1344e4b17023SJohn Marino      : _M_value{ __r, __i } { }
1345e4b17023SJohn Marino#else
1346e4b17023SJohn Marino      {
1347e4b17023SJohn Marino	__real__ _M_value = __r;
1348e4b17023SJohn Marino	__imag__ _M_value = __i;
1349e4b17023SJohn Marino      }
1350e4b17023SJohn Marino#endif
1351e4b17023SJohn Marino
1352e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(const complex<float>& __z)
1353e4b17023SJohn Marino      : _M_value(__z.__rep()) { }
1354e4b17023SJohn Marino
1355e4b17023SJohn Marino      _GLIBCXX_CONSTEXPR complex(const complex<double>& __z)
1356e4b17023SJohn Marino      : _M_value(__z.__rep()) { }
1357e4b17023SJohn Marino
1358e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1359e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1360e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1361e4b17023SJohn Marino      constexpr long double
1362e4b17023SJohn Marino      real() { return __real__ _M_value; }
1363e4b17023SJohn Marino
1364e4b17023SJohn Marino      constexpr long double
1365e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1366e4b17023SJohn Marino#else
1367e4b17023SJohn Marino      long double&
1368e4b17023SJohn Marino      real() { return __real__ _M_value; }
1369e4b17023SJohn Marino
1370e4b17023SJohn Marino      const long double&
1371e4b17023SJohn Marino      real() const { return __real__ _M_value; }
1372e4b17023SJohn Marino
1373e4b17023SJohn Marino      long double&
1374e4b17023SJohn Marino      imag() { return __imag__ _M_value; }
1375e4b17023SJohn Marino
1376e4b17023SJohn Marino      const long double&
1377e4b17023SJohn Marino      imag() const { return __imag__ _M_value; }
1378e4b17023SJohn Marino#endif
1379e4b17023SJohn Marino
1380e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1381e4b17023SJohn Marino      // DR 387. std::complex over-encapsulated.
1382e4b17023SJohn Marino      void
1383e4b17023SJohn Marino      real(long double __val) { __real__ _M_value = __val; }
1384e4b17023SJohn Marino
1385e4b17023SJohn Marino      void
1386e4b17023SJohn Marino      imag(long double __val) { __imag__ _M_value = __val; }
1387e4b17023SJohn Marino
1388e4b17023SJohn Marino      complex&
1389e4b17023SJohn Marino      operator=(long double __r)
1390e4b17023SJohn Marino      {
1391e4b17023SJohn Marino	_M_value = __r;
1392e4b17023SJohn Marino	return *this;
1393e4b17023SJohn Marino      }
1394e4b17023SJohn Marino
1395e4b17023SJohn Marino      complex&
1396e4b17023SJohn Marino      operator+=(long double __r)
1397e4b17023SJohn Marino      {
1398e4b17023SJohn Marino	_M_value += __r;
1399e4b17023SJohn Marino	return *this;
1400e4b17023SJohn Marino      }
1401e4b17023SJohn Marino
1402e4b17023SJohn Marino      complex&
1403e4b17023SJohn Marino      operator-=(long double __r)
1404e4b17023SJohn Marino      {
1405e4b17023SJohn Marino	_M_value -= __r;
1406e4b17023SJohn Marino	return *this;
1407e4b17023SJohn Marino      }
1408e4b17023SJohn Marino
1409e4b17023SJohn Marino      complex&
1410e4b17023SJohn Marino      operator*=(long double __r)
1411e4b17023SJohn Marino      {
1412e4b17023SJohn Marino	_M_value *= __r;
1413e4b17023SJohn Marino	return *this;
1414e4b17023SJohn Marino      }
1415e4b17023SJohn Marino
1416e4b17023SJohn Marino      complex&
1417e4b17023SJohn Marino      operator/=(long double __r)
1418e4b17023SJohn Marino      {
1419e4b17023SJohn Marino	_M_value /= __r;
1420e4b17023SJohn Marino	return *this;
1421e4b17023SJohn Marino      }
1422e4b17023SJohn Marino
1423e4b17023SJohn Marino      // The compiler knows how to do this efficiently
1424e4b17023SJohn Marino      // complex& operator=(const complex&);
1425e4b17023SJohn Marino
1426e4b17023SJohn Marino      template<typename _Tp>
1427e4b17023SJohn Marino        complex&
1428e4b17023SJohn Marino        operator=(const complex<_Tp>& __z)
1429e4b17023SJohn Marino	{
1430e4b17023SJohn Marino	  __real__ _M_value = __z.real();
1431e4b17023SJohn Marino	  __imag__ _M_value = __z.imag();
1432e4b17023SJohn Marino	  return *this;
1433e4b17023SJohn Marino	}
1434e4b17023SJohn Marino
1435e4b17023SJohn Marino      template<typename _Tp>
1436e4b17023SJohn Marino        complex&
1437e4b17023SJohn Marino	operator+=(const complex<_Tp>& __z)
1438e4b17023SJohn Marino	{
1439e4b17023SJohn Marino	  __real__ _M_value += __z.real();
1440e4b17023SJohn Marino	  __imag__ _M_value += __z.imag();
1441e4b17023SJohn Marino	  return *this;
1442e4b17023SJohn Marino	}
1443e4b17023SJohn Marino
1444e4b17023SJohn Marino      template<typename _Tp>
1445e4b17023SJohn Marino        complex&
1446e4b17023SJohn Marino	operator-=(const complex<_Tp>& __z)
1447e4b17023SJohn Marino	{
1448e4b17023SJohn Marino	  __real__ _M_value -= __z.real();
1449e4b17023SJohn Marino	  __imag__ _M_value -= __z.imag();
1450e4b17023SJohn Marino	  return *this;
1451e4b17023SJohn Marino	}
1452e4b17023SJohn Marino
1453e4b17023SJohn Marino      template<typename _Tp>
1454e4b17023SJohn Marino        complex&
1455e4b17023SJohn Marino	operator*=(const complex<_Tp>& __z)
1456e4b17023SJohn Marino	{
1457e4b17023SJohn Marino	  _ComplexT __t;
1458e4b17023SJohn Marino	  __real__ __t = __z.real();
1459e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1460e4b17023SJohn Marino	  _M_value *= __t;
1461e4b17023SJohn Marino	  return *this;
1462e4b17023SJohn Marino	}
1463e4b17023SJohn Marino
1464e4b17023SJohn Marino      template<typename _Tp>
1465e4b17023SJohn Marino        complex&
1466e4b17023SJohn Marino	operator/=(const complex<_Tp>& __z)
1467e4b17023SJohn Marino	{
1468e4b17023SJohn Marino	  _ComplexT __t;
1469e4b17023SJohn Marino	  __real__ __t = __z.real();
1470e4b17023SJohn Marino	  __imag__ __t = __z.imag();
1471e4b17023SJohn Marino	  _M_value /= __t;
1472e4b17023SJohn Marino	  return *this;
1473e4b17023SJohn Marino	}
1474e4b17023SJohn Marino
1475e4b17023SJohn Marino      _GLIBCXX_USE_CONSTEXPR _ComplexT __rep() const { return _M_value; }
1476e4b17023SJohn Marino
1477e4b17023SJohn Marino    private:
1478e4b17023SJohn Marino      _ComplexT _M_value;
1479e4b17023SJohn Marino    };
1480e4b17023SJohn Marino
1481e4b17023SJohn Marino  // These bits have to be at the end of this file, so that the
1482e4b17023SJohn Marino  // specializations have all been defined.
1483e4b17023SJohn Marino  inline _GLIBCXX_CONSTEXPR
1484e4b17023SJohn Marino  complex<float>::complex(const complex<double>& __z)
1485e4b17023SJohn Marino  : _M_value(__z.__rep()) { }
1486e4b17023SJohn Marino
1487e4b17023SJohn Marino  inline _GLIBCXX_CONSTEXPR
1488e4b17023SJohn Marino  complex<float>::complex(const complex<long double>& __z)
1489e4b17023SJohn Marino  : _M_value(__z.__rep()) { }
1490e4b17023SJohn Marino
1491e4b17023SJohn Marino  inline _GLIBCXX_CONSTEXPR
1492e4b17023SJohn Marino  complex<double>::complex(const complex<long double>& __z)
1493e4b17023SJohn Marino  : _M_value(__z.__rep()) { }
1494e4b17023SJohn Marino
1495e4b17023SJohn Marino  // Inhibit implicit instantiations for required instantiations,
1496e4b17023SJohn Marino  // which are defined via explicit instantiations elsewhere.
1497e4b17023SJohn Marino  // NB:  This syntax is a GNU extension.
1498e4b17023SJohn Marino#if _GLIBCXX_EXTERN_TEMPLATE
1499e4b17023SJohn Marino  extern template istream& operator>>(istream&, complex<float>&);
1500e4b17023SJohn Marino  extern template ostream& operator<<(ostream&, const complex<float>&);
1501e4b17023SJohn Marino  extern template istream& operator>>(istream&, complex<double>&);
1502e4b17023SJohn Marino  extern template ostream& operator<<(ostream&, const complex<double>&);
1503e4b17023SJohn Marino  extern template istream& operator>>(istream&, complex<long double>&);
1504e4b17023SJohn Marino  extern template ostream& operator<<(ostream&, const complex<long double>&);
1505e4b17023SJohn Marino
1506e4b17023SJohn Marino#ifdef _GLIBCXX_USE_WCHAR_T
1507e4b17023SJohn Marino  extern template wistream& operator>>(wistream&, complex<float>&);
1508e4b17023SJohn Marino  extern template wostream& operator<<(wostream&, const complex<float>&);
1509e4b17023SJohn Marino  extern template wistream& operator>>(wistream&, complex<double>&);
1510e4b17023SJohn Marino  extern template wostream& operator<<(wostream&, const complex<double>&);
1511e4b17023SJohn Marino  extern template wistream& operator>>(wistream&, complex<long double>&);
1512e4b17023SJohn Marino  extern template wostream& operator<<(wostream&, const complex<long double>&);
1513e4b17023SJohn Marino#endif
1514e4b17023SJohn Marino#endif
1515e4b17023SJohn Marino
1516e4b17023SJohn Marino  // @} group complex_numbers
1517e4b17023SJohn Marino
1518e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION
1519e4b17023SJohn Marino} // namespace
1520e4b17023SJohn Marino
1521e4b17023SJohn Marinonamespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
1522e4b17023SJohn Marino{
1523e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION
1524e4b17023SJohn Marino
1525e4b17023SJohn Marino  // See ext/type_traits.h for the primary template.
1526e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1527e4b17023SJohn Marino    struct __promote_2<std::complex<_Tp>, _Up>
1528e4b17023SJohn Marino    {
1529e4b17023SJohn Marino    public:
1530e4b17023SJohn Marino      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
1531e4b17023SJohn Marino    };
1532e4b17023SJohn Marino
1533e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1534e4b17023SJohn Marino    struct __promote_2<_Tp, std::complex<_Up> >
1535e4b17023SJohn Marino    {
1536e4b17023SJohn Marino    public:
1537e4b17023SJohn Marino      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
1538e4b17023SJohn Marino    };
1539e4b17023SJohn Marino
1540e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1541e4b17023SJohn Marino    struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
1542e4b17023SJohn Marino    {
1543e4b17023SJohn Marino    public:
1544e4b17023SJohn Marino      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
1545e4b17023SJohn Marino    };
1546e4b17023SJohn Marino
1547e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION
1548e4b17023SJohn Marino} // namespace
1549e4b17023SJohn Marino
1550e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
1551e4b17023SJohn Marino
1552e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
1553e4b17023SJohn Marino{
1554e4b17023SJohn Marino_GLIBCXX_BEGIN_NAMESPACE_VERSION
1555e4b17023SJohn Marino
1556e4b17023SJohn Marino  // Forward declarations.
1557e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
1558e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
1559e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
1560e4b17023SJohn Marino
1561e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
1562e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
1563e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
1564e4b17023SJohn Marino  // DR 595.
1565e4b17023SJohn Marino  template<typename _Tp> _Tp               fabs(const std::complex<_Tp>&);
1566e4b17023SJohn Marino
1567e4b17023SJohn Marino  template<typename _Tp>
1568e4b17023SJohn Marino    inline std::complex<_Tp>
1569e4b17023SJohn Marino    __complex_acos(const std::complex<_Tp>& __z)
1570e4b17023SJohn Marino    {
1571e4b17023SJohn Marino      const std::complex<_Tp> __t = std::asin(__z);
1572e4b17023SJohn Marino      const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
1573e4b17023SJohn Marino      return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
1574e4b17023SJohn Marino    }
1575e4b17023SJohn Marino
1576e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1577e4b17023SJohn Marino  inline __complex__ float
1578e4b17023SJohn Marino  __complex_acos(__complex__ float __z)
1579e4b17023SJohn Marino  { return __builtin_cacosf(__z); }
1580e4b17023SJohn Marino
1581e4b17023SJohn Marino  inline __complex__ double
1582e4b17023SJohn Marino  __complex_acos(__complex__ double __z)
1583e4b17023SJohn Marino  { return __builtin_cacos(__z); }
1584e4b17023SJohn Marino
1585e4b17023SJohn Marino  inline __complex__ long double
1586e4b17023SJohn Marino  __complex_acos(const __complex__ long double& __z)
1587e4b17023SJohn Marino  { return __builtin_cacosl(__z); }
1588e4b17023SJohn Marino
1589e4b17023SJohn Marino  template<typename _Tp>
1590e4b17023SJohn Marino    inline std::complex<_Tp>
1591e4b17023SJohn Marino    acos(const std::complex<_Tp>& __z)
1592e4b17023SJohn Marino    { return __complex_acos(__z.__rep()); }
1593e4b17023SJohn Marino#else
1594e4b17023SJohn Marino  /// acos(__z) [8.1.2].
1595e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function cacos, defined
1596e4b17023SJohn Marino  //            in subclause 7.3.5.1.
1597e4b17023SJohn Marino  template<typename _Tp>
1598e4b17023SJohn Marino    inline std::complex<_Tp>
1599e4b17023SJohn Marino    acos(const std::complex<_Tp>& __z)
1600e4b17023SJohn Marino    { return __complex_acos(__z); }
1601e4b17023SJohn Marino#endif
1602e4b17023SJohn Marino
1603e4b17023SJohn Marino  template<typename _Tp>
1604e4b17023SJohn Marino    inline std::complex<_Tp>
1605e4b17023SJohn Marino    __complex_asin(const std::complex<_Tp>& __z)
1606e4b17023SJohn Marino    {
1607e4b17023SJohn Marino      std::complex<_Tp> __t(-__z.imag(), __z.real());
1608e4b17023SJohn Marino      __t = std::asinh(__t);
1609e4b17023SJohn Marino      return std::complex<_Tp>(__t.imag(), -__t.real());
1610e4b17023SJohn Marino    }
1611e4b17023SJohn Marino
1612e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1613e4b17023SJohn Marino  inline __complex__ float
1614e4b17023SJohn Marino  __complex_asin(__complex__ float __z)
1615e4b17023SJohn Marino  { return __builtin_casinf(__z); }
1616e4b17023SJohn Marino
1617e4b17023SJohn Marino  inline __complex__ double
1618e4b17023SJohn Marino  __complex_asin(__complex__ double __z)
1619e4b17023SJohn Marino  { return __builtin_casin(__z); }
1620e4b17023SJohn Marino
1621e4b17023SJohn Marino  inline __complex__ long double
1622e4b17023SJohn Marino  __complex_asin(const __complex__ long double& __z)
1623e4b17023SJohn Marino  { return __builtin_casinl(__z); }
1624e4b17023SJohn Marino
1625e4b17023SJohn Marino  template<typename _Tp>
1626e4b17023SJohn Marino    inline std::complex<_Tp>
1627e4b17023SJohn Marino    asin(const std::complex<_Tp>& __z)
1628e4b17023SJohn Marino    { return __complex_asin(__z.__rep()); }
1629e4b17023SJohn Marino#else
1630e4b17023SJohn Marino  /// asin(__z) [8.1.3].
1631e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function casin, defined
1632e4b17023SJohn Marino  //            in subclause 7.3.5.2.
1633e4b17023SJohn Marino  template<typename _Tp>
1634e4b17023SJohn Marino    inline std::complex<_Tp>
1635e4b17023SJohn Marino    asin(const std::complex<_Tp>& __z)
1636e4b17023SJohn Marino    { return __complex_asin(__z); }
1637e4b17023SJohn Marino#endif
1638e4b17023SJohn Marino
1639e4b17023SJohn Marino  template<typename _Tp>
1640e4b17023SJohn Marino    std::complex<_Tp>
1641e4b17023SJohn Marino    __complex_atan(const std::complex<_Tp>& __z)
1642e4b17023SJohn Marino    {
1643e4b17023SJohn Marino      const _Tp __r2 = __z.real() * __z.real();
1644e4b17023SJohn Marino      const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
1645e4b17023SJohn Marino
1646e4b17023SJohn Marino      _Tp __num = __z.imag() + _Tp(1.0);
1647e4b17023SJohn Marino      _Tp __den = __z.imag() - _Tp(1.0);
1648e4b17023SJohn Marino
1649e4b17023SJohn Marino      __num = __r2 + __num * __num;
1650e4b17023SJohn Marino      __den = __r2 + __den * __den;
1651e4b17023SJohn Marino
1652e4b17023SJohn Marino      return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
1653e4b17023SJohn Marino			       _Tp(0.25) * log(__num / __den));
1654e4b17023SJohn Marino    }
1655e4b17023SJohn Marino
1656e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1657e4b17023SJohn Marino  inline __complex__ float
1658e4b17023SJohn Marino  __complex_atan(__complex__ float __z)
1659e4b17023SJohn Marino  { return __builtin_catanf(__z); }
1660e4b17023SJohn Marino
1661e4b17023SJohn Marino  inline __complex__ double
1662e4b17023SJohn Marino  __complex_atan(__complex__ double __z)
1663e4b17023SJohn Marino  { return __builtin_catan(__z); }
1664e4b17023SJohn Marino
1665e4b17023SJohn Marino  inline __complex__ long double
1666e4b17023SJohn Marino  __complex_atan(const __complex__ long double& __z)
1667e4b17023SJohn Marino  { return __builtin_catanl(__z); }
1668e4b17023SJohn Marino
1669e4b17023SJohn Marino  template<typename _Tp>
1670e4b17023SJohn Marino    inline std::complex<_Tp>
1671e4b17023SJohn Marino    atan(const std::complex<_Tp>& __z)
1672e4b17023SJohn Marino    { return __complex_atan(__z.__rep()); }
1673e4b17023SJohn Marino#else
1674e4b17023SJohn Marino  /// atan(__z) [8.1.4].
1675e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function catan, defined
1676e4b17023SJohn Marino  //            in subclause 7.3.5.3.
1677e4b17023SJohn Marino  template<typename _Tp>
1678e4b17023SJohn Marino    inline std::complex<_Tp>
1679e4b17023SJohn Marino    atan(const std::complex<_Tp>& __z)
1680e4b17023SJohn Marino    { return __complex_atan(__z); }
1681e4b17023SJohn Marino#endif
1682e4b17023SJohn Marino
1683e4b17023SJohn Marino  template<typename _Tp>
1684e4b17023SJohn Marino    std::complex<_Tp>
1685e4b17023SJohn Marino    __complex_acosh(const std::complex<_Tp>& __z)
1686e4b17023SJohn Marino    {
1687e4b17023SJohn Marino      // Kahan's formula.
1688e4b17023SJohn Marino      return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0)))
1689e4b17023SJohn Marino				 + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0))));
1690e4b17023SJohn Marino    }
1691e4b17023SJohn Marino
1692e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1693e4b17023SJohn Marino  inline __complex__ float
1694e4b17023SJohn Marino  __complex_acosh(__complex__ float __z)
1695e4b17023SJohn Marino  { return __builtin_cacoshf(__z); }
1696e4b17023SJohn Marino
1697e4b17023SJohn Marino  inline __complex__ double
1698e4b17023SJohn Marino  __complex_acosh(__complex__ double __z)
1699e4b17023SJohn Marino  { return __builtin_cacosh(__z); }
1700e4b17023SJohn Marino
1701e4b17023SJohn Marino  inline __complex__ long double
1702e4b17023SJohn Marino  __complex_acosh(const __complex__ long double& __z)
1703e4b17023SJohn Marino  { return __builtin_cacoshl(__z); }
1704e4b17023SJohn Marino
1705e4b17023SJohn Marino  template<typename _Tp>
1706e4b17023SJohn Marino    inline std::complex<_Tp>
1707e4b17023SJohn Marino    acosh(const std::complex<_Tp>& __z)
1708e4b17023SJohn Marino    { return __complex_acosh(__z.__rep()); }
1709e4b17023SJohn Marino#else
1710e4b17023SJohn Marino  /// acosh(__z) [8.1.5].
1711e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function cacosh, defined
1712e4b17023SJohn Marino  //            in subclause 7.3.6.1.
1713e4b17023SJohn Marino  template<typename _Tp>
1714e4b17023SJohn Marino    inline std::complex<_Tp>
1715e4b17023SJohn Marino    acosh(const std::complex<_Tp>& __z)
1716e4b17023SJohn Marino    { return __complex_acosh(__z); }
1717e4b17023SJohn Marino#endif
1718e4b17023SJohn Marino
1719e4b17023SJohn Marino  template<typename _Tp>
1720e4b17023SJohn Marino    std::complex<_Tp>
1721e4b17023SJohn Marino    __complex_asinh(const std::complex<_Tp>& __z)
1722e4b17023SJohn Marino    {
1723e4b17023SJohn Marino      std::complex<_Tp> __t((__z.real() - __z.imag())
1724e4b17023SJohn Marino			    * (__z.real() + __z.imag()) + _Tp(1.0),
1725e4b17023SJohn Marino			    _Tp(2.0) * __z.real() * __z.imag());
1726e4b17023SJohn Marino      __t = std::sqrt(__t);
1727e4b17023SJohn Marino
1728e4b17023SJohn Marino      return std::log(__t + __z);
1729e4b17023SJohn Marino    }
1730e4b17023SJohn Marino
1731e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1732e4b17023SJohn Marino  inline __complex__ float
1733e4b17023SJohn Marino  __complex_asinh(__complex__ float __z)
1734e4b17023SJohn Marino  { return __builtin_casinhf(__z); }
1735e4b17023SJohn Marino
1736e4b17023SJohn Marino  inline __complex__ double
1737e4b17023SJohn Marino  __complex_asinh(__complex__ double __z)
1738e4b17023SJohn Marino  { return __builtin_casinh(__z); }
1739e4b17023SJohn Marino
1740e4b17023SJohn Marino  inline __complex__ long double
1741e4b17023SJohn Marino  __complex_asinh(const __complex__ long double& __z)
1742e4b17023SJohn Marino  { return __builtin_casinhl(__z); }
1743e4b17023SJohn Marino
1744e4b17023SJohn Marino  template<typename _Tp>
1745e4b17023SJohn Marino    inline std::complex<_Tp>
1746e4b17023SJohn Marino    asinh(const std::complex<_Tp>& __z)
1747e4b17023SJohn Marino    { return __complex_asinh(__z.__rep()); }
1748e4b17023SJohn Marino#else
1749e4b17023SJohn Marino  /// asinh(__z) [8.1.6].
1750e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function casin, defined
1751e4b17023SJohn Marino  //            in subclause 7.3.6.2.
1752e4b17023SJohn Marino  template<typename _Tp>
1753e4b17023SJohn Marino    inline std::complex<_Tp>
1754e4b17023SJohn Marino    asinh(const std::complex<_Tp>& __z)
1755e4b17023SJohn Marino    { return __complex_asinh(__z); }
1756e4b17023SJohn Marino#endif
1757e4b17023SJohn Marino
1758e4b17023SJohn Marino  template<typename _Tp>
1759e4b17023SJohn Marino    std::complex<_Tp>
1760e4b17023SJohn Marino    __complex_atanh(const std::complex<_Tp>& __z)
1761e4b17023SJohn Marino    {
1762e4b17023SJohn Marino      const _Tp __i2 = __z.imag() * __z.imag();
1763e4b17023SJohn Marino      const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
1764e4b17023SJohn Marino
1765e4b17023SJohn Marino      _Tp __num = _Tp(1.0) + __z.real();
1766e4b17023SJohn Marino      _Tp __den = _Tp(1.0) - __z.real();
1767e4b17023SJohn Marino
1768e4b17023SJohn Marino      __num = __i2 + __num * __num;
1769e4b17023SJohn Marino      __den = __i2 + __den * __den;
1770e4b17023SJohn Marino
1771e4b17023SJohn Marino      return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
1772e4b17023SJohn Marino			       _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
1773e4b17023SJohn Marino    }
1774e4b17023SJohn Marino
1775e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX_TR1
1776e4b17023SJohn Marino  inline __complex__ float
1777e4b17023SJohn Marino  __complex_atanh(__complex__ float __z)
1778e4b17023SJohn Marino  { return __builtin_catanhf(__z); }
1779e4b17023SJohn Marino
1780e4b17023SJohn Marino  inline __complex__ double
1781e4b17023SJohn Marino  __complex_atanh(__complex__ double __z)
1782e4b17023SJohn Marino  { return __builtin_catanh(__z); }
1783e4b17023SJohn Marino
1784e4b17023SJohn Marino  inline __complex__ long double
1785e4b17023SJohn Marino  __complex_atanh(const __complex__ long double& __z)
1786e4b17023SJohn Marino  { return __builtin_catanhl(__z); }
1787e4b17023SJohn Marino
1788e4b17023SJohn Marino  template<typename _Tp>
1789e4b17023SJohn Marino    inline std::complex<_Tp>
1790e4b17023SJohn Marino    atanh(const std::complex<_Tp>& __z)
1791e4b17023SJohn Marino    { return __complex_atanh(__z.__rep()); }
1792e4b17023SJohn Marino#else
1793e4b17023SJohn Marino  /// atanh(__z) [8.1.7].
1794e4b17023SJohn Marino  //  Effects:  Behaves the same as C99 function catanh, defined
1795e4b17023SJohn Marino  //            in subclause 7.3.6.3.
1796e4b17023SJohn Marino  template<typename _Tp>
1797e4b17023SJohn Marino    inline std::complex<_Tp>
1798e4b17023SJohn Marino    atanh(const std::complex<_Tp>& __z)
1799e4b17023SJohn Marino    { return __complex_atanh(__z); }
1800e4b17023SJohn Marino#endif
1801e4b17023SJohn Marino
1802e4b17023SJohn Marino  template<typename _Tp>
1803e4b17023SJohn Marino    inline _Tp
1804e4b17023SJohn Marino    /// fabs(__z) [8.1.8].
1805e4b17023SJohn Marino    //  Effects:  Behaves the same as C99 function cabs, defined
1806e4b17023SJohn Marino    //            in subclause 7.3.8.1.
1807e4b17023SJohn Marino    fabs(const std::complex<_Tp>& __z)
1808e4b17023SJohn Marino    { return std::abs(__z); }
1809e4b17023SJohn Marino
1810e4b17023SJohn Marino  /// Additional overloads [8.1.9].
1811e4b17023SJohn Marino  template<typename _Tp>
1812e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1813e4b17023SJohn Marino    arg(_Tp __x)
1814e4b17023SJohn Marino    {
1815e4b17023SJohn Marino      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
1816e4b17023SJohn Marino#if (_GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
1817e4b17023SJohn Marino      return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L)
1818e4b17023SJohn Marino	                       : __type();
1819e4b17023SJohn Marino#else
1820e4b17023SJohn Marino      return std::arg(std::complex<__type>(__x));
1821e4b17023SJohn Marino#endif
1822e4b17023SJohn Marino    }
1823e4b17023SJohn Marino
1824e4b17023SJohn Marino  template<typename _Tp>
1825e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1826e4b17023SJohn Marino    imag(_Tp)
1827e4b17023SJohn Marino    { return _Tp(); }
1828e4b17023SJohn Marino
1829e4b17023SJohn Marino  template<typename _Tp>
1830e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1831e4b17023SJohn Marino    norm(_Tp __x)
1832e4b17023SJohn Marino    {
1833e4b17023SJohn Marino      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
1834e4b17023SJohn Marino      return __type(__x) * __type(__x);
1835e4b17023SJohn Marino    }
1836e4b17023SJohn Marino
1837e4b17023SJohn Marino  template<typename _Tp>
1838e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1839e4b17023SJohn Marino    real(_Tp __x)
1840e4b17023SJohn Marino    { return __x; }
1841e4b17023SJohn Marino
1842e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1843e4b17023SJohn Marino    inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
1844e4b17023SJohn Marino    pow(const std::complex<_Tp>& __x, const _Up& __y)
1845e4b17023SJohn Marino    {
1846e4b17023SJohn Marino      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
1847e4b17023SJohn Marino      return std::pow(std::complex<__type>(__x), __type(__y));
1848e4b17023SJohn Marino    }
1849e4b17023SJohn Marino
1850e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1851e4b17023SJohn Marino    inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
1852e4b17023SJohn Marino    pow(const _Tp& __x, const std::complex<_Up>& __y)
1853e4b17023SJohn Marino    {
1854e4b17023SJohn Marino      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
1855e4b17023SJohn Marino      return std::pow(__type(__x), std::complex<__type>(__y));
1856e4b17023SJohn Marino    }
1857e4b17023SJohn Marino
1858e4b17023SJohn Marino  template<typename _Tp, typename _Up>
1859e4b17023SJohn Marino    inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
1860e4b17023SJohn Marino    pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
1861e4b17023SJohn Marino    {
1862e4b17023SJohn Marino      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
1863e4b17023SJohn Marino      return std::pow(std::complex<__type>(__x),
1864e4b17023SJohn Marino		      std::complex<__type>(__y));
1865e4b17023SJohn Marino    }
1866e4b17023SJohn Marino
1867e4b17023SJohn Marino  // Forward declarations.
1868e4b17023SJohn Marino  // DR 781.
1869e4b17023SJohn Marino  template<typename _Tp> std::complex<_Tp> proj(const std::complex<_Tp>&);
1870e4b17023SJohn Marino
1871e4b17023SJohn Marino  template<typename _Tp>
1872e4b17023SJohn Marino    std::complex<_Tp>
1873e4b17023SJohn Marino    __complex_proj(const std::complex<_Tp>& __z)
1874e4b17023SJohn Marino    {
1875e4b17023SJohn Marino      const _Tp __den = (__z.real() * __z.real()
1876e4b17023SJohn Marino			 + __z.imag() * __z.imag() + _Tp(1.0));
1877e4b17023SJohn Marino
1878e4b17023SJohn Marino      return std::complex<_Tp>((_Tp(2.0) * __z.real()) / __den,
1879e4b17023SJohn Marino			       (_Tp(2.0) * __z.imag()) / __den);
1880e4b17023SJohn Marino    }
1881e4b17023SJohn Marino
1882e4b17023SJohn Marino#if _GLIBCXX_USE_C99_COMPLEX
1883e4b17023SJohn Marino  inline __complex__ float
1884e4b17023SJohn Marino  __complex_proj(__complex__ float __z)
1885e4b17023SJohn Marino  { return __builtin_cprojf(__z); }
1886e4b17023SJohn Marino
1887e4b17023SJohn Marino  inline __complex__ double
1888e4b17023SJohn Marino  __complex_proj(__complex__ double __z)
1889e4b17023SJohn Marino  { return __builtin_cproj(__z); }
1890e4b17023SJohn Marino
1891e4b17023SJohn Marino  inline __complex__ long double
1892e4b17023SJohn Marino  __complex_proj(const __complex__ long double& __z)
1893e4b17023SJohn Marino  { return __builtin_cprojl(__z); }
1894e4b17023SJohn Marino
1895e4b17023SJohn Marino  template<typename _Tp>
1896e4b17023SJohn Marino    inline std::complex<_Tp>
1897e4b17023SJohn Marino    proj(const std::complex<_Tp>& __z)
1898e4b17023SJohn Marino    { return __complex_proj(__z.__rep()); }
1899e4b17023SJohn Marino#else
1900e4b17023SJohn Marino  template<typename _Tp>
1901e4b17023SJohn Marino    inline std::complex<_Tp>
1902e4b17023SJohn Marino    proj(const std::complex<_Tp>& __z)
1903e4b17023SJohn Marino    { return __complex_proj(__z); }
1904e4b17023SJohn Marino#endif
1905e4b17023SJohn Marino
1906e4b17023SJohn Marino  // DR 1137.
1907e4b17023SJohn Marino  template<typename _Tp>
1908e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1909e4b17023SJohn Marino    proj(_Tp __x)
1910e4b17023SJohn Marino    { return __x; }
1911e4b17023SJohn Marino
1912e4b17023SJohn Marino  template<typename _Tp>
1913e4b17023SJohn Marino    inline typename __gnu_cxx::__promote<_Tp>::__type
1914e4b17023SJohn Marino    conj(_Tp __x)
1915e4b17023SJohn Marino    { return __x; }
1916e4b17023SJohn Marino
1917e4b17023SJohn Marino_GLIBCXX_END_NAMESPACE_VERSION
1918e4b17023SJohn Marino} // namespace
1919e4b17023SJohn Marino
1920e4b17023SJohn Marino#endif  // __GXX_EXPERIMENTAL_CXX0X__
1921e4b17023SJohn Marino
1922e4b17023SJohn Marino#endif  /* _GLIBCXX_COMPLEX */
1923