1*f8a1b7d9SAlexander Kabaev// TR1 complex -*- C++ -*-
2*f8a1b7d9SAlexander Kabaev
3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2006 Free Software Foundation, Inc.
4*f8a1b7d9SAlexander Kabaev//
5*f8a1b7d9SAlexander Kabaev// This file is part of the GNU ISO C++ Library.  This library is free
6*f8a1b7d9SAlexander Kabaev// software; you can redistribute it and/or modify it under the
7*f8a1b7d9SAlexander Kabaev// terms of the GNU General Public License as published by the
8*f8a1b7d9SAlexander Kabaev// Free Software Foundation; either version 2, or (at your option)
9*f8a1b7d9SAlexander Kabaev// any later version.
10*f8a1b7d9SAlexander Kabaev
11*f8a1b7d9SAlexander Kabaev// This library is distributed in the hope that it will be useful,
12*f8a1b7d9SAlexander Kabaev// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*f8a1b7d9SAlexander Kabaev// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*f8a1b7d9SAlexander Kabaev// GNU General Public License for more details.
15*f8a1b7d9SAlexander Kabaev
16*f8a1b7d9SAlexander Kabaev// You should have received a copy of the GNU General Public License along
17*f8a1b7d9SAlexander Kabaev// with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*f8a1b7d9SAlexander Kabaev// USA.
20*f8a1b7d9SAlexander Kabaev
21*f8a1b7d9SAlexander Kabaev// As a special exception, you may use this file as part of a free software
22*f8a1b7d9SAlexander Kabaev// library without restriction.  Specifically, if other files instantiate
23*f8a1b7d9SAlexander Kabaev// templates or use macros or inline functions from this file, or you compile
24*f8a1b7d9SAlexander Kabaev// this file and link it with other files to produce an executable, this
25*f8a1b7d9SAlexander Kabaev// file does not by itself cause the resulting executable to be covered by
26*f8a1b7d9SAlexander Kabaev// the GNU General Public License.  This exception does not however
27*f8a1b7d9SAlexander Kabaev// invalidate any other reasons why the executable file might be covered by
28*f8a1b7d9SAlexander Kabaev// the GNU General Public License.
29*f8a1b7d9SAlexander Kabaev
30*f8a1b7d9SAlexander Kabaev/** @file tr1/complex
31*f8a1b7d9SAlexander Kabaev *  This is a TR1 C++ Library header.
32*f8a1b7d9SAlexander Kabaev */
33*f8a1b7d9SAlexander Kabaev
34*f8a1b7d9SAlexander Kabaev#ifndef _TR1_COMPLEX
35*f8a1b7d9SAlexander Kabaev#define _TR1_COMPLEX 1
36*f8a1b7d9SAlexander Kabaev
37*f8a1b7d9SAlexander Kabaev#include "../complex"
38*f8a1b7d9SAlexander Kabaev#include <tr1/common.h>
39*f8a1b7d9SAlexander Kabaev
40*f8a1b7d9SAlexander Kabaev// namespace std::tr1
41*f8a1b7d9SAlexander Kabaevnamespace std
42*f8a1b7d9SAlexander Kabaev{
43*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(tr1)
44*f8a1b7d9SAlexander Kabaev
45*f8a1b7d9SAlexander Kabaev  // Forward declarations.
46*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
47*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
48*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
49*f8a1b7d9SAlexander Kabaev
50*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
51*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
52*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
53*f8a1b7d9SAlexander Kabaev  template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
54*f8a1b7d9SAlexander Kabaev
55*f8a1b7d9SAlexander Kabaev  /// @brief acos(__z) [8.1.2].
56*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function cacos, defined
57*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.5.1.
58*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
59*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
60*f8a1b7d9SAlexander Kabaev    __complex_acos(const std::complex<_Tp>& __z)
61*f8a1b7d9SAlexander Kabaev    {
62*f8a1b7d9SAlexander Kabaev      const std::complex<_Tp> __t = std::tr1::asin(__z);
63*f8a1b7d9SAlexander Kabaev      const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
64*f8a1b7d9SAlexander Kabaev      return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
65*f8a1b7d9SAlexander Kabaev    }
66*f8a1b7d9SAlexander Kabaev
67*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
68*f8a1b7d9SAlexander Kabaev  inline __complex__ float
69*f8a1b7d9SAlexander Kabaev  __complex_acos(__complex__ float __z)
70*f8a1b7d9SAlexander Kabaev  { return __builtin_cacosf(__z); }
71*f8a1b7d9SAlexander Kabaev
72*f8a1b7d9SAlexander Kabaev  inline __complex__ double
73*f8a1b7d9SAlexander Kabaev  __complex_acos(__complex__ double __z)
74*f8a1b7d9SAlexander Kabaev  { return __builtin_cacos(__z); }
75*f8a1b7d9SAlexander Kabaev
76*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
77*f8a1b7d9SAlexander Kabaev  __complex_acos(const __complex__ long double& __z)
78*f8a1b7d9SAlexander Kabaev  { return __builtin_cacosl(__z); }
79*f8a1b7d9SAlexander Kabaev
80*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
81*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
82*f8a1b7d9SAlexander Kabaev    acos(const std::complex<_Tp>& __z)
83*f8a1b7d9SAlexander Kabaev    { return __complex_acos(__z.__rep()); }
84*f8a1b7d9SAlexander Kabaev#else
85*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
86*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
87*f8a1b7d9SAlexander Kabaev    acos(const std::complex<_Tp>& __z)
88*f8a1b7d9SAlexander Kabaev    { return __complex_acos(__z); }
89*f8a1b7d9SAlexander Kabaev#endif
90*f8a1b7d9SAlexander Kabaev
91*f8a1b7d9SAlexander Kabaev  /// @brief asin(__z) [8.1.3].
92*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function casin, defined
93*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.5.2.
94*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
95*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
96*f8a1b7d9SAlexander Kabaev    __complex_asin(const std::complex<_Tp>& __z)
97*f8a1b7d9SAlexander Kabaev    {
98*f8a1b7d9SAlexander Kabaev      std::complex<_Tp> __t(-__z.imag(), __z.real());
99*f8a1b7d9SAlexander Kabaev      __t = std::tr1::asinh(__t);
100*f8a1b7d9SAlexander Kabaev      return std::complex<_Tp>(__t.imag(), -__t.real());
101*f8a1b7d9SAlexander Kabaev    }
102*f8a1b7d9SAlexander Kabaev
103*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
104*f8a1b7d9SAlexander Kabaev  inline __complex__ float
105*f8a1b7d9SAlexander Kabaev  __complex_asin(__complex__ float __z)
106*f8a1b7d9SAlexander Kabaev  { return __builtin_casinf(__z); }
107*f8a1b7d9SAlexander Kabaev
108*f8a1b7d9SAlexander Kabaev  inline __complex__ double
109*f8a1b7d9SAlexander Kabaev  __complex_asin(__complex__ double __z)
110*f8a1b7d9SAlexander Kabaev  { return __builtin_casin(__z); }
111*f8a1b7d9SAlexander Kabaev
112*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
113*f8a1b7d9SAlexander Kabaev  __complex_asin(const __complex__ long double& __z)
114*f8a1b7d9SAlexander Kabaev  { return __builtin_casinl(__z); }
115*f8a1b7d9SAlexander Kabaev
116*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
117*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
118*f8a1b7d9SAlexander Kabaev    asin(const std::complex<_Tp>& __z)
119*f8a1b7d9SAlexander Kabaev    { return __complex_asin(__z.__rep()); }
120*f8a1b7d9SAlexander Kabaev#else
121*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
122*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
123*f8a1b7d9SAlexander Kabaev    asin(const std::complex<_Tp>& __z)
124*f8a1b7d9SAlexander Kabaev    { return __complex_asin(__z); }
125*f8a1b7d9SAlexander Kabaev#endif
126*f8a1b7d9SAlexander Kabaev
127*f8a1b7d9SAlexander Kabaev  /// @brief atan(__z) [8.1.4].
128*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function catan, defined
129*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.5.3.
130*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
131*f8a1b7d9SAlexander Kabaev    std::complex<_Tp>
132*f8a1b7d9SAlexander Kabaev    __complex_atan(const std::complex<_Tp>& __z)
133*f8a1b7d9SAlexander Kabaev    {
134*f8a1b7d9SAlexander Kabaev      const _Tp __r2 = __z.real() * __z.real();
135*f8a1b7d9SAlexander Kabaev      const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
136*f8a1b7d9SAlexander Kabaev
137*f8a1b7d9SAlexander Kabaev      _Tp __num = __z.imag() + _Tp(1.0);
138*f8a1b7d9SAlexander Kabaev      _Tp __den = __z.imag() - _Tp(1.0);
139*f8a1b7d9SAlexander Kabaev
140*f8a1b7d9SAlexander Kabaev      __num = __r2 + __num * __num;
141*f8a1b7d9SAlexander Kabaev      __den = __r2 + __den * __den;
142*f8a1b7d9SAlexander Kabaev
143*f8a1b7d9SAlexander Kabaev      return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
144*f8a1b7d9SAlexander Kabaev			       _Tp(0.25) * log(__num / __den));
145*f8a1b7d9SAlexander Kabaev    }
146*f8a1b7d9SAlexander Kabaev
147*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
148*f8a1b7d9SAlexander Kabaev  inline __complex__ float
149*f8a1b7d9SAlexander Kabaev  __complex_atan(__complex__ float __z)
150*f8a1b7d9SAlexander Kabaev  { return __builtin_catanf(__z); }
151*f8a1b7d9SAlexander Kabaev
152*f8a1b7d9SAlexander Kabaev  inline __complex__ double
153*f8a1b7d9SAlexander Kabaev  __complex_atan(__complex__ double __z)
154*f8a1b7d9SAlexander Kabaev  { return __builtin_catan(__z); }
155*f8a1b7d9SAlexander Kabaev
156*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
157*f8a1b7d9SAlexander Kabaev  __complex_atan(const __complex__ long double& __z)
158*f8a1b7d9SAlexander Kabaev  { return __builtin_catanl(__z); }
159*f8a1b7d9SAlexander Kabaev
160*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
161*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
162*f8a1b7d9SAlexander Kabaev    atan(const std::complex<_Tp>& __z)
163*f8a1b7d9SAlexander Kabaev    { return __complex_atan(__z.__rep()); }
164*f8a1b7d9SAlexander Kabaev#else
165*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
166*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
167*f8a1b7d9SAlexander Kabaev    atan(const std::complex<_Tp>& __z)
168*f8a1b7d9SAlexander Kabaev    { return __complex_atan(__z); }
169*f8a1b7d9SAlexander Kabaev#endif
170*f8a1b7d9SAlexander Kabaev
171*f8a1b7d9SAlexander Kabaev  /// @brief acosh(__z) [8.1.5].
172*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function cacosh, defined
173*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.6.1.
174*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
175*f8a1b7d9SAlexander Kabaev    std::complex<_Tp>
176*f8a1b7d9SAlexander Kabaev    __complex_acosh(const std::complex<_Tp>& __z)
177*f8a1b7d9SAlexander Kabaev    {
178*f8a1b7d9SAlexander Kabaev      std::complex<_Tp> __t((__z.real() - __z.imag())
179*f8a1b7d9SAlexander Kabaev			    * (__z.real() + __z.imag()) - _Tp(1.0),
180*f8a1b7d9SAlexander Kabaev			    _Tp(2.0) * __z.real() * __z.imag());
181*f8a1b7d9SAlexander Kabaev      __t = std::sqrt(__t);
182*f8a1b7d9SAlexander Kabaev
183*f8a1b7d9SAlexander Kabaev      return std::log(__t + __z);
184*f8a1b7d9SAlexander Kabaev    }
185*f8a1b7d9SAlexander Kabaev
186*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
187*f8a1b7d9SAlexander Kabaev  inline __complex__ float
188*f8a1b7d9SAlexander Kabaev  __complex_acosh(__complex__ float __z)
189*f8a1b7d9SAlexander Kabaev  { return __builtin_cacoshf(__z); }
190*f8a1b7d9SAlexander Kabaev
191*f8a1b7d9SAlexander Kabaev  inline __complex__ double
192*f8a1b7d9SAlexander Kabaev  __complex_acosh(__complex__ double __z)
193*f8a1b7d9SAlexander Kabaev  { return __builtin_cacosh(__z); }
194*f8a1b7d9SAlexander Kabaev
195*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
196*f8a1b7d9SAlexander Kabaev  __complex_acosh(const __complex__ long double& __z)
197*f8a1b7d9SAlexander Kabaev  { return __builtin_cacoshl(__z); }
198*f8a1b7d9SAlexander Kabaev
199*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
200*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
201*f8a1b7d9SAlexander Kabaev    acosh(const std::complex<_Tp>& __z)
202*f8a1b7d9SAlexander Kabaev    { return __complex_acosh(__z.__rep()); }
203*f8a1b7d9SAlexander Kabaev#else
204*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
205*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
206*f8a1b7d9SAlexander Kabaev    acosh(const std::complex<_Tp>& __z)
207*f8a1b7d9SAlexander Kabaev    { return __complex_acosh(__z); }
208*f8a1b7d9SAlexander Kabaev#endif
209*f8a1b7d9SAlexander Kabaev
210*f8a1b7d9SAlexander Kabaev  /// @brief asinh(__z) [8.1.6].
211*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function casin, defined
212*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.6.2.
213*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
214*f8a1b7d9SAlexander Kabaev    std::complex<_Tp>
215*f8a1b7d9SAlexander Kabaev    __complex_asinh(const std::complex<_Tp>& __z)
216*f8a1b7d9SAlexander Kabaev    {
217*f8a1b7d9SAlexander Kabaev      std::complex<_Tp> __t((__z.real() - __z.imag())
218*f8a1b7d9SAlexander Kabaev			    * (__z.real() + __z.imag()) + _Tp(1.0),
219*f8a1b7d9SAlexander Kabaev			    _Tp(2.0) * __z.real() * __z.imag());
220*f8a1b7d9SAlexander Kabaev      __t = std::sqrt(__t);
221*f8a1b7d9SAlexander Kabaev
222*f8a1b7d9SAlexander Kabaev      return std::log(__t + __z);
223*f8a1b7d9SAlexander Kabaev    }
224*f8a1b7d9SAlexander Kabaev
225*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
226*f8a1b7d9SAlexander Kabaev  inline __complex__ float
227*f8a1b7d9SAlexander Kabaev  __complex_asinh(__complex__ float __z)
228*f8a1b7d9SAlexander Kabaev  { return __builtin_casinhf(__z); }
229*f8a1b7d9SAlexander Kabaev
230*f8a1b7d9SAlexander Kabaev  inline __complex__ double
231*f8a1b7d9SAlexander Kabaev  __complex_asinh(__complex__ double __z)
232*f8a1b7d9SAlexander Kabaev  { return __builtin_casinh(__z); }
233*f8a1b7d9SAlexander Kabaev
234*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
235*f8a1b7d9SAlexander Kabaev  __complex_asinh(const __complex__ long double& __z)
236*f8a1b7d9SAlexander Kabaev  { return __builtin_casinhl(__z); }
237*f8a1b7d9SAlexander Kabaev
238*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
239*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
240*f8a1b7d9SAlexander Kabaev    asinh(const std::complex<_Tp>& __z)
241*f8a1b7d9SAlexander Kabaev    { return __complex_asinh(__z.__rep()); }
242*f8a1b7d9SAlexander Kabaev#else
243*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
244*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
245*f8a1b7d9SAlexander Kabaev    asinh(const std::complex<_Tp>& __z)
246*f8a1b7d9SAlexander Kabaev    { return __complex_asinh(__z); }
247*f8a1b7d9SAlexander Kabaev#endif
248*f8a1b7d9SAlexander Kabaev
249*f8a1b7d9SAlexander Kabaev  /// @brief atanh(__z) [8.1.7].
250*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function catanh, defined
251*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.6.3.
252*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
253*f8a1b7d9SAlexander Kabaev    std::complex<_Tp>
254*f8a1b7d9SAlexander Kabaev    __complex_atanh(const std::complex<_Tp>& __z)
255*f8a1b7d9SAlexander Kabaev    {
256*f8a1b7d9SAlexander Kabaev      const _Tp __i2 = __z.imag() * __z.imag();
257*f8a1b7d9SAlexander Kabaev      const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
258*f8a1b7d9SAlexander Kabaev
259*f8a1b7d9SAlexander Kabaev      _Tp __num = _Tp(1.0) + __z.real();
260*f8a1b7d9SAlexander Kabaev      _Tp __den = _Tp(1.0) - __z.real();
261*f8a1b7d9SAlexander Kabaev
262*f8a1b7d9SAlexander Kabaev      __num = __i2 + __num * __num;
263*f8a1b7d9SAlexander Kabaev      __den = __i2 + __den * __den;
264*f8a1b7d9SAlexander Kabaev
265*f8a1b7d9SAlexander Kabaev      return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
266*f8a1b7d9SAlexander Kabaev			       _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
267*f8a1b7d9SAlexander Kabaev    }
268*f8a1b7d9SAlexander Kabaev
269*f8a1b7d9SAlexander Kabaev#if _GLIBCXX_USE_C99_COMPLEX_TR1
270*f8a1b7d9SAlexander Kabaev  inline __complex__ float
271*f8a1b7d9SAlexander Kabaev  __complex_atanh(__complex__ float __z)
272*f8a1b7d9SAlexander Kabaev  { return __builtin_catanhf(__z); }
273*f8a1b7d9SAlexander Kabaev
274*f8a1b7d9SAlexander Kabaev  inline __complex__ double
275*f8a1b7d9SAlexander Kabaev  __complex_atanh(__complex__ double __z)
276*f8a1b7d9SAlexander Kabaev  { return __builtin_catanh(__z); }
277*f8a1b7d9SAlexander Kabaev
278*f8a1b7d9SAlexander Kabaev  inline __complex__ long double
279*f8a1b7d9SAlexander Kabaev  __complex_atanh(const __complex__ long double& __z)
280*f8a1b7d9SAlexander Kabaev  { return __builtin_catanhl(__z); }
281*f8a1b7d9SAlexander Kabaev
282*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
283*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
284*f8a1b7d9SAlexander Kabaev    atanh(const std::complex<_Tp>& __z)
285*f8a1b7d9SAlexander Kabaev    { return __complex_atanh(__z.__rep()); }
286*f8a1b7d9SAlexander Kabaev#else
287*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
288*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
289*f8a1b7d9SAlexander Kabaev    atanh(const std::complex<_Tp>& __z)
290*f8a1b7d9SAlexander Kabaev    { return __complex_atanh(__z); }
291*f8a1b7d9SAlexander Kabaev#endif
292*f8a1b7d9SAlexander Kabaev
293*f8a1b7d9SAlexander Kabaev  /// @brief fabs(__z) [8.1.8].
294*f8a1b7d9SAlexander Kabaev  //  Effects:  Behaves the same as C99 function cabs, defined
295*f8a1b7d9SAlexander Kabaev  //            in subclause 7.3.8.1.
296*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
297*f8a1b7d9SAlexander Kabaev    inline std::complex<_Tp>
298*f8a1b7d9SAlexander Kabaev    fabs(const std::complex<_Tp>& __z)
299*f8a1b7d9SAlexander Kabaev    { return std::abs(__z); }
300*f8a1b7d9SAlexander Kabaev
301*f8a1b7d9SAlexander Kabaev
302*f8a1b7d9SAlexander Kabaev  /// @brief Additional overloads [8.1.9].
303*f8a1b7d9SAlexander Kabaev  //
304*f8a1b7d9SAlexander Kabaev
305*f8a1b7d9SAlexander Kabaev  // See common.h for the primary template.
306*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
307*f8a1b7d9SAlexander Kabaev    struct __promote_2<std::complex<_Tp>, _Up>
308*f8a1b7d9SAlexander Kabaev    {
309*f8a1b7d9SAlexander Kabaev    public:
310*f8a1b7d9SAlexander Kabaev      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
311*f8a1b7d9SAlexander Kabaev    };
312*f8a1b7d9SAlexander Kabaev
313*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
314*f8a1b7d9SAlexander Kabaev    struct __promote_2<_Tp, std::complex<_Up> >
315*f8a1b7d9SAlexander Kabaev    {
316*f8a1b7d9SAlexander Kabaev    public:
317*f8a1b7d9SAlexander Kabaev      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
318*f8a1b7d9SAlexander Kabaev    };
319*f8a1b7d9SAlexander Kabaev
320*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
321*f8a1b7d9SAlexander Kabaev    struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
322*f8a1b7d9SAlexander Kabaev    {
323*f8a1b7d9SAlexander Kabaev    public:
324*f8a1b7d9SAlexander Kabaev      typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
325*f8a1b7d9SAlexander Kabaev    };
326*f8a1b7d9SAlexander Kabaev
327*f8a1b7d9SAlexander Kabaev
328*f8a1b7d9SAlexander Kabaev  using std::arg;
329*f8a1b7d9SAlexander Kabaev
330*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
331*f8a1b7d9SAlexander Kabaev    inline typename __promote<_Tp>::__type
332*f8a1b7d9SAlexander Kabaev    arg(_Tp __x)
333*f8a1b7d9SAlexander Kabaev    {
334*f8a1b7d9SAlexander Kabaev      typedef typename __promote<_Tp>::__type __type;
335*f8a1b7d9SAlexander Kabaev      return std::arg(std::complex<__type>(__x));
336*f8a1b7d9SAlexander Kabaev    }
337*f8a1b7d9SAlexander Kabaev
338*f8a1b7d9SAlexander Kabaev  using std::conj;
339*f8a1b7d9SAlexander Kabaev
340*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
341*f8a1b7d9SAlexander Kabaev    inline std::complex<typename __promote<_Tp>::__type>
342*f8a1b7d9SAlexander Kabaev    conj(_Tp __x)
343*f8a1b7d9SAlexander Kabaev    { return __x; }
344*f8a1b7d9SAlexander Kabaev
345*f8a1b7d9SAlexander Kabaev  using std::imag;
346*f8a1b7d9SAlexander Kabaev
347*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
348*f8a1b7d9SAlexander Kabaev    inline typename __promote<_Tp>::__type
349*f8a1b7d9SAlexander Kabaev    imag(_Tp)
350*f8a1b7d9SAlexander Kabaev    { return _Tp(); }
351*f8a1b7d9SAlexander Kabaev
352*f8a1b7d9SAlexander Kabaev  using std::norm;
353*f8a1b7d9SAlexander Kabaev
354*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
355*f8a1b7d9SAlexander Kabaev    inline typename __promote<_Tp>::__type
356*f8a1b7d9SAlexander Kabaev    norm(_Tp __x)
357*f8a1b7d9SAlexander Kabaev    {
358*f8a1b7d9SAlexander Kabaev      typedef typename __promote<_Tp>::__type __type;
359*f8a1b7d9SAlexander Kabaev      return __type(__x) * __type(__x);
360*f8a1b7d9SAlexander Kabaev    }
361*f8a1b7d9SAlexander Kabaev
362*f8a1b7d9SAlexander Kabaev  using std::polar;
363*f8a1b7d9SAlexander Kabaev
364*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
365*f8a1b7d9SAlexander Kabaev    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
366*f8a1b7d9SAlexander Kabaev    polar(const _Tp& __rho, const _Up& __theta)
367*f8a1b7d9SAlexander Kabaev    {
368*f8a1b7d9SAlexander Kabaev      typedef typename __promote_2<_Tp, _Up>::__type __type;
369*f8a1b7d9SAlexander Kabaev      return std::polar(__type(__rho), __type(__theta));
370*f8a1b7d9SAlexander Kabaev    }
371*f8a1b7d9SAlexander Kabaev
372*f8a1b7d9SAlexander Kabaev  using std::pow;
373*f8a1b7d9SAlexander Kabaev
374*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
375*f8a1b7d9SAlexander Kabaev    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
376*f8a1b7d9SAlexander Kabaev    pow(const std::complex<_Tp>& __x, const _Up& __y)
377*f8a1b7d9SAlexander Kabaev    {
378*f8a1b7d9SAlexander Kabaev      typedef typename __promote_2<_Tp, _Up>::__type __type;
379*f8a1b7d9SAlexander Kabaev      return std::pow(std::complex<__type>(__x), __type(__y));
380*f8a1b7d9SAlexander Kabaev    }
381*f8a1b7d9SAlexander Kabaev
382*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
383*f8a1b7d9SAlexander Kabaev    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
384*f8a1b7d9SAlexander Kabaev    pow(const _Tp& __x, const std::complex<_Up>& __y)
385*f8a1b7d9SAlexander Kabaev    {
386*f8a1b7d9SAlexander Kabaev      typedef typename __promote_2<_Tp, _Up>::__type __type;
387*f8a1b7d9SAlexander Kabaev      return std::pow(__type(__x), std::complex<__type>(__y));
388*f8a1b7d9SAlexander Kabaev    }
389*f8a1b7d9SAlexander Kabaev
390*f8a1b7d9SAlexander Kabaev  template<typename _Tp, typename _Up>
391*f8a1b7d9SAlexander Kabaev    inline std::complex<typename __promote_2<_Tp, _Up>::__type>
392*f8a1b7d9SAlexander Kabaev    pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
393*f8a1b7d9SAlexander Kabaev    {
394*f8a1b7d9SAlexander Kabaev      typedef typename __promote_2<_Tp, _Up>::__type __type;
395*f8a1b7d9SAlexander Kabaev      return std::pow(std::complex<__type>(__x),
396*f8a1b7d9SAlexander Kabaev		      std::complex<__type>(__y));
397*f8a1b7d9SAlexander Kabaev    }
398*f8a1b7d9SAlexander Kabaev
399*f8a1b7d9SAlexander Kabaev  using std::real;
400*f8a1b7d9SAlexander Kabaev
401*f8a1b7d9SAlexander Kabaev  template<typename _Tp>
402*f8a1b7d9SAlexander Kabaev    inline typename __promote<_Tp>::__type
403*f8a1b7d9SAlexander Kabaev    real(_Tp __x)
404*f8a1b7d9SAlexander Kabaev    { return __x; }
405*f8a1b7d9SAlexander Kabaev
406*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE
407*f8a1b7d9SAlexander Kabaev}
408*f8a1b7d9SAlexander Kabaev
409*f8a1b7d9SAlexander Kabaev#endif
410