OSDN Git Service

2006-01-25 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / complex
1 // TR1 complex -*- C++ -*-
2
3 // Copyright (C) 2006 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.
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 // 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.
20
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.
29
30 /** @file 
31  *  This is a TR1 C++ Library header. 
32  */
33
34 #ifndef _TR1_COMPLEX
35 #define _TR1_COMPLEX 1
36
37 #include "../complex"
38 #include <tr1/common.h>
39
40 // namespace std::tr1
41 namespace std
42 {
43 _GLIBCXX_BEGIN_NAMESPACE(tr1)
44
45   // Forward declarations.
46   template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&);
47   template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&);
48   template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&);
49
50   template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&);
51   template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&);
52   template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&);
53   template<typename _Tp> std::complex<_Tp> fabs(const std::complex<_Tp>&);
54
55   /// @brief acos(__z) [8.1.2].
56   //  Effects:  Behaves the same as C99 function cacos, defined
57   //            in subclause 7.3.5.1.
58   template<typename _Tp>
59     inline std::complex<_Tp>
60     __complex_acos(const std::complex<_Tp>& __z)
61     {
62       const std::complex<_Tp> __t = std::tr1::asin(__z);
63       const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
64       return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
65     }
66
67 #if _GLIBCXX_USE_C99_COMPLEX_TR1
68   inline __complex__ float
69   __complex_acos(__complex__ float __z)
70   { return __builtin_cacosf(__z); }
71
72   inline __complex__ double
73   __complex_acos(__complex__ double __z)
74   { return __builtin_cacos(__z); }
75
76   inline __complex__ long double
77   __complex_acos(const __complex__ long double& __z)
78   { return __builtin_cacosl(__z); }
79
80   template<typename _Tp>
81     inline std::complex<_Tp>
82     acos(const std::complex<_Tp>& __z)
83     { return __complex_acos(__z.__rep()); }
84 #else
85   template<typename _Tp>
86     inline std::complex<_Tp>
87     acos(const std::complex<_Tp>& __z)
88     { return __complex_acos(__z); }
89 #endif
90
91   /// @brief asin(__z) [8.1.3].
92   //  Effects:  Behaves the same as C99 function casin, defined
93   //            in subclause 7.3.5.2.
94   template<typename _Tp>
95     inline std::complex<_Tp>
96     __complex_asin(const std::complex<_Tp>& __z)
97     {
98       std::complex<_Tp> __t(-__z.imag(), __z.real());
99       __t = std::tr1::asinh(__t);
100       return std::complex<_Tp>(__t.imag(), -__t.real());
101     }
102
103 #if _GLIBCXX_USE_C99_COMPLEX_TR1
104   inline __complex__ float
105   __complex_asin(__complex__ float __z)
106   { return __builtin_casinf(__z); }
107
108   inline __complex__ double
109   __complex_asin(__complex__ double __z)
110   { return __builtin_casin(__z); }
111
112   inline __complex__ long double
113   __complex_asin(const __complex__ long double& __z)
114   { return __builtin_casinl(__z); }
115
116   template<typename _Tp>
117     inline std::complex<_Tp>
118     asin(const std::complex<_Tp>& __z)
119     { return __complex_asin(__z.__rep()); }
120 #else
121   template<typename _Tp>
122     inline std::complex<_Tp>
123     asin(const std::complex<_Tp>& __z)
124     { return __complex_asin(__z); }
125 #endif
126   
127   /// @brief atan(__z) [8.1.4].
128   //  Effects:  Behaves the same as C99 function catan, defined
129   //            in subclause 7.3.5.3.
130   template<typename _Tp>
131     std::complex<_Tp>
132     __complex_atan(const std::complex<_Tp>& __z)
133     {
134       const _Tp __r2 = __z.real() * __z.real();
135       const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag();
136
137       _Tp __num = __z.imag() + _Tp(1.0);
138       _Tp __den = __z.imag() - _Tp(1.0);
139
140       __num = __r2 + __num * __num;
141       __den = __r2 + __den * __den;
142
143       return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x),
144                                _Tp(0.25) * log(__num / __den));
145     }
146
147 #if _GLIBCXX_USE_C99_COMPLEX_TR1
148   inline __complex__ float
149   __complex_atan(__complex__ float __z)
150   { return __builtin_catanf(__z); }
151
152   inline __complex__ double
153   __complex_atan(__complex__ double __z)
154   { return __builtin_catan(__z); }
155
156   inline __complex__ long double
157   __complex_atan(const __complex__ long double& __z)
158   { return __builtin_catanl(__z); }
159
160   template<typename _Tp>
161     inline std::complex<_Tp>
162     atan(const std::complex<_Tp>& __z)
163     { return __complex_atan(__z.__rep()); }
164 #else
165   template<typename _Tp>
166     inline std::complex<_Tp>
167     atan(const std::complex<_Tp>& __z)
168     { return __complex_atan(__z); }
169 #endif
170
171   /// @brief acosh(__z) [8.1.5].
172   //  Effects:  Behaves the same as C99 function cacosh, defined
173   //            in subclause 7.3.6.1.
174   template<typename _Tp>
175     std::complex<_Tp>
176     __complex_acosh(const std::complex<_Tp>& __z)
177     {
178       std::complex<_Tp> __t((__z.real() - __z.imag())
179                             * (__z.real() + __z.imag()) - _Tp(1.0),
180                             _Tp(2.0) * __z.real() * __z.imag());
181       __t = std::sqrt(__t);
182
183       return std::log(__t + __z);
184     }
185
186 #if _GLIBCXX_USE_C99_COMPLEX_TR1
187   inline __complex__ float
188   __complex_acosh(__complex__ float __z)
189   { return __builtin_cacoshf(__z); }
190
191   inline __complex__ double
192   __complex_acosh(__complex__ double __z)
193   { return __builtin_cacosh(__z); }
194
195   inline __complex__ long double
196   __complex_acosh(const __complex__ long double& __z)
197   { return __builtin_cacoshl(__z); }
198
199   template<typename _Tp>
200     inline std::complex<_Tp>
201     acosh(const std::complex<_Tp>& __z)
202     { return __complex_acosh(__z.__rep()); }
203 #else
204   template<typename _Tp>
205     inline std::complex<_Tp>
206     acosh(const std::complex<_Tp>& __z)
207     { return __complex_acosh(__z); }
208 #endif
209
210   /// @brief asinh(__z) [8.1.6].
211   //  Effects:  Behaves the same as C99 function casin, defined
212   //            in subclause 7.3.6.2.
213   template<typename _Tp>
214     std::complex<_Tp>
215     __complex_asinh(const std::complex<_Tp>& __z)
216     {
217       std::complex<_Tp> __t((__z.real() - __z.imag())
218                             * (__z.real() + __z.imag()) + _Tp(1.0),
219                             _Tp(2.0) * __z.real() * __z.imag());
220       __t = std::sqrt(__t);
221
222       return std::log(__t + __z);
223     }
224
225 #if _GLIBCXX_USE_C99_COMPLEX_TR1
226   inline __complex__ float
227   __complex_asinh(__complex__ float __z)
228   { return __builtin_casinhf(__z); }
229
230   inline __complex__ double
231   __complex_asinh(__complex__ double __z)
232   { return __builtin_casinh(__z); }
233
234   inline __complex__ long double
235   __complex_asinh(const __complex__ long double& __z)
236   { return __builtin_casinhl(__z); }
237
238   template<typename _Tp>
239     inline std::complex<_Tp>
240     asinh(const std::complex<_Tp>& __z)
241     { return __complex_asinh(__z.__rep()); }
242 #else
243   template<typename _Tp>
244     inline std::complex<_Tp>
245     asinh(const std::complex<_Tp>& __z)
246     { return __complex_asinh(__z); }
247 #endif
248
249   /// @brief atanh(__z) [8.1.7].
250   //  Effects:  Behaves the same as C99 function catanh, defined
251   //            in subclause 7.3.6.3.
252   template<typename _Tp>
253     std::complex<_Tp>
254     __complex_atanh(const std::complex<_Tp>& __z)
255     {
256       const _Tp __i2 = __z.imag() * __z.imag();
257       const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real();
258
259       _Tp __num = _Tp(1.0) + __z.real();
260       _Tp __den = _Tp(1.0) - __z.real();
261
262       __num = __i2 + __num * __num;
263       __den = __i2 + __den * __den;
264
265       return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)),
266                                _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x));
267     }
268
269 #if _GLIBCXX_USE_C99_COMPLEX_TR1
270   inline __complex__ float
271   __complex_atanh(__complex__ float __z)
272   { return __builtin_catanhf(__z); }
273
274   inline __complex__ double
275   __complex_atanh(__complex__ double __z)
276   { return __builtin_catanh(__z); }
277
278   inline __complex__ long double
279   __complex_atanh(const __complex__ long double& __z)
280   { return __builtin_catanhl(__z); }
281
282   template<typename _Tp>
283     inline std::complex<_Tp>
284     atanh(const std::complex<_Tp>& __z)
285     { return __complex_atanh(__z.__rep()); }
286 #else
287   template<typename _Tp>
288     inline std::complex<_Tp>
289     atanh(const std::complex<_Tp>& __z)
290     { return __complex_atanh(__z); }
291 #endif
292
293   /// @brief fabs(__z) [8.1.8].
294   //  Effects:  Behaves the same as C99 function cabs, defined
295   //            in subclause 7.3.8.1.
296   template<typename _Tp>
297     inline std::complex<_Tp>
298     fabs(const std::complex<_Tp>& __z)
299     { return std::abs(__z); }
300
301
302   /// @brief Additional overloads [8.1.9].
303   //
304
305   // See common.h for the primary template.
306   template<typename _Tp, typename _Up>
307     struct __promote_2<std::complex<_Tp>, _Up>
308     {
309     public:
310       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
311     };
312
313   template<typename _Tp, typename _Up>
314     struct __promote_2<_Tp, std::complex<_Up> >
315     {
316     public:
317       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
318     };
319   
320   template<typename _Tp, typename _Up>
321     struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
322     {
323     public:
324       typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
325     };
326
327
328   template<typename _Tp>
329     inline typename __promote<_Tp>::__type
330     arg(_Tp __x)
331     {
332       typedef typename __promote<_Tp>::__type __type;
333       return std::arg(std::complex<__type>(__x));
334     }
335
336   template<typename _Tp>
337     inline std::complex<typename __promote<_Tp>::__type>
338     conj(_Tp __x)
339     { return __x; }
340
341   template<typename _Tp>
342     inline typename __promote<_Tp>::__type
343     imag(_Tp)
344     { return _Tp(); }
345
346   template<typename _Tp>
347     inline typename __promote<_Tp>::__type
348     norm(_Tp __x)
349     {
350       typedef typename __promote<_Tp>::__type __type;
351       return __type(__x) * __type(__x);
352     }
353
354   template<typename _Tp, typename _Up>
355     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
356     polar(const _Tp& __rho, const _Up& __theta)
357     {
358       typedef typename __promote_2<_Tp, _Up>::__type __type;
359       return std::polar(__type(__rho), __type(__theta));
360     }
361   
362   template<typename _Tp, typename _Up>
363     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
364     pow(const std::complex<_Tp>& __x, const _Up& __y)
365     {
366       typedef typename __promote_2<_Tp, _Up>::__type __type;
367       return std::pow(std::complex<__type>(__x), __type(__y));
368     }
369
370   template<typename _Tp, typename _Up>
371     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
372     pow(const _Tp& __x, const std::complex<_Up>& __y)
373     {
374       typedef typename __promote_2<_Tp, _Up>::__type __type;
375       return std::pow(__type(__x), std::complex<__type>(__y));
376     }
377
378   template<typename _Tp, typename _Up>
379     inline std::complex<typename __promote_2<_Tp, _Up>::__type>
380     pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y)
381     {
382       typedef typename __promote_2<_Tp, _Up>::__type __type;
383       return std::pow(std::complex<__type>(__x),
384                       std::complex<__type>(__y));
385     }
386
387   template<typename _Tp>
388     inline typename __promote<_Tp>::__type
389     real(_Tp __x)
390     { return __x; }
391
392 _GLIBCXX_END_NAMESPACE
393 }
394
395 #endif