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