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