]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // The template and inlines for the -*- C++ -*- complex number classes. |
de96ac46 | 2 | |
7adcbafe | 3 | // Copyright (C) 1997-2022 Free Software Foundation, Inc. |
de96ac46 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
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 | ||
748086b7 JJ |
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. | |
de96ac46 | 19 | |
748086b7 JJ |
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/>. | |
de96ac46 | 24 | |
ad68e9fc | 25 | /** @file include/complex |
143c27b0 BK |
26 | * This is a Standard C++ Library header. |
27 | */ | |
28 | ||
54c1bf78 BK |
29 | // |
30 | // ISO C++ 14882: 26.2 Complex Numbers | |
31 | // Note: this is not a conforming implementation. | |
32 | // Initially implemented by Ulrich Drepper <drepper@cygnus.com> | |
33 | // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> | |
34 | // | |
35 | ||
1143680e SE |
36 | #ifndef _GLIBCXX_COMPLEX |
37 | #define _GLIBCXX_COMPLEX 1 | |
54c1bf78 BK |
38 | |
39 | #pragma GCC system_header | |
40 | ||
41 | #include <bits/c++config.h> | |
42 | #include <bits/cpp_type_traits.h> | |
e133ace8 | 43 | #include <ext/type_traits.h> |
54c1bf78 BK |
44 | #include <cmath> |
45 | #include <sstream> | |
46 | ||
1c259e8b MG |
47 | // Get rid of a macro possibly defined in <complex.h> |
48 | #undef complex | |
49 | ||
393283b8 JW |
50 | #if __cplusplus > 201703L |
51 | # define __cpp_lib_constexpr_complex 201711L | |
52 | #endif | |
53 | ||
12ffa228 BK |
54 | namespace std _GLIBCXX_VISIBILITY(default) |
55 | { | |
56 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 57 | |
5b9daa7e BK |
58 | /** |
59 | * @defgroup complex_numbers Complex Numbers | |
60 | * @ingroup numerics | |
61 | * | |
62 | * Classes and functions for complex numbers. | |
63 | * @{ | |
64 | */ | |
65 | ||
52e6723c | 66 | // Forward declarations. |
54c1bf78 BK |
67 | template<typename _Tp> class complex; |
68 | template<> class complex<float>; | |
69 | template<> class complex<double>; | |
70 | template<> class complex<long double>; | |
71 | ||
ffcec5c8 | 72 | /// Return magnitude of @a z. |
54c1bf78 | 73 | template<typename _Tp> _Tp abs(const complex<_Tp>&); |
ffcec5c8 | 74 | /// Return phase angle of @a z. |
54c1bf78 | 75 | template<typename _Tp> _Tp arg(const complex<_Tp>&); |
ffcec5c8 | 76 | /// Return @a z magnitude squared. |
e987fb1e | 77 | template<typename _Tp> _Tp _GLIBCXX20_CONSTEXPR norm(const complex<_Tp>&); |
54c1bf78 | 78 | |
ffcec5c8 | 79 | /// Return complex conjugate of @a z. |
e987fb1e ESR |
80 | template<typename _Tp> |
81 | _GLIBCXX20_CONSTEXPR complex<_Tp> conj(const complex<_Tp>&); | |
ffcec5c8 | 82 | /// Return complex with magnitude @a rho and angle @a theta. |
54c1bf78 BK |
83 | template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); |
84 | ||
85 | // Transcendentals: | |
ffcec5c8 | 86 | /// Return complex cosine of @a z. |
54c1bf78 | 87 | template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); |
ffcec5c8 | 88 | /// Return complex hyperbolic cosine of @a z. |
54c1bf78 | 89 | template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); |
ffcec5c8 | 90 | /// Return complex base e exponential of @a z. |
54c1bf78 | 91 | template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); |
ffcec5c8 | 92 | /// Return complex natural logarithm of @a z. |
54c1bf78 | 93 | template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); |
ffcec5c8 | 94 | /// Return complex base 10 logarithm of @a z. |
54c1bf78 | 95 | template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); |
3fd29fa9 | 96 | /// Return @a x to the @a y'th power. |
54c1bf78 | 97 | template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); |
ffcec5c8 | 98 | /// Return @a x to the @a y'th power. |
54c1bf78 | 99 | template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); |
ffcec5c8 | 100 | /// Return @a x to the @a y'th power. |
33ac58d5 | 101 | template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, |
a4ddde0d | 102 | const complex<_Tp>&); |
ffcec5c8 | 103 | /// Return @a x to the @a y'th power. |
54c1bf78 | 104 | template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); |
ffcec5c8 | 105 | /// Return complex sine of @a z. |
54c1bf78 | 106 | template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); |
ffcec5c8 | 107 | /// Return complex hyperbolic sine of @a z. |
54c1bf78 | 108 | template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); |
ffcec5c8 | 109 | /// Return complex square root of @a z. |
54c1bf78 | 110 | template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); |
ffcec5c8 | 111 | /// Return complex tangent of @a z. |
54c1bf78 | 112 | template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); |
ffcec5c8 | 113 | /// Return complex hyperbolic tangent of @a z. |
54c1bf78 | 114 | template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); |
33ac58d5 JW |
115 | |
116 | ||
54c1bf78 | 117 | // 26.2.2 Primary template class complex |
ffcec5c8 JQ |
118 | /** |
119 | * Template to represent complex numbers. | |
120 | * | |
121 | * Specializations for float, double, and long double are part of the | |
122 | * library. Results with any other type are not guaranteed. | |
123 | * | |
124 | * @param Tp Type of real and imaginary values. | |
125 | */ | |
54c1bf78 | 126 | template<typename _Tp> |
0e5abeb0 | 127 | class complex |
54c1bf78 | 128 | { |
0e5abeb0 | 129 | public: |
ffcec5c8 | 130 | /// Value typedef. |
54c1bf78 | 131 | typedef _Tp value_type; |
33ac58d5 | 132 | |
ffcec5c8 JQ |
133 | /// Default constructor. First parameter is x, second parameter is y. |
134 | /// Unspecified parameters default to 0. | |
94a86be0 | 135 | _GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp()) |
2acceeac | 136 | : _M_real(__r), _M_imag(__i) { } |
54c1bf78 | 137 | |
fa794dc6 JW |
138 | // Let the compiler synthesize the copy constructor |
139 | #if __cplusplus >= 201103L | |
140 | constexpr complex(const complex&) = default; | |
141 | #endif | |
142 | ||
143 | /// Converting constructor. | |
54c1bf78 | 144 | template<typename _Up> |
94a86be0 | 145 | _GLIBCXX_CONSTEXPR complex(const complex<_Up>& __z) |
2acceeac | 146 | : _M_real(__z.real()), _M_imag(__z.imag()) { } |
3b3bfc0e | 147 | |
734f5023 | 148 | #if __cplusplus >= 201103L |
23ed71c6 PC |
149 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
150 | // DR 387. std::complex over-encapsulated. | |
3b31a727 | 151 | _GLIBCXX_ABI_TAG_CXX11 |
33ac58d5 | 152 | constexpr _Tp |
327a79a5 | 153 | real() const { return _M_real; } |
23ed71c6 | 154 | |
3b31a727 | 155 | _GLIBCXX_ABI_TAG_CXX11 |
33ac58d5 | 156 | constexpr _Tp |
327a79a5 | 157 | imag() const { return _M_imag; } |
23ed71c6 | 158 | #else |
ffcec5c8 | 159 | /// Return real part of complex number. |
33ac58d5 | 160 | _Tp& |
94a86be0 | 161 | real() { return _M_real; } |
2acceeac | 162 | |
ffcec5c8 | 163 | /// Return real part of complex number. |
33ac58d5 | 164 | const _Tp& |
94a86be0 | 165 | real() const { return _M_real; } |
2acceeac | 166 | |
ffcec5c8 | 167 | /// Return imaginary part of complex number. |
33ac58d5 | 168 | _Tp& |
94a86be0 | 169 | imag() { return _M_imag; } |
2acceeac | 170 | |
ffcec5c8 | 171 | /// Return imaginary part of complex number. |
33ac58d5 | 172 | const _Tp& |
94a86be0 | 173 | imag() const { return _M_imag; } |
23ed71c6 PC |
174 | #endif |
175 | ||
176 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
177 | // DR 387. std::complex over-encapsulated. | |
e987fb1e | 178 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 179 | real(_Tp __val) { _M_real = __val; } |
23ed71c6 | 180 | |
e987fb1e | 181 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 182 | imag(_Tp __val) { _M_imag = __val; } |
54c1bf78 | 183 | |
fa794dc6 | 184 | /// Assign a scalar to this complex number. |
e987fb1e | 185 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const _Tp&); |
33ac58d5 | 186 | |
fa794dc6 | 187 | /// Add a scalar to this complex number. |
2acceeac | 188 | // 26.2.5/1 |
e987fb1e | 189 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
2acceeac PC |
190 | operator+=(const _Tp& __t) |
191 | { | |
192 | _M_real += __t; | |
193 | return *this; | |
194 | } | |
195 | ||
fa794dc6 | 196 | /// Subtract a scalar from this complex number. |
2acceeac | 197 | // 26.2.5/3 |
e987fb1e | 198 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
2acceeac PC |
199 | operator-=(const _Tp& __t) |
200 | { | |
201 | _M_real -= __t; | |
202 | return *this; | |
203 | } | |
204 | ||
fa794dc6 | 205 | /// Multiply this complex number by a scalar. |
e987fb1e | 206 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const _Tp&); |
fa794dc6 | 207 | /// Divide this complex number by a scalar. |
e987fb1e | 208 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const _Tp&); |
54c1bf78 | 209 | |
fa794dc6 JW |
210 | // Let the compiler synthesize the copy assignment operator |
211 | #if __cplusplus >= 201103L | |
e987fb1e | 212 | _GLIBCXX20_CONSTEXPR complex& operator=(const complex&) = default; |
fa794dc6 JW |
213 | #endif |
214 | ||
215 | /// Assign another complex number to this one. | |
54c1bf78 | 216 | template<typename _Up> |
e987fb1e | 217 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator=(const complex<_Up>&); |
fa794dc6 | 218 | /// Add another complex number to this one. |
54c1bf78 | 219 | template<typename _Up> |
e987fb1e | 220 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator+=(const complex<_Up>&); |
fa794dc6 | 221 | /// Subtract another complex number from this one. |
54c1bf78 | 222 | template<typename _Up> |
e987fb1e | 223 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator-=(const complex<_Up>&); |
fa794dc6 | 224 | /// Multiply this complex number by another. |
54c1bf78 | 225 | template<typename _Up> |
e987fb1e | 226 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator*=(const complex<_Up>&); |
fa794dc6 | 227 | /// Divide this complex number by another. |
54c1bf78 | 228 | template<typename _Up> |
e987fb1e | 229 | _GLIBCXX20_CONSTEXPR complex<_Tp>& operator/=(const complex<_Up>&); |
54c1bf78 | 230 | |
3fa591d4 | 231 | _GLIBCXX_CONSTEXPR complex __rep() const |
2acceeac | 232 | { return *this; } |
a4ddde0d | 233 | |
54c1bf78 | 234 | private: |
3b3bfc0e GDR |
235 | _Tp _M_real; |
236 | _Tp _M_imag; | |
54c1bf78 BK |
237 | }; |
238 | ||
54c1bf78 | 239 | template<typename _Tp> |
e987fb1e | 240 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
241 | complex<_Tp>::operator=(const _Tp& __t) |
242 | { | |
243 | _M_real = __t; | |
244 | _M_imag = _Tp(); | |
245 | return *this; | |
33ac58d5 | 246 | } |
54c1bf78 | 247 | |
54c1bf78 BK |
248 | // 26.2.5/5 |
249 | template<typename _Tp> | |
e987fb1e | 250 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
251 | complex<_Tp>::operator*=(const _Tp& __t) |
252 | { | |
253 | _M_real *= __t; | |
254 | _M_imag *= __t; | |
255 | return *this; | |
256 | } | |
257 | ||
258 | // 26.2.5/7 | |
259 | template<typename _Tp> | |
e987fb1e | 260 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
261 | complex<_Tp>::operator/=(const _Tp& __t) |
262 | { | |
263 | _M_real /= __t; | |
264 | _M_imag /= __t; | |
265 | return *this; | |
266 | } | |
267 | ||
268 | template<typename _Tp> | |
269 | template<typename _Up> | |
e987fb1e | 270 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
271 | complex<_Tp>::operator=(const complex<_Up>& __z) |
272 | { | |
273 | _M_real = __z.real(); | |
274 | _M_imag = __z.imag(); | |
275 | return *this; | |
276 | } | |
277 | ||
278 | // 26.2.5/9 | |
279 | template<typename _Tp> | |
280 | template<typename _Up> | |
e987fb1e | 281 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
282 | complex<_Tp>::operator+=(const complex<_Up>& __z) |
283 | { | |
284 | _M_real += __z.real(); | |
285 | _M_imag += __z.imag(); | |
286 | return *this; | |
287 | } | |
288 | ||
289 | // 26.2.5/11 | |
290 | template<typename _Tp> | |
291 | template<typename _Up> | |
e987fb1e | 292 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
293 | complex<_Tp>::operator-=(const complex<_Up>& __z) |
294 | { | |
295 | _M_real -= __z.real(); | |
296 | _M_imag -= __z.imag(); | |
297 | return *this; | |
298 | } | |
299 | ||
300 | // 26.2.5/13 | |
301 | // XXX: This is a grammar school implementation. | |
302 | template<typename _Tp> | |
303 | template<typename _Up> | |
e987fb1e | 304 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
305 | complex<_Tp>::operator*=(const complex<_Up>& __z) |
306 | { | |
307 | const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); | |
308 | _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); | |
309 | _M_real = __r; | |
310 | return *this; | |
311 | } | |
312 | ||
313 | // 26.2.5/15 | |
314 | // XXX: This is a grammar school implementation. | |
315 | template<typename _Tp> | |
316 | template<typename _Up> | |
e987fb1e | 317 | _GLIBCXX20_CONSTEXPR complex<_Tp>& |
54c1bf78 BK |
318 | complex<_Tp>::operator/=(const complex<_Up>& __z) |
319 | { | |
320 | const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); | |
eb9a4231 | 321 | const _Tp __n = std::norm(__z); |
54c1bf78 BK |
322 | _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; |
323 | _M_real = __r / __n; | |
324 | return *this; | |
325 | } | |
33ac58d5 | 326 | |
54c1bf78 | 327 | // Operators: |
f0b88346 | 328 | ///@{ |
ffcec5c8 | 329 | /// Return new complex value @a x plus @a y. |
54c1bf78 | 330 | template<typename _Tp> |
e987fb1e | 331 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 332 | operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
333 | { |
334 | complex<_Tp> __r = __x; | |
335 | __r += __y; | |
336 | return __r; | |
337 | } | |
54c1bf78 BK |
338 | |
339 | template<typename _Tp> | |
e987fb1e | 340 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 341 | operator+(const complex<_Tp>& __x, const _Tp& __y) |
3b3bfc0e GDR |
342 | { |
343 | complex<_Tp> __r = __x; | |
23cdf8e8 | 344 | __r += __y; |
3b3bfc0e GDR |
345 | return __r; |
346 | } | |
54c1bf78 BK |
347 | |
348 | template<typename _Tp> | |
e987fb1e | 349 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 350 | operator+(const _Tp& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
351 | { |
352 | complex<_Tp> __r = __y; | |
23cdf8e8 | 353 | __r += __x; |
3b3bfc0e GDR |
354 | return __r; |
355 | } | |
f0b88346 | 356 | ///@} |
54c1bf78 | 357 | |
f0b88346 | 358 | ///@{ |
ffcec5c8 | 359 | /// Return new complex value @a x minus @a y. |
54c1bf78 | 360 | template<typename _Tp> |
e987fb1e | 361 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 362 | operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
363 | { |
364 | complex<_Tp> __r = __x; | |
365 | __r -= __y; | |
366 | return __r; | |
367 | } | |
33ac58d5 | 368 | |
54c1bf78 | 369 | template<typename _Tp> |
e987fb1e | 370 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 371 | operator-(const complex<_Tp>& __x, const _Tp& __y) |
3b3bfc0e GDR |
372 | { |
373 | complex<_Tp> __r = __x; | |
23cdf8e8 | 374 | __r -= __y; |
3b3bfc0e GDR |
375 | return __r; |
376 | } | |
54c1bf78 BK |
377 | |
378 | template<typename _Tp> | |
e987fb1e | 379 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 380 | operator-(const _Tp& __x, const complex<_Tp>& __y) |
3b3bfc0e | 381 | { |
e987fb1e ESR |
382 | complex<_Tp> __r = -__y; |
383 | __r += __x; | |
3b3bfc0e GDR |
384 | return __r; |
385 | } | |
f0b88346 | 386 | ///@} |
54c1bf78 | 387 | |
f0b88346 | 388 | ///@{ |
ffcec5c8 | 389 | /// Return new complex value @a x times @a y. |
54c1bf78 | 390 | template<typename _Tp> |
e987fb1e | 391 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 392 | operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
393 | { |
394 | complex<_Tp> __r = __x; | |
395 | __r *= __y; | |
396 | return __r; | |
397 | } | |
54c1bf78 BK |
398 | |
399 | template<typename _Tp> | |
e987fb1e | 400 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 401 | operator*(const complex<_Tp>& __x, const _Tp& __y) |
3b3bfc0e GDR |
402 | { |
403 | complex<_Tp> __r = __x; | |
404 | __r *= __y; | |
405 | return __r; | |
406 | } | |
54c1bf78 BK |
407 | |
408 | template<typename _Tp> | |
e987fb1e | 409 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 410 | operator*(const _Tp& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
411 | { |
412 | complex<_Tp> __r = __y; | |
413 | __r *= __x; | |
414 | return __r; | |
415 | } | |
f0b88346 | 416 | ///@} |
54c1bf78 | 417 | |
f0b88346 | 418 | ///@{ |
ffcec5c8 | 419 | /// Return new complex value @a x divided by @a y. |
54c1bf78 | 420 | template<typename _Tp> |
e987fb1e | 421 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 422 | operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
423 | { |
424 | complex<_Tp> __r = __x; | |
425 | __r /= __y; | |
426 | return __r; | |
427 | } | |
33ac58d5 | 428 | |
54c1bf78 | 429 | template<typename _Tp> |
e987fb1e | 430 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 431 | operator/(const complex<_Tp>& __x, const _Tp& __y) |
3b3bfc0e GDR |
432 | { |
433 | complex<_Tp> __r = __x; | |
434 | __r /= __y; | |
435 | return __r; | |
436 | } | |
54c1bf78 BK |
437 | |
438 | template<typename _Tp> | |
e987fb1e | 439 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 440 | operator/(const _Tp& __x, const complex<_Tp>& __y) |
3b3bfc0e GDR |
441 | { |
442 | complex<_Tp> __r = __x; | |
443 | __r /= __y; | |
444 | return __r; | |
445 | } | |
f0b88346 | 446 | ///@} |
54c1bf78 | 447 | |
ffcec5c8 | 448 | /// Return @a x. |
54c1bf78 | 449 | template<typename _Tp> |
e987fb1e | 450 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 BK |
451 | operator+(const complex<_Tp>& __x) |
452 | { return __x; } | |
453 | ||
ffcec5c8 | 454 | /// Return complex negation of @a x. |
54c1bf78 | 455 | template<typename _Tp> |
e987fb1e | 456 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 | 457 | operator-(const complex<_Tp>& __x) |
e987fb1e | 458 | { return complex<_Tp>(-__x.real(), -__x.imag()); } |
54c1bf78 | 459 | |
f0b88346 | 460 | ///@{ |
ffcec5c8 | 461 | /// Return true if @a x is equal to @a y. |
54c1bf78 | 462 | template<typename _Tp> |
eda0ab6e | 463 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
464 | operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) |
465 | { return __x.real() == __y.real() && __x.imag() == __y.imag(); } | |
466 | ||
467 | template<typename _Tp> | |
eda0ab6e | 468 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
469 | operator==(const complex<_Tp>& __x, const _Tp& __y) |
470 | { return __x.real() == __y && __x.imag() == _Tp(); } | |
471 | ||
ef389dad | 472 | #if !(__cpp_impl_three_way_comparison >= 201907L) |
54c1bf78 | 473 | template<typename _Tp> |
eda0ab6e | 474 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
475 | operator==(const _Tp& __x, const complex<_Tp>& __y) |
476 | { return __x == __y.real() && _Tp() == __y.imag(); } | |
f0b88346 | 477 | ///@} |
54c1bf78 | 478 | |
f0b88346 | 479 | ///@{ |
ffcec5c8 | 480 | /// Return false if @a x is equal to @a y. |
54c1bf78 | 481 | template<typename _Tp> |
eda0ab6e | 482 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
483 | operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) |
484 | { return __x.real() != __y.real() || __x.imag() != __y.imag(); } | |
485 | ||
486 | template<typename _Tp> | |
eda0ab6e | 487 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
488 | operator!=(const complex<_Tp>& __x, const _Tp& __y) |
489 | { return __x.real() != __y || __x.imag() != _Tp(); } | |
490 | ||
491 | template<typename _Tp> | |
eda0ab6e | 492 | inline _GLIBCXX_CONSTEXPR bool |
54c1bf78 BK |
493 | operator!=(const _Tp& __x, const complex<_Tp>& __y) |
494 | { return __x != __y.real() || _Tp() != __y.imag(); } | |
ef389dad | 495 | #endif |
f0b88346 | 496 | ///@} |
54c1bf78 | 497 | |
ffcec5c8 | 498 | /// Extraction operator for complex values. |
54c1bf78 BK |
499 | template<typename _Tp, typename _CharT, class _Traits> |
500 | basic_istream<_CharT, _Traits>& | |
501 | operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) | |
502 | { | |
3ca652c1 | 503 | bool __fail = true; |
54c1bf78 | 504 | _CharT __ch; |
3ca652c1 | 505 | if (__is >> __ch) |
54c1bf78 | 506 | { |
3ca652c1 | 507 | if (_Traits::eq(__ch, __is.widen('('))) |
54c1bf78 | 508 | { |
3ca652c1 JW |
509 | _Tp __u; |
510 | if (__is >> __u >> __ch) | |
511 | { | |
512 | const _CharT __rparen = __is.widen(')'); | |
513 | if (_Traits::eq(__ch, __rparen)) | |
514 | { | |
515 | __x = __u; | |
516 | __fail = false; | |
517 | } | |
518 | else if (_Traits::eq(__ch, __is.widen(','))) | |
519 | { | |
520 | _Tp __v; | |
521 | if (__is >> __v >> __ch) | |
522 | { | |
523 | if (_Traits::eq(__ch, __rparen)) | |
524 | { | |
525 | __x = complex<_Tp>(__u, __v); | |
526 | __fail = false; | |
527 | } | |
528 | else | |
529 | __is.putback(__ch); | |
530 | } | |
531 | } | |
532 | else | |
533 | __is.putback(__ch); | |
534 | } | |
54c1bf78 | 535 | } |
54c1bf78 | 536 | else |
3ca652c1 JW |
537 | { |
538 | __is.putback(__ch); | |
539 | _Tp __u; | |
540 | if (__is >> __u) | |
541 | { | |
542 | __x = __u; | |
543 | __fail = false; | |
544 | } | |
545 | } | |
54c1bf78 | 546 | } |
3ca652c1 JW |
547 | if (__fail) |
548 | __is.setstate(ios_base::failbit); | |
54c1bf78 BK |
549 | return __is; |
550 | } | |
551 | ||
ffcec5c8 | 552 | /// Insertion operator for complex values. |
54c1bf78 BK |
553 | template<typename _Tp, typename _CharT, class _Traits> |
554 | basic_ostream<_CharT, _Traits>& | |
555 | operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) | |
556 | { | |
557 | basic_ostringstream<_CharT, _Traits> __s; | |
558 | __s.flags(__os.flags()); | |
559 | __s.imbue(__os.getloc()); | |
560 | __s.precision(__os.precision()); | |
f815521c | 561 | __s << '(' << __x.real() << ',' << __x.imag() << ')'; |
54c1bf78 BK |
562 | return __os << __s.str(); |
563 | } | |
564 | ||
565 | // Values | |
734f5023 | 566 | #if __cplusplus >= 201103L |
23ed71c6 | 567 | template<typename _Tp> |
a4eeb822 | 568 | constexpr _Tp |
23ed71c6 PC |
569 | real(const complex<_Tp>& __z) |
570 | { return __z.real(); } | |
a4eeb822 | 571 | |
23ed71c6 | 572 | template<typename _Tp> |
a4eeb822 | 573 | constexpr _Tp |
23ed71c6 PC |
574 | imag(const complex<_Tp>& __z) |
575 | { return __z.imag(); } | |
576 | #else | |
54c1bf78 | 577 | template<typename _Tp> |
3b3bfc0e GDR |
578 | inline _Tp& |
579 | real(complex<_Tp>& __z) | |
580 | { return __z.real(); } | |
33ac58d5 | 581 | |
3b3bfc0e GDR |
582 | template<typename _Tp> |
583 | inline const _Tp& | |
54c1bf78 BK |
584 | real(const complex<_Tp>& __z) |
585 | { return __z.real(); } | |
33ac58d5 | 586 | |
54c1bf78 | 587 | template<typename _Tp> |
3b3bfc0e GDR |
588 | inline _Tp& |
589 | imag(complex<_Tp>& __z) | |
590 | { return __z.imag(); } | |
33ac58d5 | 591 | |
3b3bfc0e GDR |
592 | template<typename _Tp> |
593 | inline const _Tp& | |
54c1bf78 BK |
594 | imag(const complex<_Tp>& __z) |
595 | { return __z.imag(); } | |
23ed71c6 | 596 | #endif |
54c1bf78 | 597 | |
a4ddde0d | 598 | // 26.2.7/3 abs(__z): Returns the magnitude of __z. |
54c1bf78 BK |
599 | template<typename _Tp> |
600 | inline _Tp | |
a4ddde0d | 601 | __complex_abs(const complex<_Tp>& __z) |
54c1bf78 BK |
602 | { |
603 | _Tp __x = __z.real(); | |
604 | _Tp __y = __z.imag(); | |
a8784c4c | 605 | const _Tp __s = std::max(abs(__x), abs(__y)); |
54c1bf78 BK |
606 | if (__s == _Tp()) // well ... |
607 | return __s; | |
33ac58d5 | 608 | __x /= __s; |
54c1bf78 | 609 | __y /= __s; |
52e6723c | 610 | return __s * sqrt(__x * __x + __y * __y); |
54c1bf78 BK |
611 | } |
612 | ||
ab9b9d2c | 613 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
614 | inline float |
615 | __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); } | |
616 | ||
617 | inline double | |
618 | __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); } | |
619 | ||
620 | inline long double | |
621 | __complex_abs(const __complex__ long double& __z) | |
52e6723c BK |
622 | { return __builtin_cabsl(__z); } |
623 | ||
a4ddde0d GDR |
624 | template<typename _Tp> |
625 | inline _Tp | |
626 | abs(const complex<_Tp>& __z) { return __complex_abs(__z.__rep()); } | |
52e6723c BK |
627 | #else |
628 | template<typename _Tp> | |
629 | inline _Tp | |
630 | abs(const complex<_Tp>& __z) { return __complex_abs(__z); } | |
33ac58d5 | 631 | #endif |
a4ddde0d GDR |
632 | |
633 | ||
634 | // 26.2.7/4: arg(__z): Returns the phase angle of __z. | |
54c1bf78 BK |
635 | template<typename _Tp> |
636 | inline _Tp | |
a4ddde0d | 637 | __complex_arg(const complex<_Tp>& __z) |
52e6723c | 638 | { return atan2(__z.imag(), __z.real()); } |
a4ddde0d | 639 | |
ab9b9d2c | 640 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
641 | inline float |
642 | __complex_arg(__complex__ float __z) { return __builtin_cargf(__z); } | |
643 | ||
644 | inline double | |
645 | __complex_arg(__complex__ double __z) { return __builtin_carg(__z); } | |
646 | ||
647 | inline long double | |
648 | __complex_arg(const __complex__ long double& __z) | |
649 | { return __builtin_cargl(__z); } | |
650 | ||
651 | template<typename _Tp> | |
652 | inline _Tp | |
653 | arg(const complex<_Tp>& __z) { return __complex_arg(__z.__rep()); } | |
52e6723c BK |
654 | #else |
655 | template<typename _Tp> | |
656 | inline _Tp | |
657 | arg(const complex<_Tp>& __z) { return __complex_arg(__z); } | |
658 | #endif | |
54c1bf78 | 659 | |
28dac70a | 660 | // 26.2.7/5: norm(__z) returns the squared magnitude of __z. |
54c1bf78 | 661 | // As defined, norm() is -not- a norm is the common mathematical |
fa794dc6 | 662 | // sense used in numerics. The helper class _Norm_helper<> tries to |
54c1bf78 BK |
663 | // distinguish between builtin floating point and the rest, so as |
664 | // to deliver an answer as close as possible to the real value. | |
665 | template<bool> | |
666 | struct _Norm_helper | |
667 | { | |
668 | template<typename _Tp> | |
d012ab60 | 669 | static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) |
54c1bf78 BK |
670 | { |
671 | const _Tp __x = __z.real(); | |
672 | const _Tp __y = __z.imag(); | |
673 | return __x * __x + __y * __y; | |
674 | } | |
675 | }; | |
676 | ||
677 | template<> | |
678 | struct _Norm_helper<true> | |
679 | { | |
680 | template<typename _Tp> | |
d012ab60 | 681 | static inline _GLIBCXX20_CONSTEXPR _Tp _S_do_it(const complex<_Tp>& __z) |
54c1bf78 | 682 | { |
e987fb1e ESR |
683 | //_Tp __res = std::abs(__z); |
684 | //return __res * __res; | |
685 | const _Tp __x = __z.real(); | |
686 | const _Tp __y = __z.imag(); | |
687 | return __x * __x + __y * __y; | |
54c1bf78 BK |
688 | } |
689 | }; | |
33ac58d5 | 690 | |
54c1bf78 | 691 | template<typename _Tp> |
e987fb1e | 692 | inline _GLIBCXX20_CONSTEXPR _Tp |
54c1bf78 BK |
693 | norm(const complex<_Tp>& __z) |
694 | { | |
33ac58d5 | 695 | return _Norm_helper<__is_floating<_Tp>::__value |
52e6723c | 696 | && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); |
54c1bf78 BK |
697 | } |
698 | ||
699 | template<typename _Tp> | |
700 | inline complex<_Tp> | |
701 | polar(const _Tp& __rho, const _Tp& __theta) | |
d0cad9fe | 702 | { |
2f1e8e7c | 703 | __glibcxx_assert( __rho >= 0 ); |
d0cad9fe JW |
704 | return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); |
705 | } | |
54c1bf78 BK |
706 | |
707 | template<typename _Tp> | |
e987fb1e | 708 | inline _GLIBCXX20_CONSTEXPR complex<_Tp> |
54c1bf78 BK |
709 | conj(const complex<_Tp>& __z) |
710 | { return complex<_Tp>(__z.real(), -__z.imag()); } | |
33ac58d5 | 711 | |
54c1bf78 | 712 | // Transcendentals |
a4ddde0d GDR |
713 | |
714 | // 26.2.8/1 cos(__z): Returns the cosine of __z. | |
54c1bf78 BK |
715 | template<typename _Tp> |
716 | inline complex<_Tp> | |
a4ddde0d | 717 | __complex_cos(const complex<_Tp>& __z) |
54c1bf78 BK |
718 | { |
719 | const _Tp __x = __z.real(); | |
720 | const _Tp __y = __z.imag(); | |
a8784c4c | 721 | return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); |
54c1bf78 BK |
722 | } |
723 | ||
ab9b9d2c | 724 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
725 | inline __complex__ float |
726 | __complex_cos(__complex__ float __z) { return __builtin_ccosf(__z); } | |
727 | ||
728 | inline __complex__ double | |
729 | __complex_cos(__complex__ double __z) { return __builtin_ccos(__z); } | |
730 | ||
731 | inline __complex__ long double | |
732 | __complex_cos(const __complex__ long double& __z) | |
733 | { return __builtin_ccosl(__z); } | |
52e6723c | 734 | |
54c1bf78 BK |
735 | template<typename _Tp> |
736 | inline complex<_Tp> | |
a4ddde0d | 737 | cos(const complex<_Tp>& __z) { return __complex_cos(__z.__rep()); } |
52e6723c BK |
738 | #else |
739 | template<typename _Tp> | |
740 | inline complex<_Tp> | |
741 | cos(const complex<_Tp>& __z) { return __complex_cos(__z); } | |
742 | #endif | |
a4ddde0d GDR |
743 | |
744 | // 26.2.8/2 cosh(__z): Returns the hyperbolic cosine of __z. | |
745 | template<typename _Tp> | |
746 | inline complex<_Tp> | |
747 | __complex_cosh(const complex<_Tp>& __z) | |
9ef313e3 JD |
748 | { |
749 | const _Tp __x = __z.real(); | |
750 | const _Tp __y = __z.imag(); | |
751 | return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); | |
752 | } | |
a4ddde0d | 753 | |
ab9b9d2c | 754 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
755 | inline __complex__ float |
756 | __complex_cosh(__complex__ float __z) { return __builtin_ccoshf(__z); } | |
757 | ||
758 | inline __complex__ double | |
759 | __complex_cosh(__complex__ double __z) { return __builtin_ccosh(__z); } | |
760 | ||
761 | inline __complex__ long double | |
762 | __complex_cosh(const __complex__ long double& __z) | |
763 | { return __builtin_ccoshl(__z); } | |
54c1bf78 BK |
764 | |
765 | template<typename _Tp> | |
766 | inline complex<_Tp> | |
a4ddde0d | 767 | cosh(const complex<_Tp>& __z) { return __complex_cosh(__z.__rep()); } |
52e6723c BK |
768 | #else |
769 | template<typename _Tp> | |
770 | inline complex<_Tp> | |
771 | cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } | |
772 | #endif | |
a4ddde0d GDR |
773 | |
774 | // 26.2.8/3 exp(__z): Returns the complex base e exponential of x | |
775 | template<typename _Tp> | |
776 | inline complex<_Tp> | |
777 | __complex_exp(const complex<_Tp>& __z) | |
742f66e7 | 778 | { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } |
54c1bf78 | 779 | |
ab9b9d2c | 780 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
781 | inline __complex__ float |
782 | __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } | |
783 | ||
784 | inline __complex__ double | |
785 | __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } | |
786 | ||
787 | inline __complex__ long double | |
9ef313e3 JD |
788 | __complex_exp(const __complex__ long double& __z) |
789 | { return __builtin_cexpl(__z); } | |
52e6723c | 790 | |
54c1bf78 BK |
791 | template<typename _Tp> |
792 | inline complex<_Tp> | |
a4ddde0d | 793 | exp(const complex<_Tp>& __z) { return __complex_exp(__z.__rep()); } |
52e6723c BK |
794 | #else |
795 | template<typename _Tp> | |
796 | inline complex<_Tp> | |
797 | exp(const complex<_Tp>& __z) { return __complex_exp(__z); } | |
798 | #endif | |
a4ddde0d | 799 | |
28dac70a | 800 | // 26.2.8/5 log(__z): Returns the natural complex logarithm of __z. |
a4ddde0d GDR |
801 | // The branch cut is along the negative axis. |
802 | template<typename _Tp> | |
803 | inline complex<_Tp> | |
804 | __complex_log(const complex<_Tp>& __z) | |
a8784c4c | 805 | { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } |
54c1bf78 | 806 | |
d5c405cc | 807 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
808 | inline __complex__ float |
809 | __complex_log(__complex__ float __z) { return __builtin_clogf(__z); } | |
810 | ||
811 | inline __complex__ double | |
812 | __complex_log(__complex__ double __z) { return __builtin_clog(__z); } | |
813 | ||
814 | inline __complex__ long double | |
815 | __complex_log(const __complex__ long double& __z) | |
d5c405cc | 816 | { return __builtin_clogl(__z); } |
a4ddde0d | 817 | |
d5c405cc PC |
818 | template<typename _Tp> |
819 | inline complex<_Tp> | |
820 | log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); } | |
821 | #else | |
a4ddde0d GDR |
822 | template<typename _Tp> |
823 | inline complex<_Tp> | |
b53dcf3e | 824 | log(const complex<_Tp>& __z) { return __complex_log(__z); } |
d5c405cc | 825 | #endif |
a4ddde0d | 826 | |
54c1bf78 BK |
827 | template<typename _Tp> |
828 | inline complex<_Tp> | |
829 | log10(const complex<_Tp>& __z) | |
a8784c4c | 830 | { return std::log(__z) / log(_Tp(10.0)); } |
54c1bf78 | 831 | |
a4ddde0d | 832 | // 26.2.8/10 sin(__z): Returns the sine of __z. |
54c1bf78 BK |
833 | template<typename _Tp> |
834 | inline complex<_Tp> | |
a4ddde0d | 835 | __complex_sin(const complex<_Tp>& __z) |
54c1bf78 BK |
836 | { |
837 | const _Tp __x = __z.real(); | |
838 | const _Tp __y = __z.imag(); | |
33ac58d5 | 839 | return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); |
54c1bf78 BK |
840 | } |
841 | ||
ab9b9d2c | 842 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
843 | inline __complex__ float |
844 | __complex_sin(__complex__ float __z) { return __builtin_csinf(__z); } | |
845 | ||
846 | inline __complex__ double | |
847 | __complex_sin(__complex__ double __z) { return __builtin_csin(__z); } | |
848 | ||
849 | inline __complex__ long double | |
850 | __complex_sin(const __complex__ long double& __z) | |
851 | { return __builtin_csinl(__z); } | |
852 | ||
54c1bf78 BK |
853 | template<typename _Tp> |
854 | inline complex<_Tp> | |
9ef313e3 | 855 | sin(const complex<_Tp>& __z) { return __complex_sin(__z.__rep()); } |
52e6723c BK |
856 | #else |
857 | template<typename _Tp> | |
858 | inline complex<_Tp> | |
859 | sin(const complex<_Tp>& __z) { return __complex_sin(__z); } | |
860 | #endif | |
a4ddde0d GDR |
861 | |
862 | // 26.2.8/11 sinh(__z): Returns the hyperbolic sine of __z. | |
863 | template<typename _Tp> | |
864 | inline complex<_Tp> | |
865 | __complex_sinh(const complex<_Tp>& __z) | |
54c1bf78 BK |
866 | { |
867 | const _Tp __x = __z.real(); | |
868 | const _Tp __y = __z.imag(); | |
a8784c4c | 869 | return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); |
54c1bf78 BK |
870 | } |
871 | ||
ab9b9d2c | 872 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d | 873 | inline __complex__ float |
33ac58d5 | 874 | __complex_sinh(__complex__ float __z) { return __builtin_csinhf(__z); } |
a4ddde0d GDR |
875 | |
876 | inline __complex__ double | |
33ac58d5 | 877 | __complex_sinh(__complex__ double __z) { return __builtin_csinh(__z); } |
a4ddde0d GDR |
878 | |
879 | inline __complex__ long double | |
880 | __complex_sinh(const __complex__ long double& __z) | |
33ac58d5 | 881 | { return __builtin_csinhl(__z); } |
a4ddde0d GDR |
882 | |
883 | template<typename _Tp> | |
884 | inline complex<_Tp> | |
885 | sinh(const complex<_Tp>& __z) { return __complex_sinh(__z.__rep()); } | |
52e6723c BK |
886 | #else |
887 | template<typename _Tp> | |
888 | inline complex<_Tp> | |
889 | sinh(const complex<_Tp>& __z) { return __complex_sinh(__z); } | |
890 | #endif | |
a4ddde0d GDR |
891 | |
892 | // 26.2.8/13 sqrt(__z): Returns the complex square root of __z. | |
893 | // The branch cut is on the negative axis. | |
54c1bf78 BK |
894 | template<typename _Tp> |
895 | complex<_Tp> | |
a4ddde0d | 896 | __complex_sqrt(const complex<_Tp>& __z) |
54c1bf78 BK |
897 | { |
898 | _Tp __x = __z.real(); | |
899 | _Tp __y = __z.imag(); | |
900 | ||
901 | if (__x == _Tp()) | |
902 | { | |
a8784c4c | 903 | _Tp __t = sqrt(abs(__y) / 2); |
54c1bf78 BK |
904 | return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); |
905 | } | |
906 | else | |
907 | { | |
a8784c4c | 908 | _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); |
54c1bf78 BK |
909 | _Tp __u = __t / 2; |
910 | return __x > _Tp() | |
911 | ? complex<_Tp>(__u, __y / __t) | |
a8784c4c | 912 | : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); |
54c1bf78 BK |
913 | } |
914 | } | |
915 | ||
ab9b9d2c | 916 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
917 | inline __complex__ float |
918 | __complex_sqrt(__complex__ float __z) { return __builtin_csqrtf(__z); } | |
919 | ||
920 | inline __complex__ double | |
921 | __complex_sqrt(__complex__ double __z) { return __builtin_csqrt(__z); } | |
922 | ||
923 | inline __complex__ long double | |
924 | __complex_sqrt(const __complex__ long double& __z) | |
925 | { return __builtin_csqrtl(__z); } | |
926 | ||
54c1bf78 BK |
927 | template<typename _Tp> |
928 | inline complex<_Tp> | |
a4ddde0d | 929 | sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z.__rep()); } |
52e6723c BK |
930 | #else |
931 | template<typename _Tp> | |
932 | inline complex<_Tp> | |
933 | sqrt(const complex<_Tp>& __z) { return __complex_sqrt(__z); } | |
934 | #endif | |
54c1bf78 | 935 | |
a4ddde0d | 936 | // 26.2.8/14 tan(__z): Return the complex tangent of __z. |
33ac58d5 | 937 | |
54c1bf78 BK |
938 | template<typename _Tp> |
939 | inline complex<_Tp> | |
a4ddde0d GDR |
940 | __complex_tan(const complex<_Tp>& __z) |
941 | { return std::sin(__z) / std::cos(__z); } | |
942 | ||
ab9b9d2c | 943 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
944 | inline __complex__ float |
945 | __complex_tan(__complex__ float __z) { return __builtin_ctanf(__z); } | |
946 | ||
947 | inline __complex__ double | |
948 | __complex_tan(__complex__ double __z) { return __builtin_ctan(__z); } | |
949 | ||
950 | inline __complex__ long double | |
951 | __complex_tan(const __complex__ long double& __z) | |
952 | { return __builtin_ctanl(__z); } | |
953 | ||
954 | template<typename _Tp> | |
955 | inline complex<_Tp> | |
956 | tan(const complex<_Tp>& __z) { return __complex_tan(__z.__rep()); } | |
52e6723c BK |
957 | #else |
958 | template<typename _Tp> | |
959 | inline complex<_Tp> | |
960 | tan(const complex<_Tp>& __z) { return __complex_tan(__z); } | |
961 | #endif | |
962 | ||
a4ddde0d GDR |
963 | |
964 | // 26.2.8/15 tanh(__z): Returns the hyperbolic tangent of __z. | |
33ac58d5 | 965 | |
a4ddde0d GDR |
966 | template<typename _Tp> |
967 | inline complex<_Tp> | |
968 | __complex_tanh(const complex<_Tp>& __z) | |
969 | { return std::sinh(__z) / std::cosh(__z); } | |
970 | ||
ab9b9d2c | 971 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
972 | inline __complex__ float |
973 | __complex_tanh(__complex__ float __z) { return __builtin_ctanhf(__z); } | |
974 | ||
975 | inline __complex__ double | |
976 | __complex_tanh(__complex__ double __z) { return __builtin_ctanh(__z); } | |
977 | ||
978 | inline __complex__ long double | |
979 | __complex_tanh(const __complex__ long double& __z) | |
980 | { return __builtin_ctanhl(__z); } | |
54c1bf78 | 981 | |
a4ddde0d GDR |
982 | template<typename _Tp> |
983 | inline complex<_Tp> | |
984 | tanh(const complex<_Tp>& __z) { return __complex_tanh(__z.__rep()); } | |
52e6723c BK |
985 | #else |
986 | template<typename _Tp> | |
987 | inline complex<_Tp> | |
988 | tanh(const complex<_Tp>& __z) { return __complex_tanh(__z); } | |
989 | #endif | |
990 | ||
a4ddde0d GDR |
991 | |
992 | // 26.2.8/9 pow(__x, __y): Returns the complex power base of __x | |
993 | // raised to the __y-th power. The branch | |
994 | // cut is on the negative axis. | |
f3961bdf PC |
995 | template<typename _Tp> |
996 | complex<_Tp> | |
997 | __complex_pow_unsigned(complex<_Tp> __x, unsigned __n) | |
998 | { | |
999 | complex<_Tp> __y = __n % 2 ? __x : complex<_Tp>(1); | |
1000 | ||
1001 | while (__n >>= 1) | |
1002 | { | |
1003 | __x *= __x; | |
1004 | if (__n % 2) | |
1005 | __y *= __x; | |
1006 | } | |
1007 | ||
1008 | return __y; | |
1009 | } | |
1010 | ||
4e30cb71 | 1011 | // In C++11 mode we used to implement the resolution of |
3fd29fa9 | 1012 | // DR 844. complex pow return type is ambiguous. |
4e30cb71 PC |
1013 | // thus the following overload was disabled in that mode. However, doing |
1014 | // that causes all sorts of issues, see, for example: | |
1015 | // http://gcc.gnu.org/ml/libstdc++/2013-01/msg00058.html | |
1016 | // and also PR57974. | |
54c1bf78 BK |
1017 | template<typename _Tp> |
1018 | inline complex<_Tp> | |
1019 | pow(const complex<_Tp>& __z, int __n) | |
f3961bdf PC |
1020 | { |
1021 | return __n < 0 | |
91f4a9e3 | 1022 | ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n) |
f3961bdf PC |
1023 | : std::__complex_pow_unsigned(__z, __n); |
1024 | } | |
54c1bf78 BK |
1025 | |
1026 | template<typename _Tp> | |
1db0418a | 1027 | complex<_Tp> |
54c1bf78 BK |
1028 | pow(const complex<_Tp>& __x, const _Tp& __y) |
1029 | { | |
23c64853 | 1030 | #if ! _GLIBCXX_USE_C99_COMPLEX |
b0de8599 PC |
1031 | if (__x == _Tp()) |
1032 | return _Tp(); | |
1033 | #endif | |
52ddaf41 | 1034 | if (__x.imag() == _Tp() && __x.real() > _Tp()) |
a8784c4c | 1035 | return pow(__x.real(), __y); |
1db0418a | 1036 | |
c6feb697 | 1037 | complex<_Tp> __t = std::log(__x); |
742f66e7 | 1038 | return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag()); |
54c1bf78 BK |
1039 | } |
1040 | ||
a4ddde0d GDR |
1041 | template<typename _Tp> |
1042 | inline complex<_Tp> | |
1043 | __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) | |
1044 | { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } | |
1045 | ||
ab9b9d2c | 1046 | #if _GLIBCXX_USE_C99_COMPLEX |
a4ddde0d GDR |
1047 | inline __complex__ float |
1048 | __complex_pow(__complex__ float __x, __complex__ float __y) | |
1049 | { return __builtin_cpowf(__x, __y); } | |
1050 | ||
1051 | inline __complex__ double | |
1052 | __complex_pow(__complex__ double __x, __complex__ double __y) | |
1053 | { return __builtin_cpow(__x, __y); } | |
1054 | ||
1055 | inline __complex__ long double | |
cff001b2 PC |
1056 | __complex_pow(const __complex__ long double& __x, |
1057 | const __complex__ long double& __y) | |
a4ddde0d | 1058 | { return __builtin_cpowl(__x, __y); } |
52e6723c | 1059 | |
cff001b2 PC |
1060 | template<typename _Tp> |
1061 | inline complex<_Tp> | |
1062 | pow(const complex<_Tp>& __x, const complex<_Tp>& __y) | |
1063 | { return __complex_pow(__x.__rep(), __y.__rep()); } | |
1064 | #else | |
54c1bf78 BK |
1065 | template<typename _Tp> |
1066 | inline complex<_Tp> | |
1067 | pow(const complex<_Tp>& __x, const complex<_Tp>& __y) | |
a4ddde0d | 1068 | { return __complex_pow(__x, __y); } |
cff001b2 | 1069 | #endif |
54c1bf78 BK |
1070 | |
1071 | template<typename _Tp> | |
1072 | inline complex<_Tp> | |
1073 | pow(const _Tp& __x, const complex<_Tp>& __y) | |
1074 | { | |
742f66e7 MG |
1075 | return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()), |
1076 | __y.imag() * log(__x)) | |
2acceeac | 1077 | : std::pow(complex<_Tp>(__x), __y); |
54c1bf78 BK |
1078 | } |
1079 | ||
7897a1c0 BK |
1080 | /// 26.2.3 complex specializations |
1081 | /// complex<float> specialization | |
a4ddde0d | 1082 | template<> |
0e5abeb0 | 1083 | class complex<float> |
a4ddde0d | 1084 | { |
0e5abeb0 | 1085 | public: |
a4ddde0d GDR |
1086 | typedef float value_type; |
1087 | typedef __complex__ float _ComplexT; | |
1088 | ||
94a86be0 | 1089 | _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } |
a4ddde0d | 1090 | |
94a86be0 | 1091 | _GLIBCXX_CONSTEXPR complex(float __r = 0.0f, float __i = 0.0f) |
734f5023 | 1092 | #if __cplusplus >= 201103L |
9f1163b1 PC |
1093 | : _M_value{ __r, __i } { } |
1094 | #else | |
1095 | { | |
1096 | __real__ _M_value = __r; | |
1097 | __imag__ _M_value = __i; | |
1098 | } | |
1099 | #endif | |
02a65d23 | 1100 | |
94a86be0 | 1101 | explicit _GLIBCXX_CONSTEXPR complex(const complex<double>&); |
33ac58d5 | 1102 | explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); |
2acceeac | 1103 | |
734f5023 | 1104 | #if __cplusplus >= 201103L |
23ed71c6 PC |
1105 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1106 | // DR 387. std::complex over-encapsulated. | |
7a3a9e68 | 1107 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1108 | constexpr float |
9191d7a8 | 1109 | real() const { return __real__ _M_value; } |
23ed71c6 | 1110 | |
7a3a9e68 | 1111 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1112 | constexpr float |
9191d7a8 | 1113 | imag() const { return __imag__ _M_value; } |
23ed71c6 | 1114 | #else |
33ac58d5 | 1115 | float& |
94a86be0 | 1116 | real() { return __real__ _M_value; } |
2acceeac | 1117 | |
33ac58d5 JW |
1118 | const float& |
1119 | real() const { return __real__ _M_value; } | |
2acceeac | 1120 | |
33ac58d5 | 1121 | float& |
94a86be0 | 1122 | imag() { return __imag__ _M_value; } |
2acceeac | 1123 | |
33ac58d5 | 1124 | const float& |
94a86be0 | 1125 | imag() const { return __imag__ _M_value; } |
23ed71c6 PC |
1126 | #endif |
1127 | ||
1128 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1129 | // DR 387. std::complex over-encapsulated. | |
e987fb1e | 1130 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1131 | real(float __val) { __real__ _M_value = __val; } |
23ed71c6 | 1132 | |
e987fb1e | 1133 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1134 | imag(float __val) { __imag__ _M_value = __val; } |
2acceeac | 1135 | |
e987fb1e | 1136 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1137 | operator=(float __f) |
1138 | { | |
f941c3e2 | 1139 | _M_value = __f; |
2acceeac PC |
1140 | return *this; |
1141 | } | |
1142 | ||
e987fb1e | 1143 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1144 | operator+=(float __f) |
1145 | { | |
f941c3e2 | 1146 | _M_value += __f; |
2acceeac PC |
1147 | return *this; |
1148 | } | |
1149 | ||
e987fb1e | 1150 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1151 | operator-=(float __f) |
1152 | { | |
f941c3e2 | 1153 | _M_value -= __f; |
2acceeac PC |
1154 | return *this; |
1155 | } | |
1156 | ||
e987fb1e | 1157 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1158 | operator*=(float __f) |
1159 | { | |
1160 | _M_value *= __f; | |
1161 | return *this; | |
1162 | } | |
1163 | ||
e987fb1e | 1164 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1165 | operator/=(float __f) |
1166 | { | |
1167 | _M_value /= __f; | |
1168 | return *this; | |
1169 | } | |
a4ddde0d | 1170 | |
28dac70a | 1171 | // Let the compiler synthesize the copy and assignment |
a4ddde0d | 1172 | // operator. It always does a pretty good job. |
a1417556 JW |
1173 | #if __cplusplus >= 201103L |
1174 | _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; | |
1175 | #endif | |
2acceeac | 1176 | |
a4ddde0d | 1177 | template<typename _Tp> |
e987fb1e | 1178 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1179 | operator=(const complex<_Tp>& __z) |
1180 | { | |
1181 | __real__ _M_value = __z.real(); | |
1182 | __imag__ _M_value = __z.imag(); | |
1183 | return *this; | |
1184 | } | |
1185 | ||
a4ddde0d | 1186 | template<typename _Tp> |
e987fb1e | 1187 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1188 | operator+=(const complex<_Tp>& __z) |
1189 | { | |
e987fb1e | 1190 | _M_value += __z.__rep(); |
2acceeac PC |
1191 | return *this; |
1192 | } | |
1193 | ||
a4ddde0d | 1194 | template<class _Tp> |
e987fb1e | 1195 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1196 | operator-=(const complex<_Tp>& __z) |
1197 | { | |
e987fb1e | 1198 | _M_value -= __z.__rep(); |
2acceeac PC |
1199 | return *this; |
1200 | } | |
1201 | ||
a4ddde0d | 1202 | template<class _Tp> |
e987fb1e | 1203 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1204 | operator*=(const complex<_Tp>& __z) |
1205 | { | |
e987fb1e | 1206 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1207 | _M_value *= __t; |
1208 | return *this; | |
1209 | } | |
1210 | ||
a4ddde0d | 1211 | template<class _Tp> |
e987fb1e | 1212 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1213 | operator/=(const complex<_Tp>& __z) |
1214 | { | |
e987fb1e | 1215 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1216 | _M_value /= __t; |
1217 | return *this; | |
1218 | } | |
a4ddde0d | 1219 | |
3fa591d4 | 1220 | _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } |
a4ddde0d GDR |
1221 | |
1222 | private: | |
1223 | _ComplexT _M_value; | |
1224 | }; | |
54c1bf78 | 1225 | |
7897a1c0 BK |
1226 | /// 26.2.3 complex specializations |
1227 | /// complex<double> specialization | |
a4ddde0d | 1228 | template<> |
0e5abeb0 | 1229 | class complex<double> |
a4ddde0d | 1230 | { |
0e5abeb0 | 1231 | public: |
a4ddde0d GDR |
1232 | typedef double value_type; |
1233 | typedef __complex__ double _ComplexT; | |
1234 | ||
94a86be0 | 1235 | _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } |
54c1bf78 | 1236 | |
94a86be0 | 1237 | _GLIBCXX_CONSTEXPR complex(double __r = 0.0, double __i = 0.0) |
734f5023 | 1238 | #if __cplusplus >= 201103L |
9f1163b1 PC |
1239 | : _M_value{ __r, __i } { } |
1240 | #else | |
1241 | { | |
1242 | __real__ _M_value = __r; | |
1243 | __imag__ _M_value = __i; | |
1244 | } | |
1245 | #endif | |
2acceeac | 1246 | |
94a86be0 | 1247 | _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) |
2acceeac PC |
1248 | : _M_value(__z.__rep()) { } |
1249 | ||
33ac58d5 | 1250 | explicit _GLIBCXX_CONSTEXPR complex(const complex<long double>&); |
2acceeac | 1251 | |
734f5023 | 1252 | #if __cplusplus >= 201103L |
23ed71c6 PC |
1253 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1254 | // DR 387. std::complex over-encapsulated. | |
7a3a9e68 | 1255 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1256 | constexpr double |
9191d7a8 | 1257 | real() const { return __real__ _M_value; } |
23ed71c6 | 1258 | |
7a3a9e68 | 1259 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1260 | constexpr double |
9191d7a8 | 1261 | imag() const { return __imag__ _M_value; } |
23ed71c6 | 1262 | #else |
33ac58d5 | 1263 | double& |
94a86be0 | 1264 | real() { return __real__ _M_value; } |
2acceeac | 1265 | |
33ac58d5 | 1266 | const double& |
94a86be0 | 1267 | real() const { return __real__ _M_value; } |
2acceeac | 1268 | |
33ac58d5 | 1269 | double& |
94a86be0 | 1270 | imag() { return __imag__ _M_value; } |
2acceeac | 1271 | |
33ac58d5 | 1272 | const double& |
94a86be0 | 1273 | imag() const { return __imag__ _M_value; } |
23ed71c6 PC |
1274 | #endif |
1275 | ||
1276 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1277 | // DR 387. std::complex over-encapsulated. | |
e987fb1e | 1278 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1279 | real(double __val) { __real__ _M_value = __val; } |
23ed71c6 | 1280 | |
e987fb1e | 1281 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1282 | imag(double __val) { __imag__ _M_value = __val; } |
2acceeac | 1283 | |
e987fb1e | 1284 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1285 | operator=(double __d) |
1286 | { | |
f941c3e2 | 1287 | _M_value = __d; |
2acceeac PC |
1288 | return *this; |
1289 | } | |
1290 | ||
e987fb1e | 1291 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1292 | operator+=(double __d) |
1293 | { | |
f941c3e2 | 1294 | _M_value += __d; |
2acceeac PC |
1295 | return *this; |
1296 | } | |
33ac58d5 | 1297 | |
e987fb1e | 1298 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1299 | operator-=(double __d) |
1300 | { | |
f941c3e2 | 1301 | _M_value -= __d; |
2acceeac PC |
1302 | return *this; |
1303 | } | |
1304 | ||
e987fb1e | 1305 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1306 | operator*=(double __d) |
1307 | { | |
1308 | _M_value *= __d; | |
1309 | return *this; | |
1310 | } | |
1311 | ||
e987fb1e | 1312 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1313 | operator/=(double __d) |
1314 | { | |
1315 | _M_value /= __d; | |
1316 | return *this; | |
1317 | } | |
a4ddde0d | 1318 | |
28dac70a | 1319 | // The compiler will synthesize this, efficiently. |
a1417556 JW |
1320 | #if __cplusplus >= 201103L |
1321 | _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; | |
1322 | #endif | |
2acceeac | 1323 | |
a4ddde0d | 1324 | template<typename _Tp> |
e987fb1e | 1325 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1326 | operator=(const complex<_Tp>& __z) |
1327 | { | |
e987fb1e | 1328 | _M_value = __z.__rep(); |
2acceeac PC |
1329 | return *this; |
1330 | } | |
1331 | ||
a4ddde0d | 1332 | template<typename _Tp> |
e987fb1e | 1333 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1334 | operator+=(const complex<_Tp>& __z) |
1335 | { | |
e987fb1e | 1336 | _M_value += __z.__rep(); |
2acceeac PC |
1337 | return *this; |
1338 | } | |
1339 | ||
a4ddde0d | 1340 | template<typename _Tp> |
e987fb1e | 1341 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1342 | operator-=(const complex<_Tp>& __z) |
1343 | { | |
e987fb1e | 1344 | _M_value -= __z.__rep(); |
2acceeac PC |
1345 | return *this; |
1346 | } | |
1347 | ||
a4ddde0d | 1348 | template<typename _Tp> |
e987fb1e | 1349 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1350 | operator*=(const complex<_Tp>& __z) |
1351 | { | |
e987fb1e | 1352 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1353 | _M_value *= __t; |
1354 | return *this; | |
1355 | } | |
1356 | ||
a4ddde0d | 1357 | template<typename _Tp> |
e987fb1e | 1358 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1359 | operator/=(const complex<_Tp>& __z) |
1360 | { | |
e987fb1e | 1361 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1362 | _M_value /= __t; |
1363 | return *this; | |
1364 | } | |
3b3bfc0e | 1365 | |
3fa591d4 | 1366 | _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } |
a4ddde0d GDR |
1367 | |
1368 | private: | |
1369 | _ComplexT _M_value; | |
1370 | }; | |
54c1bf78 | 1371 | |
7897a1c0 BK |
1372 | /// 26.2.3 complex specializations |
1373 | /// complex<long double> specialization | |
a4ddde0d | 1374 | template<> |
0e5abeb0 | 1375 | class complex<long double> |
a4ddde0d | 1376 | { |
0e5abeb0 | 1377 | public: |
a4ddde0d GDR |
1378 | typedef long double value_type; |
1379 | typedef __complex__ long double _ComplexT; | |
54c1bf78 | 1380 | |
94a86be0 | 1381 | _GLIBCXX_CONSTEXPR complex(_ComplexT __z) : _M_value(__z) { } |
a4ddde0d | 1382 | |
33ac58d5 | 1383 | _GLIBCXX_CONSTEXPR complex(long double __r = 0.0L, |
94a86be0 | 1384 | long double __i = 0.0L) |
734f5023 | 1385 | #if __cplusplus >= 201103L |
9f1163b1 PC |
1386 | : _M_value{ __r, __i } { } |
1387 | #else | |
1388 | { | |
1389 | __real__ _M_value = __r; | |
1390 | __imag__ _M_value = __i; | |
1391 | } | |
1392 | #endif | |
2acceeac | 1393 | |
94a86be0 | 1394 | _GLIBCXX_CONSTEXPR complex(const complex<float>& __z) |
2acceeac PC |
1395 | : _M_value(__z.__rep()) { } |
1396 | ||
94a86be0 | 1397 | _GLIBCXX_CONSTEXPR complex(const complex<double>& __z) |
2acceeac PC |
1398 | : _M_value(__z.__rep()) { } |
1399 | ||
734f5023 | 1400 | #if __cplusplus >= 201103L |
23ed71c6 PC |
1401 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1402 | // DR 387. std::complex over-encapsulated. | |
7a3a9e68 | 1403 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1404 | constexpr long double |
9191d7a8 | 1405 | real() const { return __real__ _M_value; } |
23ed71c6 | 1406 | |
7a3a9e68 | 1407 | __attribute ((__abi_tag__ ("cxx11"))) |
33ac58d5 | 1408 | constexpr long double |
9191d7a8 | 1409 | imag() const { return __imag__ _M_value; } |
23ed71c6 | 1410 | #else |
33ac58d5 | 1411 | long double& |
94a86be0 | 1412 | real() { return __real__ _M_value; } |
2acceeac | 1413 | |
33ac58d5 | 1414 | const long double& |
94a86be0 | 1415 | real() const { return __real__ _M_value; } |
2acceeac | 1416 | |
33ac58d5 | 1417 | long double& |
94a86be0 | 1418 | imag() { return __imag__ _M_value; } |
2acceeac | 1419 | |
33ac58d5 | 1420 | const long double& |
94a86be0 | 1421 | imag() const { return __imag__ _M_value; } |
23ed71c6 PC |
1422 | #endif |
1423 | ||
1424 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1425 | // DR 387. std::complex over-encapsulated. | |
e987fb1e | 1426 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1427 | real(long double __val) { __real__ _M_value = __val; } |
23ed71c6 | 1428 | |
e987fb1e | 1429 | _GLIBCXX20_CONSTEXPR void |
94a86be0 | 1430 | imag(long double __val) { __imag__ _M_value = __val; } |
2acceeac | 1431 | |
e987fb1e | 1432 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1433 | operator=(long double __r) |
1434 | { | |
f941c3e2 | 1435 | _M_value = __r; |
2acceeac PC |
1436 | return *this; |
1437 | } | |
1438 | ||
e987fb1e | 1439 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1440 | operator+=(long double __r) |
1441 | { | |
f941c3e2 | 1442 | _M_value += __r; |
2acceeac PC |
1443 | return *this; |
1444 | } | |
1445 | ||
e987fb1e | 1446 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1447 | operator-=(long double __r) |
1448 | { | |
f941c3e2 | 1449 | _M_value -= __r; |
2acceeac PC |
1450 | return *this; |
1451 | } | |
1452 | ||
e987fb1e | 1453 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1454 | operator*=(long double __r) |
1455 | { | |
1456 | _M_value *= __r; | |
1457 | return *this; | |
1458 | } | |
1459 | ||
e987fb1e | 1460 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1461 | operator/=(long double __r) |
1462 | { | |
1463 | _M_value /= __r; | |
1464 | return *this; | |
1465 | } | |
a4ddde0d GDR |
1466 | |
1467 | // The compiler knows how to do this efficiently | |
a1417556 JW |
1468 | #if __cplusplus >= 201103L |
1469 | _GLIBCXX14_CONSTEXPR complex& operator=(const complex&) = default; | |
1470 | #endif | |
2acceeac | 1471 | |
a4ddde0d | 1472 | template<typename _Tp> |
e987fb1e | 1473 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1474 | operator=(const complex<_Tp>& __z) |
1475 | { | |
e987fb1e | 1476 | _M_value = __z.__rep(); |
2acceeac PC |
1477 | return *this; |
1478 | } | |
1479 | ||
a4ddde0d | 1480 | template<typename _Tp> |
e987fb1e | 1481 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1482 | operator+=(const complex<_Tp>& __z) |
1483 | { | |
e987fb1e | 1484 | _M_value += __z.__rep(); |
2acceeac PC |
1485 | return *this; |
1486 | } | |
1487 | ||
a4ddde0d | 1488 | template<typename _Tp> |
e987fb1e | 1489 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1490 | operator-=(const complex<_Tp>& __z) |
1491 | { | |
e987fb1e | 1492 | _M_value -= __z.__rep(); |
2acceeac PC |
1493 | return *this; |
1494 | } | |
1495 | ||
a4ddde0d | 1496 | template<typename _Tp> |
e987fb1e | 1497 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1498 | operator*=(const complex<_Tp>& __z) |
1499 | { | |
e987fb1e | 1500 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1501 | _M_value *= __t; |
1502 | return *this; | |
1503 | } | |
1504 | ||
a4ddde0d | 1505 | template<typename _Tp> |
e987fb1e | 1506 | _GLIBCXX20_CONSTEXPR complex& |
2acceeac PC |
1507 | operator/=(const complex<_Tp>& __z) |
1508 | { | |
e987fb1e | 1509 | const _ComplexT __t = __z.__rep(); |
2acceeac PC |
1510 | _M_value /= __t; |
1511 | return *this; | |
1512 | } | |
a4ddde0d | 1513 | |
3fa591d4 | 1514 | _GLIBCXX_CONSTEXPR _ComplexT __rep() const { return _M_value; } |
a4ddde0d GDR |
1515 | |
1516 | private: | |
1517 | _ComplexT _M_value; | |
1518 | }; | |
54c1bf78 | 1519 | |
54c1bf78 BK |
1520 | // These bits have to be at the end of this file, so that the |
1521 | // specializations have all been defined. | |
94a86be0 | 1522 | inline _GLIBCXX_CONSTEXPR |
54c1bf78 | 1523 | complex<float>::complex(const complex<double>& __z) |
a4ddde0d | 1524 | : _M_value(__z.__rep()) { } |
54c1bf78 | 1525 | |
94a86be0 | 1526 | inline _GLIBCXX_CONSTEXPR |
54c1bf78 | 1527 | complex<float>::complex(const complex<long double>& __z) |
a4ddde0d | 1528 | : _M_value(__z.__rep()) { } |
54c1bf78 | 1529 | |
94a86be0 | 1530 | inline _GLIBCXX_CONSTEXPR |
54c1bf78 | 1531 | complex<double>::complex(const complex<long double>& __z) |
d0cbf089 | 1532 | : _M_value(__z.__rep()) { } |
54c1bf78 | 1533 | |
74b332b8 PC |
1534 | // Inhibit implicit instantiations for required instantiations, |
1535 | // which are defined via explicit instantiations elsewhere. | |
1536 | // NB: This syntax is a GNU extension. | |
1537 | #if _GLIBCXX_EXTERN_TEMPLATE | |
1538 | extern template istream& operator>>(istream&, complex<float>&); | |
1539 | extern template ostream& operator<<(ostream&, const complex<float>&); | |
1540 | extern template istream& operator>>(istream&, complex<double>&); | |
1541 | extern template ostream& operator<<(ostream&, const complex<double>&); | |
1542 | extern template istream& operator>>(istream&, complex<long double>&); | |
1543 | extern template ostream& operator<<(ostream&, const complex<long double>&); | |
1544 | ||
1545 | #ifdef _GLIBCXX_USE_WCHAR_T | |
1546 | extern template wistream& operator>>(wistream&, complex<float>&); | |
1547 | extern template wostream& operator<<(wostream&, const complex<float>&); | |
1548 | extern template wistream& operator>>(wistream&, complex<double>&); | |
1549 | extern template wostream& operator<<(wostream&, const complex<double>&); | |
1550 | extern template wistream& operator>>(wistream&, complex<long double>&); | |
1551 | extern template wostream& operator<<(wostream&, const complex<long double>&); | |
1552 | #endif | |
1553 | #endif | |
1554 | ||
f0b88346 | 1555 | /// @} group complex_numbers |
5b9daa7e | 1556 | |
12ffa228 BK |
1557 | _GLIBCXX_END_NAMESPACE_VERSION |
1558 | } // namespace | |
54c1bf78 | 1559 | |
734f5023 | 1560 | #if __cplusplus >= 201103L |
3cd54fc9 | 1561 | |
12ffa228 BK |
1562 | namespace std _GLIBCXX_VISIBILITY(default) |
1563 | { | |
1564 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cd54fc9 | 1565 | |
53dc5044 PC |
1566 | // Forward declarations. |
1567 | template<typename _Tp> std::complex<_Tp> acos(const std::complex<_Tp>&); | |
1568 | template<typename _Tp> std::complex<_Tp> asin(const std::complex<_Tp>&); | |
1569 | template<typename _Tp> std::complex<_Tp> atan(const std::complex<_Tp>&); | |
1570 | ||
1571 | template<typename _Tp> std::complex<_Tp> acosh(const std::complex<_Tp>&); | |
1572 | template<typename _Tp> std::complex<_Tp> asinh(const std::complex<_Tp>&); | |
1573 | template<typename _Tp> std::complex<_Tp> atanh(const std::complex<_Tp>&); | |
1574 | // DR 595. | |
1575 | template<typename _Tp> _Tp fabs(const std::complex<_Tp>&); | |
1576 | ||
1577 | template<typename _Tp> | |
1578 | inline std::complex<_Tp> | |
1579 | __complex_acos(const std::complex<_Tp>& __z) | |
1580 | { | |
1581 | const std::complex<_Tp> __t = std::asin(__z); | |
1582 | const _Tp __pi_2 = 1.5707963267948966192313216916397514L; | |
1583 | return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag()); | |
1584 | } | |
1585 | ||
1586 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1587 | inline __complex__ float | |
1588 | __complex_acos(__complex__ float __z) | |
1589 | { return __builtin_cacosf(__z); } | |
1590 | ||
1591 | inline __complex__ double | |
1592 | __complex_acos(__complex__ double __z) | |
1593 | { return __builtin_cacos(__z); } | |
1594 | ||
1595 | inline __complex__ long double | |
1596 | __complex_acos(const __complex__ long double& __z) | |
1597 | { return __builtin_cacosl(__z); } | |
1598 | ||
1599 | template<typename _Tp> | |
1600 | inline std::complex<_Tp> | |
1601 | acos(const std::complex<_Tp>& __z) | |
1602 | { return __complex_acos(__z.__rep()); } | |
1603 | #else | |
1604 | /// acos(__z) [8.1.2]. | |
1605 | // Effects: Behaves the same as C99 function cacos, defined | |
1606 | // in subclause 7.3.5.1. | |
1607 | template<typename _Tp> | |
1608 | inline std::complex<_Tp> | |
1609 | acos(const std::complex<_Tp>& __z) | |
1610 | { return __complex_acos(__z); } | |
1611 | #endif | |
1612 | ||
1613 | template<typename _Tp> | |
1614 | inline std::complex<_Tp> | |
1615 | __complex_asin(const std::complex<_Tp>& __z) | |
1616 | { | |
1617 | std::complex<_Tp> __t(-__z.imag(), __z.real()); | |
1618 | __t = std::asinh(__t); | |
1619 | return std::complex<_Tp>(__t.imag(), -__t.real()); | |
1620 | } | |
1621 | ||
1622 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1623 | inline __complex__ float | |
1624 | __complex_asin(__complex__ float __z) | |
1625 | { return __builtin_casinf(__z); } | |
1626 | ||
1627 | inline __complex__ double | |
1628 | __complex_asin(__complex__ double __z) | |
1629 | { return __builtin_casin(__z); } | |
1630 | ||
1631 | inline __complex__ long double | |
1632 | __complex_asin(const __complex__ long double& __z) | |
1633 | { return __builtin_casinl(__z); } | |
1634 | ||
1635 | template<typename _Tp> | |
1636 | inline std::complex<_Tp> | |
1637 | asin(const std::complex<_Tp>& __z) | |
1638 | { return __complex_asin(__z.__rep()); } | |
1639 | #else | |
1640 | /// asin(__z) [8.1.3]. | |
1641 | // Effects: Behaves the same as C99 function casin, defined | |
1642 | // in subclause 7.3.5.2. | |
1643 | template<typename _Tp> | |
1644 | inline std::complex<_Tp> | |
1645 | asin(const std::complex<_Tp>& __z) | |
1646 | { return __complex_asin(__z); } | |
1647 | #endif | |
33ac58d5 | 1648 | |
53dc5044 PC |
1649 | template<typename _Tp> |
1650 | std::complex<_Tp> | |
1651 | __complex_atan(const std::complex<_Tp>& __z) | |
1652 | { | |
1653 | const _Tp __r2 = __z.real() * __z.real(); | |
1654 | const _Tp __x = _Tp(1.0) - __r2 - __z.imag() * __z.imag(); | |
1655 | ||
1656 | _Tp __num = __z.imag() + _Tp(1.0); | |
1657 | _Tp __den = __z.imag() - _Tp(1.0); | |
1658 | ||
1659 | __num = __r2 + __num * __num; | |
1660 | __den = __r2 + __den * __den; | |
1661 | ||
1662 | return std::complex<_Tp>(_Tp(0.5) * atan2(_Tp(2.0) * __z.real(), __x), | |
1663 | _Tp(0.25) * log(__num / __den)); | |
1664 | } | |
1665 | ||
1666 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1667 | inline __complex__ float | |
1668 | __complex_atan(__complex__ float __z) | |
1669 | { return __builtin_catanf(__z); } | |
1670 | ||
1671 | inline __complex__ double | |
1672 | __complex_atan(__complex__ double __z) | |
1673 | { return __builtin_catan(__z); } | |
1674 | ||
1675 | inline __complex__ long double | |
1676 | __complex_atan(const __complex__ long double& __z) | |
1677 | { return __builtin_catanl(__z); } | |
1678 | ||
1679 | template<typename _Tp> | |
1680 | inline std::complex<_Tp> | |
1681 | atan(const std::complex<_Tp>& __z) | |
1682 | { return __complex_atan(__z.__rep()); } | |
1683 | #else | |
1684 | /// atan(__z) [8.1.4]. | |
1685 | // Effects: Behaves the same as C99 function catan, defined | |
1686 | // in subclause 7.3.5.3. | |
1687 | template<typename _Tp> | |
1688 | inline std::complex<_Tp> | |
1689 | atan(const std::complex<_Tp>& __z) | |
1690 | { return __complex_atan(__z); } | |
1691 | #endif | |
1692 | ||
1693 | template<typename _Tp> | |
1694 | std::complex<_Tp> | |
1695 | __complex_acosh(const std::complex<_Tp>& __z) | |
1696 | { | |
af7c1858 RK |
1697 | // Kahan's formula. |
1698 | return _Tp(2.0) * std::log(std::sqrt(_Tp(0.5) * (__z + _Tp(1.0))) | |
1699 | + std::sqrt(_Tp(0.5) * (__z - _Tp(1.0)))); | |
53dc5044 PC |
1700 | } |
1701 | ||
1702 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1703 | inline __complex__ float | |
1704 | __complex_acosh(__complex__ float __z) | |
1705 | { return __builtin_cacoshf(__z); } | |
1706 | ||
1707 | inline __complex__ double | |
1708 | __complex_acosh(__complex__ double __z) | |
1709 | { return __builtin_cacosh(__z); } | |
1710 | ||
1711 | inline __complex__ long double | |
1712 | __complex_acosh(const __complex__ long double& __z) | |
1713 | { return __builtin_cacoshl(__z); } | |
1714 | ||
1715 | template<typename _Tp> | |
1716 | inline std::complex<_Tp> | |
1717 | acosh(const std::complex<_Tp>& __z) | |
1718 | { return __complex_acosh(__z.__rep()); } | |
1719 | #else | |
1720 | /// acosh(__z) [8.1.5]. | |
1721 | // Effects: Behaves the same as C99 function cacosh, defined | |
1722 | // in subclause 7.3.6.1. | |
1723 | template<typename _Tp> | |
1724 | inline std::complex<_Tp> | |
1725 | acosh(const std::complex<_Tp>& __z) | |
1726 | { return __complex_acosh(__z); } | |
1727 | #endif | |
1728 | ||
1729 | template<typename _Tp> | |
1730 | std::complex<_Tp> | |
1731 | __complex_asinh(const std::complex<_Tp>& __z) | |
1732 | { | |
1733 | std::complex<_Tp> __t((__z.real() - __z.imag()) | |
1734 | * (__z.real() + __z.imag()) + _Tp(1.0), | |
1735 | _Tp(2.0) * __z.real() * __z.imag()); | |
1736 | __t = std::sqrt(__t); | |
1737 | ||
1738 | return std::log(__t + __z); | |
1739 | } | |
1740 | ||
1741 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1742 | inline __complex__ float | |
1743 | __complex_asinh(__complex__ float __z) | |
1744 | { return __builtin_casinhf(__z); } | |
1745 | ||
1746 | inline __complex__ double | |
1747 | __complex_asinh(__complex__ double __z) | |
1748 | { return __builtin_casinh(__z); } | |
1749 | ||
1750 | inline __complex__ long double | |
1751 | __complex_asinh(const __complex__ long double& __z) | |
1752 | { return __builtin_casinhl(__z); } | |
1753 | ||
1754 | template<typename _Tp> | |
1755 | inline std::complex<_Tp> | |
1756 | asinh(const std::complex<_Tp>& __z) | |
1757 | { return __complex_asinh(__z.__rep()); } | |
1758 | #else | |
1759 | /// asinh(__z) [8.1.6]. | |
1760 | // Effects: Behaves the same as C99 function casin, defined | |
1761 | // in subclause 7.3.6.2. | |
1762 | template<typename _Tp> | |
1763 | inline std::complex<_Tp> | |
1764 | asinh(const std::complex<_Tp>& __z) | |
1765 | { return __complex_asinh(__z); } | |
1766 | #endif | |
1767 | ||
1768 | template<typename _Tp> | |
1769 | std::complex<_Tp> | |
1770 | __complex_atanh(const std::complex<_Tp>& __z) | |
1771 | { | |
1772 | const _Tp __i2 = __z.imag() * __z.imag(); | |
1773 | const _Tp __x = _Tp(1.0) - __i2 - __z.real() * __z.real(); | |
1774 | ||
1775 | _Tp __num = _Tp(1.0) + __z.real(); | |
1776 | _Tp __den = _Tp(1.0) - __z.real(); | |
1777 | ||
1778 | __num = __i2 + __num * __num; | |
1779 | __den = __i2 + __den * __den; | |
1780 | ||
1781 | return std::complex<_Tp>(_Tp(0.25) * (log(__num) - log(__den)), | |
1782 | _Tp(0.5) * atan2(_Tp(2.0) * __z.imag(), __x)); | |
1783 | } | |
1784 | ||
1785 | #if _GLIBCXX_USE_C99_COMPLEX_TR1 | |
1786 | inline __complex__ float | |
1787 | __complex_atanh(__complex__ float __z) | |
1788 | { return __builtin_catanhf(__z); } | |
1789 | ||
1790 | inline __complex__ double | |
1791 | __complex_atanh(__complex__ double __z) | |
1792 | { return __builtin_catanh(__z); } | |
1793 | ||
1794 | inline __complex__ long double | |
1795 | __complex_atanh(const __complex__ long double& __z) | |
1796 | { return __builtin_catanhl(__z); } | |
1797 | ||
1798 | template<typename _Tp> | |
1799 | inline std::complex<_Tp> | |
1800 | atanh(const std::complex<_Tp>& __z) | |
1801 | { return __complex_atanh(__z.__rep()); } | |
1802 | #else | |
1803 | /// atanh(__z) [8.1.7]. | |
1804 | // Effects: Behaves the same as C99 function catanh, defined | |
1805 | // in subclause 7.3.6.3. | |
1806 | template<typename _Tp> | |
1807 | inline std::complex<_Tp> | |
1808 | atanh(const std::complex<_Tp>& __z) | |
1809 | { return __complex_atanh(__z); } | |
1810 | #endif | |
1811 | ||
1812 | template<typename _Tp> | |
1813 | inline _Tp | |
1814 | /// fabs(__z) [8.1.8]. | |
1815 | // Effects: Behaves the same as C99 function cabs, defined | |
1816 | // in subclause 7.3.8.1. | |
1817 | fabs(const std::complex<_Tp>& __z) | |
1818 | { return std::abs(__z); } | |
1819 | ||
1820 | /// Additional overloads [8.1.9]. | |
1821 | template<typename _Tp> | |
1822 | inline typename __gnu_cxx::__promote<_Tp>::__type | |
1823 | arg(_Tp __x) | |
1824 | { | |
1825 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
23c64853 | 1826 | #if (_GLIBCXX11_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) |
53dc5044 PC |
1827 | return std::signbit(__x) ? __type(3.1415926535897932384626433832795029L) |
1828 | : __type(); | |
1829 | #else | |
1830 | return std::arg(std::complex<__type>(__x)); | |
1831 | #endif | |
1832 | } | |
1833 | ||
1834 | template<typename _Tp> | |
536c221d | 1835 | _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type |
53dc5044 PC |
1836 | imag(_Tp) |
1837 | { return _Tp(); } | |
1838 | ||
1839 | template<typename _Tp> | |
e987fb1e | 1840 | _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type |
53dc5044 PC |
1841 | norm(_Tp __x) |
1842 | { | |
1843 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
1844 | return __type(__x) * __type(__x); | |
1845 | } | |
1846 | ||
1847 | template<typename _Tp> | |
536c221d | 1848 | _GLIBCXX_CONSTEXPR inline typename __gnu_cxx::__promote<_Tp>::__type |
53dc5044 PC |
1849 | real(_Tp __x) |
1850 | { return __x; } | |
1851 | ||
1852 | template<typename _Tp, typename _Up> | |
1853 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
1854 | pow(const std::complex<_Tp>& __x, const _Up& __y) | |
1855 | { | |
1856 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
1857 | return std::pow(std::complex<__type>(__x), __type(__y)); | |
1858 | } | |
1859 | ||
1860 | template<typename _Tp, typename _Up> | |
1861 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
1862 | pow(const _Tp& __x, const std::complex<_Up>& __y) | |
1863 | { | |
1864 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
1865 | return std::pow(__type(__x), std::complex<__type>(__y)); | |
1866 | } | |
1867 | ||
1868 | template<typename _Tp, typename _Up> | |
1869 | inline std::complex<typename __gnu_cxx::__promote_2<_Tp, _Up>::__type> | |
1870 | pow(const std::complex<_Tp>& __x, const std::complex<_Up>& __y) | |
1871 | { | |
1872 | typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; | |
1873 | return std::pow(std::complex<__type>(__x), | |
1874 | std::complex<__type>(__y)); | |
1875 | } | |
1876 | ||
3cd54fc9 PC |
1877 | // Forward declarations. |
1878 | // DR 781. | |
e987fb1e ESR |
1879 | template<typename _Tp> |
1880 | std::complex<_Tp> proj(const std::complex<_Tp>&); | |
3cd54fc9 | 1881 | |
4f75543d | 1882 | // Generic implementation of std::proj, does not work for infinities. |
3cd54fc9 | 1883 | template<typename _Tp> |
4f75543d | 1884 | inline std::complex<_Tp> |
3cd54fc9 | 1885 | __complex_proj(const std::complex<_Tp>& __z) |
4f75543d | 1886 | { return __z; } |
3cd54fc9 PC |
1887 | |
1888 | #if _GLIBCXX_USE_C99_COMPLEX | |
4f75543d JW |
1889 | inline complex<float> |
1890 | __complex_proj(const complex<float>& __z) | |
1891 | { return __builtin_cprojf(__z.__rep()); } | |
1892 | ||
1893 | inline complex<double> | |
1894 | __complex_proj(const complex<double>& __z) | |
1895 | { return __builtin_cproj(__z.__rep()); } | |
1896 | ||
1897 | inline complex<long double> | |
1898 | __complex_proj(const complex<long double>& __z) | |
1899 | { return __builtin_cprojl(__z.__rep()); } | |
1900 | #elif defined _GLIBCXX_USE_C99_MATH_TR1 | |
1901 | inline complex<float> | |
1902 | __complex_proj(const complex<float>& __z) | |
1903 | { | |
1904 | if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) | |
1905 | return complex<float>(__builtin_inff(), | |
1906 | __builtin_copysignf(0.0f, __z.imag())); | |
1907 | return __z; | |
1908 | } | |
1909 | ||
1910 | inline complex<double> | |
1911 | __complex_proj(const complex<double>& __z) | |
1912 | { | |
1913 | if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) | |
1914 | return complex<double>(__builtin_inf(), | |
1915 | __builtin_copysign(0.0, __z.imag())); | |
1916 | return __z; | |
1917 | } | |
1918 | ||
1919 | inline complex<long double> | |
1920 | __complex_proj(const complex<long double>& __z) | |
1921 | { | |
1922 | if (__builtin_isinf(__z.real()) || __builtin_isinf(__z.imag())) | |
1923 | return complex<long double>(__builtin_infl(), | |
1924 | __builtin_copysignl(0.0l, __z.imag())); | |
1925 | return __z; | |
1926 | } | |
1927 | #endif | |
3cd54fc9 | 1928 | |
3cd54fc9 | 1929 | template<typename _Tp> |
eda0ab6e | 1930 | inline std::complex<_Tp> |
3cd54fc9 PC |
1931 | proj(const std::complex<_Tp>& __z) |
1932 | { return __complex_proj(__z); } | |
3cd54fc9 | 1933 | |
4f75543d | 1934 | // Overload for scalars |
3cd54fc9 | 1935 | template<typename _Tp> |
536c221d | 1936 | inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type> |
3cd54fc9 | 1937 | proj(_Tp __x) |
536c221d JW |
1938 | { |
1939 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
1940 | return std::proj(std::complex<__type>(__x)); | |
1941 | } | |
681f05d4 PC |
1942 | |
1943 | template<typename _Tp> | |
e987fb1e ESR |
1944 | inline _GLIBCXX20_CONSTEXPR |
1945 | std::complex<typename __gnu_cxx::__promote<_Tp>::__type> | |
681f05d4 | 1946 | conj(_Tp __x) |
536c221d JW |
1947 | { |
1948 | typedef typename __gnu_cxx::__promote<_Tp>::__type __type; | |
1949 | return std::complex<__type>(__x, -__type()); | |
1950 | } | |
3cd54fc9 | 1951 | |
ae5543e6 ESR |
1952 | #if __cplusplus > 201103L |
1953 | ||
1954 | inline namespace literals { | |
1955 | inline namespace complex_literals { | |
f03858e5 JW |
1956 | #pragma GCC diagnostic push |
1957 | #pragma GCC diagnostic ignored "-Wliteral-suffix" | |
a15f7cb8 ESR |
1958 | #define __cpp_lib_complex_udls 201309 |
1959 | ||
ae5543e6 ESR |
1960 | constexpr std::complex<float> |
1961 | operator""if(long double __num) | |
1962 | { return std::complex<float>{0.0F, static_cast<float>(__num)}; } | |
1963 | ||
1964 | constexpr std::complex<float> | |
1965 | operator""if(unsigned long long __num) | |
1966 | { return std::complex<float>{0.0F, static_cast<float>(__num)}; } | |
1967 | ||
1968 | constexpr std::complex<double> | |
1969 | operator""i(long double __num) | |
1970 | { return std::complex<double>{0.0, static_cast<double>(__num)}; } | |
1971 | ||
1972 | constexpr std::complex<double> | |
1973 | operator""i(unsigned long long __num) | |
1974 | { return std::complex<double>{0.0, static_cast<double>(__num)}; } | |
1975 | ||
1976 | constexpr std::complex<long double> | |
1977 | operator""il(long double __num) | |
1978 | { return std::complex<long double>{0.0L, __num}; } | |
1979 | ||
1980 | constexpr std::complex<long double> | |
1981 | operator""il(unsigned long long __num) | |
1982 | { return std::complex<long double>{0.0L, static_cast<long double>(__num)}; } | |
1983 | ||
f03858e5 | 1984 | #pragma GCC diagnostic pop |
ae5543e6 ESR |
1985 | } // inline namespace complex_literals |
1986 | } // inline namespace literals | |
1987 | ||
1988 | #endif // C++14 | |
1989 | ||
4a15d842 | 1990 | _GLIBCXX_END_NAMESPACE_VERSION |
12ffa228 | 1991 | } // namespace |
3cd54fc9 | 1992 | |
734f5023 | 1993 | #endif // C++11 |
af13a7a6 | 1994 | |
53dc5044 | 1995 | #endif /* _GLIBCXX_COMPLEX */ |