Import gcc-4.4.1
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / tr1_impl / complex
1 // TR1 complex -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 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 3, or (at your option)
9 // any later version.
10
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.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file tr1_impl/complex
26  *  This is an internal header file, included by other library headers.
27  *  You should not attempt to use it directly.
28  */
29
30 namespace std
31 {
32 _GLIBCXX_BEGIN_NAMESPACE_TR1
33
34   /**
35    * @addtogroup complex_numbers
36    * @{
37    */
38
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>&);
43
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
53
54   template<typename _Tp>
55     inline std::complex<_Tp>
56     __complex_acos(const std::complex<_Tp>& __z)
57     {
58       const std::complex<_Tp> __t = std::_GLIBCXX_TR1 asin(__z);
59       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
60       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
61     }
62
63 #if _GLIBCXX_USE_C99_COMPLEX_TR1
64   inline __complex__ float
65   __complex_acos(__complex__ float __z)
66   { return __builtin_cacosf(__z); }
67
68   inline __complex__ double
69   __complex_acos(__complex__ double __z)
70   { return __builtin_cacos(__z); }
71
72   inline __complex__ long double
73   __complex_acos(const __complex__ long double& __z)
74   { return __builtin_cacosl(__z); }
75
76   template<typename _Tp>
77     inline std::complex<_Tp>
78     acos(const std::complex<_Tp>& __z)
79     { return __complex_acos(__z.__rep()); }
80 #else
81   /// acos(__z) [8.1.2].
82   //  Effects:  Behaves the same as C99 function cacos, defined
83   //            in subclause 7.3.5.1.
84   template<typename _Tp>
85     inline std::complex<_Tp>
86     acos(const std::complex<_Tp>& __z)
87     { return __complex_acos(__z); }
88 #endif
89
90   template<typename _Tp>
91     inline std::complex<_Tp>
92     __complex_asin(const std::complex<_Tp>& __z)
93     {
94       std::complex<_Tp> __t(-__z.imag(), __z.real());
95       __t = std::_GLIBCXX_TR1 asinh(__t);
96       return std::complex<_Tp>(__t.imag(), -__t.real());
97     }
98
99 #if _GLIBCXX_USE_C99_COMPLEX_TR1
100   inline __complex__ float
101   __complex_asin(__complex__ float __z)
102   { return __builtin_casinf(__z); }
103
104   inline __complex__ double
105   __complex_asin(__complex__ double __z)
106   { return __builtin_casin(__z); }
107
108   inline __complex__ long double
109   __complex_asin(const __complex__ long double& __z)
110   { return __builtin_casinl(__z); }
111
112   template<typename _Tp>
113     inline std::complex<_Tp>
114     asin(const std::complex<_Tp>& __z)
115     { return __complex_asin(__z.__rep()); }
116 #else
117   /// asin(__z) [8.1.3].
118   //  Effects:  Behaves the same as C99 function casin, defined
119   //            in subclause 7.3.5.2.
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   template<typename _Tp>
127     std::complex<_Tp>
128     __complex_atan(const std::complex<_Tp>& __z)
129     {
130       const _Tp __r2 = __z.real() * __z.real();
131       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
132
133       _Tp __num = __z.imag() + _Tp(1.0);
134       _Tp __den = __z.imag() - _Tp(1.0);
135
136       __num = __r2 + __num * __num;
137       __den = __r2 + __den * __den;
138
139       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
140                                _Tp(0.25) * log(__num / __den));
141     }
142
143 #if _GLIBCXX_USE_C99_COMPLEX_TR1
144   inline __complex__ float
145   __complex_atan(__complex__ float __z)
146   { return __builtin_catanf(__z); }
147
148   inline __complex__ double
149   __complex_atan(__complex__ double __z)
150   { return __builtin_catan(__z); }
151
152   inline __complex__ long double
153   __complex_atan(const __complex__ long double& __z)
154   { return __builtin_catanl(__z); }
155
156   template<typename _Tp>
157     inline std::complex<_Tp>
158     atan(const std::complex<_Tp>& __z)
159     { return __complex_atan(__z.__rep()); }
160 #else
161   /// atan(__z) [8.1.4].
162   //  Effects:  Behaves the same as C99 function catan, defined
163   //            in subclause 7.3.5.3.
164   template<typename _Tp>
165     inline std::complex<_Tp>
166     atan(const std::complex<_Tp>& __z)
167     { return __complex_atan(__z); }
168 #endif
169
170   template<typename _Tp>
171     std::complex<_Tp>
172     __complex_acosh(const std::complex<_Tp>& __z)
173     {
174       std::complex<_Tp> __t((__z.real() - __z.imag())
175                             * (__z.real() + __z.imag()) - _Tp(1.0),
176                             _Tp(2.0) * __z.real() * __z.imag());
177       __t = std::sqrt(__t);
178
179       return std::log(__t + __z);
180     }
181
182 #if _GLIBCXX_USE_C99_COMPLEX_TR1
183   inline __complex__ float
184   __complex_acosh(__complex__ float __z)
185   { return __builtin_cacoshf(__z); }
186
187   inline __complex__ double
188   __complex_acosh(__complex__ double __z)
189   { return __builtin_cacosh(__z); }
190
191   inline __complex__ long double
192   __complex_acosh(const __complex__ long double& __z)
193   { return __builtin_cacoshl(__z); }
194
195   template<typename _Tp>
196     inline std::complex<_Tp>
197     acosh(const std::complex<_Tp>& __z)
198     { return __complex_acosh(__z.__rep()); }
199 #else
200   /// acosh(__z) [8.1.5].
201   //  Effects:  Behaves the same as C99 function cacosh, defined
202   //            in subclause 7.3.6.1.
203   template<typename _Tp>
204     inline std::complex<_Tp>
205     acosh(const std::complex<_Tp>& __z)
206     { return __complex_acosh(__z); }
207 #endif
208
209   template<typename _Tp>
210     std::complex<_Tp>
211     __complex_asinh(const std::complex<_Tp>& __z)
212     {
213       std::complex<_Tp> __t((__z.real() - __z.imag())
214                             * (__z.real() + __z.imag()) + _Tp(1.0),
215                             _Tp(2.0) * __z.real() * __z.imag());
216       __t = std::sqrt(__t);
217
218       return std::log(__t + __z);
219     }
220
221 #if _GLIBCXX_USE_C99_COMPLEX_TR1
222   inline __complex__ float
223   __complex_asinh(__complex__ float __z)
224   { return __builtin_casinhf(__z); }
225
226   inline __complex__ double
227   __complex_asinh(__complex__ double __z)
228   { return __builtin_casinh(__z); }
229
230   inline __complex__ long double
231   __complex_asinh(const __complex__ long double& __z)
232   { return __builtin_casinhl(__z); }
233
234   template<typename _Tp>
235     inline std::complex<_Tp>
236     asinh(const std::complex<_Tp>& __z)
237     { return __complex_asinh(__z.__rep()); }
238 #else
239   /// asinh(__z) [8.1.6].
240   //  Effects:  Behaves the same as C99 function casin, defined
241   //            in subclause 7.3.6.2.
242   template<typename _Tp>
243     inline std::complex<_Tp>
244     asinh(const std::complex<_Tp>& __z)
245     { return __complex_asinh(__z); }
246 #endif
247
248   template<typename _Tp>
249     std::complex<_Tp>
250     __complex_atanh(const std::complex<_Tp>& __z)
251     {
252       const _Tp __i2 = __z.imag() * __z.imag();
253       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
254
255       _Tp __num = _Tp(1.0) + __z.real();
256       _Tp __den = _Tp(1.0) - __z.real();
257
258       __num = __i2 + __num * __num;
259       __den = __i2 + __den * __den;
260
261       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
262                                _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
263     }
264
265 #if _GLIBCXX_USE_C99_COMPLEX_TR1
266   inline __complex__ float
267   __complex_atanh(__complex__ float __z)
268   { return __builtin_catanhf(__z); }
269
270   inline __complex__ double
271   __complex_atanh(__complex__ double __z)
272   { return __builtin_catanh(__z); }
273
274   inline __complex__ long double
275   __complex_atanh(const __complex__ long double& __z)
276   { return __builtin_catanhl(__z); }
277
278   template<typename _Tp>
279     inline std::complex<_Tp>
280     atanh(const std::complex<_Tp>& __z)
281     { return __complex_atanh(__z.__rep()); }
282 #else
283   /// atanh(__z) [8.1.7].
284   //  Effects:  Behaves the same as C99 function catanh, defined
285   //            in subclause 7.3.6.3.
286   template<typename _Tp>
287     inline std::complex<_Tp>
288     atanh(const std::complex<_Tp>& __z)
289     { return __complex_atanh(__z); }
290 #endif
291
292   template<typename _Tp>
293 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
294     inline _Tp
295 #else
296     inline std::complex<_Tp>
297 #endif
298     /// fabs(__z) [8.1.8].
299     //  Effects:  Behaves the same as C99 function cabs, defined
300     //            in subclause 7.3.8.1.
301     fabs(const std::complex<_Tp>& __z)
302     { return std::abs(__z); }
303
304   /// Additional overloads [8.1.9].
305 #if (defined(_GLIBCXX_INCLUDE_AS_CXX0X) \
306      || (defined(_GLIBCXX_INCLUDE_AS_TR1) \
307          && !defined(__GXX_EXPERIMENTAL_CXX0X__)))
308
309   template<typename _Tp>
310     inline typename __gnu_cxx::__promote<_Tp>::__type
311     arg(_Tp __x)
312     {
313       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
314       return std::arg(std::complex<__type>(__x));
315     }
316
317   template<typename _Tp>
318     inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
319     conj(_Tp __x)
320     { return __x; }
321
322   template<typename _Tp>
323     inline typename __gnu_cxx::__promote<_Tp>::__type
324     imag(_Tp)
325     { return _Tp(); }
326
327   template<typename _Tp>
328     inline typename __gnu_cxx::__promote<_Tp>::__type
329     norm(_Tp __x)
330     {
331       typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
332       return __type(__x) * __type(__x);
333     }
334
335   template<typename _Tp>
336     inline typename __gnu_cxx::__promote<_Tp>::__type
337     real(_Tp __x)
338     { return __x; }
339
340 #endif
341
342   template<typename _Tp, typename _Up>
343     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
344     pow(const std::complex<_Tp>& __x, const _Up& __y)
345     {
346       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
347       return std::pow(std::complex<__type>(__x), __type(__y));
348     }
349
350   template<typename _Tp, typename _Up>
351     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
352     pow(const _Tp& __x, const std::complex<_Up>& __y)
353     {
354       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
355       return std::pow(__type(__x), std::complex<__type>(__y));
356     }
357
358   template<typename _Tp, typename _Up>
359     inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type>
360     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
361     {
362       typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
363       return std::pow(std::complex<__type>(__x),
364                       std::complex<__type>(__y));
365     }
366
367   // @} group complex_numbers
368
369 _GLIBCXX_END_NAMESPACE_TR1
370 }