1 | // -*- C++ -*- |
2 | //===--------------------------- complex ----------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP_COMPLEX |
11 | #define _LIBCPP_COMPLEX |
12 | |
13 | /* |
14 | complex synopsis |
15 | |
16 | namespace std |
17 | { |
18 | |
19 | template<class T> |
20 | class complex |
21 | { |
22 | public: |
23 | typedef T value_type; |
24 | |
25 | complex(const T& re = T(), const T& im = T()); // constexpr in C++14 |
26 | complex(const complex&); // constexpr in C++14 |
27 | template<class X> complex(const complex<X>&); // constexpr in C++14 |
28 | |
29 | T real() const; // constexpr in C++14 |
30 | T imag() const; // constexpr in C++14 |
31 | |
32 | void real(T); |
33 | void imag(T); |
34 | |
35 | complex<T>& operator= (const T&); |
36 | complex<T>& operator+=(const T&); |
37 | complex<T>& operator-=(const T&); |
38 | complex<T>& operator*=(const T&); |
39 | complex<T>& operator/=(const T&); |
40 | |
41 | complex& operator=(const complex&); |
42 | template<class X> complex<T>& operator= (const complex<X>&); |
43 | template<class X> complex<T>& operator+=(const complex<X>&); |
44 | template<class X> complex<T>& operator-=(const complex<X>&); |
45 | template<class X> complex<T>& operator*=(const complex<X>&); |
46 | template<class X> complex<T>& operator/=(const complex<X>&); |
47 | }; |
48 | |
49 | template<> |
50 | class complex<float> |
51 | { |
52 | public: |
53 | typedef float value_type; |
54 | |
55 | constexpr complex(float re = 0.0f, float im = 0.0f); |
56 | explicit constexpr complex(const complex<double>&); |
57 | explicit constexpr complex(const complex<long double>&); |
58 | |
59 | constexpr float real() const; |
60 | void real(float); |
61 | constexpr float imag() const; |
62 | void imag(float); |
63 | |
64 | complex<float>& operator= (float); |
65 | complex<float>& operator+=(float); |
66 | complex<float>& operator-=(float); |
67 | complex<float>& operator*=(float); |
68 | complex<float>& operator/=(float); |
69 | |
70 | complex<float>& operator=(const complex<float>&); |
71 | template<class X> complex<float>& operator= (const complex<X>&); |
72 | template<class X> complex<float>& operator+=(const complex<X>&); |
73 | template<class X> complex<float>& operator-=(const complex<X>&); |
74 | template<class X> complex<float>& operator*=(const complex<X>&); |
75 | template<class X> complex<float>& operator/=(const complex<X>&); |
76 | }; |
77 | |
78 | template<> |
79 | class complex<double> |
80 | { |
81 | public: |
82 | typedef double value_type; |
83 | |
84 | constexpr complex(double re = 0.0, double im = 0.0); |
85 | constexpr complex(const complex<float>&); |
86 | explicit constexpr complex(const complex<long double>&); |
87 | |
88 | constexpr double real() const; |
89 | void real(double); |
90 | constexpr double imag() const; |
91 | void imag(double); |
92 | |
93 | complex<double>& operator= (double); |
94 | complex<double>& operator+=(double); |
95 | complex<double>& operator-=(double); |
96 | complex<double>& operator*=(double); |
97 | complex<double>& operator/=(double); |
98 | complex<double>& operator=(const complex<double>&); |
99 | |
100 | template<class X> complex<double>& operator= (const complex<X>&); |
101 | template<class X> complex<double>& operator+=(const complex<X>&); |
102 | template<class X> complex<double>& operator-=(const complex<X>&); |
103 | template<class X> complex<double>& operator*=(const complex<X>&); |
104 | template<class X> complex<double>& operator/=(const complex<X>&); |
105 | }; |
106 | |
107 | template<> |
108 | class complex<long double> |
109 | { |
110 | public: |
111 | typedef long double value_type; |
112 | |
113 | constexpr complex(long double re = 0.0L, long double im = 0.0L); |
114 | constexpr complex(const complex<float>&); |
115 | constexpr complex(const complex<double>&); |
116 | |
117 | constexpr long double real() const; |
118 | void real(long double); |
119 | constexpr long double imag() const; |
120 | void imag(long double); |
121 | |
122 | complex<long double>& operator=(const complex<long double>&); |
123 | complex<long double>& operator= (long double); |
124 | complex<long double>& operator+=(long double); |
125 | complex<long double>& operator-=(long double); |
126 | complex<long double>& operator*=(long double); |
127 | complex<long double>& operator/=(long double); |
128 | |
129 | template<class X> complex<long double>& operator= (const complex<X>&); |
130 | template<class X> complex<long double>& operator+=(const complex<X>&); |
131 | template<class X> complex<long double>& operator-=(const complex<X>&); |
132 | template<class X> complex<long double>& operator*=(const complex<X>&); |
133 | template<class X> complex<long double>& operator/=(const complex<X>&); |
134 | }; |
135 | |
136 | // 26.3.6 operators: |
137 | template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); |
138 | template<class T> complex<T> operator+(const complex<T>&, const T&); |
139 | template<class T> complex<T> operator+(const T&, const complex<T>&); |
140 | template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); |
141 | template<class T> complex<T> operator-(const complex<T>&, const T&); |
142 | template<class T> complex<T> operator-(const T&, const complex<T>&); |
143 | template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); |
144 | template<class T> complex<T> operator*(const complex<T>&, const T&); |
145 | template<class T> complex<T> operator*(const T&, const complex<T>&); |
146 | template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); |
147 | template<class T> complex<T> operator/(const complex<T>&, const T&); |
148 | template<class T> complex<T> operator/(const T&, const complex<T>&); |
149 | template<class T> complex<T> operator+(const complex<T>&); |
150 | template<class T> complex<T> operator-(const complex<T>&); |
151 | template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14 |
152 | template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14 |
153 | template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14 |
154 | template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14 |
155 | template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14 |
156 | template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14 |
157 | |
158 | template<class T, class charT, class traits> |
159 | basic_istream<charT, traits>& |
160 | operator>>(basic_istream<charT, traits>&, complex<T>&); |
161 | template<class T, class charT, class traits> |
162 | basic_ostream<charT, traits>& |
163 | operator<<(basic_ostream<charT, traits>&, const complex<T>&); |
164 | |
165 | // 26.3.7 values: |
166 | |
167 | template<class T> T real(const complex<T>&); // constexpr in C++14 |
168 | long double real(long double); // constexpr in C++14 |
169 | double real(double); // constexpr in C++14 |
170 | template<Integral T> double real(T); // constexpr in C++14 |
171 | float real(float); // constexpr in C++14 |
172 | |
173 | template<class T> T imag(const complex<T>&); // constexpr in C++14 |
174 | long double imag(long double); // constexpr in C++14 |
175 | double imag(double); // constexpr in C++14 |
176 | template<Integral T> double imag(T); // constexpr in C++14 |
177 | float imag(float); // constexpr in C++14 |
178 | |
179 | template<class T> T abs(const complex<T>&); |
180 | |
181 | template<class T> T arg(const complex<T>&); |
182 | long double arg(long double); |
183 | double arg(double); |
184 | template<Integral T> double arg(T); |
185 | float arg(float); |
186 | |
187 | template<class T> T norm(const complex<T>&); |
188 | long double norm(long double); |
189 | double norm(double); |
190 | template<Integral T> double norm(T); |
191 | float norm(float); |
192 | |
193 | template<class T> complex<T> conj(const complex<T>&); |
194 | complex<long double> conj(long double); |
195 | complex<double> conj(double); |
196 | template<Integral T> complex<double> conj(T); |
197 | complex<float> conj(float); |
198 | |
199 | template<class T> complex<T> proj(const complex<T>&); |
200 | complex<long double> proj(long double); |
201 | complex<double> proj(double); |
202 | template<Integral T> complex<double> proj(T); |
203 | complex<float> proj(float); |
204 | |
205 | template<class T> complex<T> polar(const T&, const T& = T()); |
206 | |
207 | // 26.3.8 transcendentals: |
208 | template<class T> complex<T> acos(const complex<T>&); |
209 | template<class T> complex<T> asin(const complex<T>&); |
210 | template<class T> complex<T> atan(const complex<T>&); |
211 | template<class T> complex<T> acosh(const complex<T>&); |
212 | template<class T> complex<T> asinh(const complex<T>&); |
213 | template<class T> complex<T> atanh(const complex<T>&); |
214 | template<class T> complex<T> cos (const complex<T>&); |
215 | template<class T> complex<T> cosh (const complex<T>&); |
216 | template<class T> complex<T> exp (const complex<T>&); |
217 | template<class T> complex<T> log (const complex<T>&); |
218 | template<class T> complex<T> log10(const complex<T>&); |
219 | |
220 | template<class T> complex<T> pow(const complex<T>&, const T&); |
221 | template<class T> complex<T> pow(const complex<T>&, const complex<T>&); |
222 | template<class T> complex<T> pow(const T&, const complex<T>&); |
223 | |
224 | template<class T> complex<T> sin (const complex<T>&); |
225 | template<class T> complex<T> sinh (const complex<T>&); |
226 | template<class T> complex<T> sqrt (const complex<T>&); |
227 | template<class T> complex<T> tan (const complex<T>&); |
228 | template<class T> complex<T> tanh (const complex<T>&); |
229 | |
230 | template<class T, class charT, class traits> |
231 | basic_istream<charT, traits>& |
232 | operator>>(basic_istream<charT, traits>& is, complex<T>& x); |
233 | |
234 | template<class T, class charT, class traits> |
235 | basic_ostream<charT, traits>& |
236 | operator<<(basic_ostream<charT, traits>& o, const complex<T>& x); |
237 | |
238 | } // std |
239 | |
240 | */ |
241 | |
242 | #include <__config> |
243 | #include <type_traits> |
244 | #include <stdexcept> |
245 | #include <cmath> |
246 | #include <sstream> |
247 | #include <version> |
248 | |
249 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
250 | #pragma GCC system_header |
251 | #endif |
252 | |
253 | _LIBCPP_BEGIN_NAMESPACE_STD |
254 | |
255 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex; |
256 | |
257 | template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); |
258 | template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); |
259 | |
260 | template<class _Tp> |
261 | class _LIBCPP_TEMPLATE_VIS complex |
262 | { |
263 | public: |
264 | typedef _Tp value_type; |
265 | private: |
266 | value_type __re_; |
267 | value_type __im_; |
268 | public: |
269 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
270 | complex(const value_type& __re = value_type(), const value_type& __im = value_type()) |
271 | : __re_(__re), __im_(__im) {} |
272 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
273 | complex(const complex<_Xp>& __c) |
274 | : __re_(__c.real()), __im_(__c.imag()) {} |
275 | |
276 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} |
277 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} |
278 | |
279 | _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} |
280 | _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} |
281 | |
282 | _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) |
283 | {__re_ = __re; __im_ = value_type(); return *this;} |
284 | _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} |
285 | _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} |
286 | _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} |
287 | _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} |
288 | |
289 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) |
290 | { |
291 | __re_ = __c.real(); |
292 | __im_ = __c.imag(); |
293 | return *this; |
294 | } |
295 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) |
296 | { |
297 | __re_ += __c.real(); |
298 | __im_ += __c.imag(); |
299 | return *this; |
300 | } |
301 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) |
302 | { |
303 | __re_ -= __c.real(); |
304 | __im_ -= __c.imag(); |
305 | return *this; |
306 | } |
307 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) |
308 | { |
309 | *this = *this * complex(__c.real(), __c.imag()); |
310 | return *this; |
311 | } |
312 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) |
313 | { |
314 | *this = *this / complex(__c.real(), __c.imag()); |
315 | return *this; |
316 | } |
317 | }; |
318 | |
319 | template<> class _LIBCPP_TEMPLATE_VIS complex<double>; |
320 | template<> class _LIBCPP_TEMPLATE_VIS complex<long double>; |
321 | |
322 | template<> |
323 | class _LIBCPP_TEMPLATE_VIS complex<float> |
324 | { |
325 | float __re_; |
326 | float __im_; |
327 | public: |
328 | typedef float value_type; |
329 | |
330 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) |
331 | : __re_(__re), __im_(__im) {} |
332 | _LIBCPP_INLINE_VISIBILITY |
333 | explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); |
334 | _LIBCPP_INLINE_VISIBILITY |
335 | explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); |
336 | |
337 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} |
338 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} |
339 | |
340 | _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} |
341 | _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} |
342 | |
343 | _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) |
344 | {__re_ = __re; __im_ = value_type(); return *this;} |
345 | _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} |
346 | _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} |
347 | _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} |
348 | _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} |
349 | |
350 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) |
351 | { |
352 | __re_ = __c.real(); |
353 | __im_ = __c.imag(); |
354 | return *this; |
355 | } |
356 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) |
357 | { |
358 | __re_ += __c.real(); |
359 | __im_ += __c.imag(); |
360 | return *this; |
361 | } |
362 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) |
363 | { |
364 | __re_ -= __c.real(); |
365 | __im_ -= __c.imag(); |
366 | return *this; |
367 | } |
368 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) |
369 | { |
370 | *this = *this * complex(__c.real(), __c.imag()); |
371 | return *this; |
372 | } |
373 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) |
374 | { |
375 | *this = *this / complex(__c.real(), __c.imag()); |
376 | return *this; |
377 | } |
378 | }; |
379 | |
380 | template<> |
381 | class _LIBCPP_TEMPLATE_VIS complex<double> |
382 | { |
383 | double __re_; |
384 | double __im_; |
385 | public: |
386 | typedef double value_type; |
387 | |
388 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) |
389 | : __re_(__re), __im_(__im) {} |
390 | _LIBCPP_INLINE_VISIBILITY |
391 | _LIBCPP_CONSTEXPR complex(const complex<float>& __c); |
392 | _LIBCPP_INLINE_VISIBILITY |
393 | explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); |
394 | |
395 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} |
396 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} |
397 | |
398 | _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} |
399 | _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} |
400 | |
401 | _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) |
402 | {__re_ = __re; __im_ = value_type(); return *this;} |
403 | _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} |
404 | _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} |
405 | _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} |
406 | _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} |
407 | |
408 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) |
409 | { |
410 | __re_ = __c.real(); |
411 | __im_ = __c.imag(); |
412 | return *this; |
413 | } |
414 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) |
415 | { |
416 | __re_ += __c.real(); |
417 | __im_ += __c.imag(); |
418 | return *this; |
419 | } |
420 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) |
421 | { |
422 | __re_ -= __c.real(); |
423 | __im_ -= __c.imag(); |
424 | return *this; |
425 | } |
426 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) |
427 | { |
428 | *this = *this * complex(__c.real(), __c.imag()); |
429 | return *this; |
430 | } |
431 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) |
432 | { |
433 | *this = *this / complex(__c.real(), __c.imag()); |
434 | return *this; |
435 | } |
436 | }; |
437 | |
438 | template<> |
439 | class _LIBCPP_TEMPLATE_VIS complex<long double> |
440 | { |
441 | long double __re_; |
442 | long double __im_; |
443 | public: |
444 | typedef long double value_type; |
445 | |
446 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) |
447 | : __re_(__re), __im_(__im) {} |
448 | _LIBCPP_INLINE_VISIBILITY |
449 | _LIBCPP_CONSTEXPR complex(const complex<float>& __c); |
450 | _LIBCPP_INLINE_VISIBILITY |
451 | _LIBCPP_CONSTEXPR complex(const complex<double>& __c); |
452 | |
453 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} |
454 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} |
455 | |
456 | _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} |
457 | _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} |
458 | |
459 | _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) |
460 | {__re_ = __re; __im_ = value_type(); return *this;} |
461 | _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} |
462 | _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} |
463 | _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} |
464 | _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} |
465 | |
466 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) |
467 | { |
468 | __re_ = __c.real(); |
469 | __im_ = __c.imag(); |
470 | return *this; |
471 | } |
472 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) |
473 | { |
474 | __re_ += __c.real(); |
475 | __im_ += __c.imag(); |
476 | return *this; |
477 | } |
478 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) |
479 | { |
480 | __re_ -= __c.real(); |
481 | __im_ -= __c.imag(); |
482 | return *this; |
483 | } |
484 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) |
485 | { |
486 | *this = *this * complex(__c.real(), __c.imag()); |
487 | return *this; |
488 | } |
489 | template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) |
490 | { |
491 | *this = *this / complex(__c.real(), __c.imag()); |
492 | return *this; |
493 | } |
494 | }; |
495 | |
496 | inline |
497 | _LIBCPP_CONSTEXPR |
498 | complex<float>::complex(const complex<double>& __c) |
499 | : __re_(__c.real()), __im_(__c.imag()) {} |
500 | |
501 | inline |
502 | _LIBCPP_CONSTEXPR |
503 | complex<float>::complex(const complex<long double>& __c) |
504 | : __re_(__c.real()), __im_(__c.imag()) {} |
505 | |
506 | inline |
507 | _LIBCPP_CONSTEXPR |
508 | complex<double>::complex(const complex<float>& __c) |
509 | : __re_(__c.real()), __im_(__c.imag()) {} |
510 | |
511 | inline |
512 | _LIBCPP_CONSTEXPR |
513 | complex<double>::complex(const complex<long double>& __c) |
514 | : __re_(__c.real()), __im_(__c.imag()) {} |
515 | |
516 | inline |
517 | _LIBCPP_CONSTEXPR |
518 | complex<long double>::complex(const complex<float>& __c) |
519 | : __re_(__c.real()), __im_(__c.imag()) {} |
520 | |
521 | inline |
522 | _LIBCPP_CONSTEXPR |
523 | complex<long double>::complex(const complex<double>& __c) |
524 | : __re_(__c.real()), __im_(__c.imag()) {} |
525 | |
526 | // 26.3.6 operators: |
527 | |
528 | template<class _Tp> |
529 | inline _LIBCPP_INLINE_VISIBILITY |
530 | complex<_Tp> |
531 | operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) |
532 | { |
533 | complex<_Tp> __t(__x); |
534 | __t += __y; |
535 | return __t; |
536 | } |
537 | |
538 | template<class _Tp> |
539 | inline _LIBCPP_INLINE_VISIBILITY |
540 | complex<_Tp> |
541 | operator+(const complex<_Tp>& __x, const _Tp& __y) |
542 | { |
543 | complex<_Tp> __t(__x); |
544 | __t += __y; |
545 | return __t; |
546 | } |
547 | |
548 | template<class _Tp> |
549 | inline _LIBCPP_INLINE_VISIBILITY |
550 | complex<_Tp> |
551 | operator+(const _Tp& __x, const complex<_Tp>& __y) |
552 | { |
553 | complex<_Tp> __t(__y); |
554 | __t += __x; |
555 | return __t; |
556 | } |
557 | |
558 | template<class _Tp> |
559 | inline _LIBCPP_INLINE_VISIBILITY |
560 | complex<_Tp> |
561 | operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) |
562 | { |
563 | complex<_Tp> __t(__x); |
564 | __t -= __y; |
565 | return __t; |
566 | } |
567 | |
568 | template<class _Tp> |
569 | inline _LIBCPP_INLINE_VISIBILITY |
570 | complex<_Tp> |
571 | operator-(const complex<_Tp>& __x, const _Tp& __y) |
572 | { |
573 | complex<_Tp> __t(__x); |
574 | __t -= __y; |
575 | return __t; |
576 | } |
577 | |
578 | template<class _Tp> |
579 | inline _LIBCPP_INLINE_VISIBILITY |
580 | complex<_Tp> |
581 | operator-(const _Tp& __x, const complex<_Tp>& __y) |
582 | { |
583 | complex<_Tp> __t(-__y); |
584 | __t += __x; |
585 | return __t; |
586 | } |
587 | |
588 | template<class _Tp> |
589 | complex<_Tp> |
590 | operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) |
591 | { |
592 | _Tp __a = __z.real(); |
593 | _Tp __b = __z.imag(); |
594 | _Tp __c = __w.real(); |
595 | _Tp __d = __w.imag(); |
596 | _Tp __ac = __a * __c; |
597 | _Tp __bd = __b * __d; |
598 | _Tp __ad = __a * __d; |
599 | _Tp __bc = __b * __c; |
600 | _Tp __x = __ac - __bd; |
601 | _Tp __y = __ad + __bc; |
602 | if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) |
603 | { |
604 | bool __recalc = false; |
605 | if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) |
606 | { |
607 | __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); |
608 | __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); |
609 | if (__libcpp_isnan_or_builtin(__c)) |
610 | __c = copysign(_Tp(0), __c); |
611 | if (__libcpp_isnan_or_builtin(__d)) |
612 | __d = copysign(_Tp(0), __d); |
613 | __recalc = true; |
614 | } |
615 | if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) |
616 | { |
617 | __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); |
618 | __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); |
619 | if (__libcpp_isnan_or_builtin(__a)) |
620 | __a = copysign(_Tp(0), __a); |
621 | if (__libcpp_isnan_or_builtin(__b)) |
622 | __b = copysign(_Tp(0), __b); |
623 | __recalc = true; |
624 | } |
625 | if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) || |
626 | __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc))) |
627 | { |
628 | if (__libcpp_isnan_or_builtin(__a)) |
629 | __a = copysign(_Tp(0), __a); |
630 | if (__libcpp_isnan_or_builtin(__b)) |
631 | __b = copysign(_Tp(0), __b); |
632 | if (__libcpp_isnan_or_builtin(__c)) |
633 | __c = copysign(_Tp(0), __c); |
634 | if (__libcpp_isnan_or_builtin(__d)) |
635 | __d = copysign(_Tp(0), __d); |
636 | __recalc = true; |
637 | } |
638 | if (__recalc) |
639 | { |
640 | __x = _Tp(INFINITY) * (__a * __c - __b * __d); |
641 | __y = _Tp(INFINITY) * (__a * __d + __b * __c); |
642 | } |
643 | } |
644 | return complex<_Tp>(__x, __y); |
645 | } |
646 | |
647 | template<class _Tp> |
648 | inline _LIBCPP_INLINE_VISIBILITY |
649 | complex<_Tp> |
650 | operator*(const complex<_Tp>& __x, const _Tp& __y) |
651 | { |
652 | complex<_Tp> __t(__x); |
653 | __t *= __y; |
654 | return __t; |
655 | } |
656 | |
657 | template<class _Tp> |
658 | inline _LIBCPP_INLINE_VISIBILITY |
659 | complex<_Tp> |
660 | operator*(const _Tp& __x, const complex<_Tp>& __y) |
661 | { |
662 | complex<_Tp> __t(__y); |
663 | __t *= __x; |
664 | return __t; |
665 | } |
666 | |
667 | template<class _Tp> |
668 | complex<_Tp> |
669 | operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) |
670 | { |
671 | int __ilogbw = 0; |
672 | _Tp __a = __z.real(); |
673 | _Tp __b = __z.imag(); |
674 | _Tp __c = __w.real(); |
675 | _Tp __d = __w.imag(); |
676 | _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); |
677 | if (__libcpp_isfinite_or_builtin(__logbw)) |
678 | { |
679 | __ilogbw = static_cast<int>(__logbw); |
680 | __c = scalbn(__c, -__ilogbw); |
681 | __d = scalbn(__d, -__ilogbw); |
682 | } |
683 | _Tp __denom = __c * __c + __d * __d; |
684 | _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); |
685 | _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); |
686 | if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) |
687 | { |
688 | if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b))) |
689 | { |
690 | __x = copysign(_Tp(INFINITY), __c) * __a; |
691 | __y = copysign(_Tp(INFINITY), __c) * __b; |
692 | } |
693 | else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d)) |
694 | { |
695 | __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); |
696 | __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); |
697 | __x = _Tp(INFINITY) * (__a * __c + __b * __d); |
698 | __y = _Tp(INFINITY) * (__b * __c - __a * __d); |
699 | } |
700 | else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b)) |
701 | { |
702 | __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); |
703 | __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); |
704 | __x = _Tp(0) * (__a * __c + __b * __d); |
705 | __y = _Tp(0) * (__b * __c - __a * __d); |
706 | } |
707 | } |
708 | return complex<_Tp>(__x, __y); |
709 | } |
710 | |
711 | template<class _Tp> |
712 | inline _LIBCPP_INLINE_VISIBILITY |
713 | complex<_Tp> |
714 | operator/(const complex<_Tp>& __x, const _Tp& __y) |
715 | { |
716 | return complex<_Tp>(__x.real() / __y, __x.imag() / __y); |
717 | } |
718 | |
719 | template<class _Tp> |
720 | inline _LIBCPP_INLINE_VISIBILITY |
721 | complex<_Tp> |
722 | operator/(const _Tp& __x, const complex<_Tp>& __y) |
723 | { |
724 | complex<_Tp> __t(__x); |
725 | __t /= __y; |
726 | return __t; |
727 | } |
728 | |
729 | template<class _Tp> |
730 | inline _LIBCPP_INLINE_VISIBILITY |
731 | complex<_Tp> |
732 | operator+(const complex<_Tp>& __x) |
733 | { |
734 | return __x; |
735 | } |
736 | |
737 | template<class _Tp> |
738 | inline _LIBCPP_INLINE_VISIBILITY |
739 | complex<_Tp> |
740 | operator-(const complex<_Tp>& __x) |
741 | { |
742 | return complex<_Tp>(-__x.real(), -__x.imag()); |
743 | } |
744 | |
745 | template<class _Tp> |
746 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
747 | bool |
748 | operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) |
749 | { |
750 | return __x.real() == __y.real() && __x.imag() == __y.imag(); |
751 | } |
752 | |
753 | template<class _Tp> |
754 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
755 | bool |
756 | operator==(const complex<_Tp>& __x, const _Tp& __y) |
757 | { |
758 | return __x.real() == __y && __x.imag() == 0; |
759 | } |
760 | |
761 | template<class _Tp> |
762 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
763 | bool |
764 | operator==(const _Tp& __x, const complex<_Tp>& __y) |
765 | { |
766 | return __x == __y.real() && 0 == __y.imag(); |
767 | } |
768 | |
769 | template<class _Tp> |
770 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
771 | bool |
772 | operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) |
773 | { |
774 | return !(__x == __y); |
775 | } |
776 | |
777 | template<class _Tp> |
778 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
779 | bool |
780 | operator!=(const complex<_Tp>& __x, const _Tp& __y) |
781 | { |
782 | return !(__x == __y); |
783 | } |
784 | |
785 | template<class _Tp> |
786 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
787 | bool |
788 | operator!=(const _Tp& __x, const complex<_Tp>& __y) |
789 | { |
790 | return !(__x == __y); |
791 | } |
792 | |
793 | // 26.3.7 values: |
794 | |
795 | template <class _Tp, bool = is_integral<_Tp>::value, |
796 | bool = is_floating_point<_Tp>::value |
797 | > |
798 | struct __libcpp_complex_overload_traits {}; |
799 | |
800 | // Integral Types |
801 | template <class _Tp> |
802 | struct __libcpp_complex_overload_traits<_Tp, true, false> |
803 | { |
804 | typedef double _ValueType; |
805 | typedef complex<double> _ComplexType; |
806 | }; |
807 | |
808 | // Floating point types |
809 | template <class _Tp> |
810 | struct __libcpp_complex_overload_traits<_Tp, false, true> |
811 | { |
812 | typedef _Tp _ValueType; |
813 | typedef complex<_Tp> _ComplexType; |
814 | }; |
815 | |
816 | // real |
817 | |
818 | template<class _Tp> |
819 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
820 | _Tp |
821 | real(const complex<_Tp>& __c) |
822 | { |
823 | return __c.real(); |
824 | } |
825 | |
826 | template <class _Tp> |
827 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
828 | typename __libcpp_complex_overload_traits<_Tp>::_ValueType |
829 | real(_Tp __re) |
830 | { |
831 | return __re; |
832 | } |
833 | |
834 | // imag |
835 | |
836 | template<class _Tp> |
837 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
838 | _Tp |
839 | imag(const complex<_Tp>& __c) |
840 | { |
841 | return __c.imag(); |
842 | } |
843 | |
844 | template <class _Tp> |
845 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 |
846 | typename __libcpp_complex_overload_traits<_Tp>::_ValueType |
847 | imag(_Tp) |
848 | { |
849 | return 0; |
850 | } |
851 | |
852 | // abs |
853 | |
854 | template<class _Tp> |
855 | inline _LIBCPP_INLINE_VISIBILITY |
856 | _Tp |
857 | abs(const complex<_Tp>& __c) |
858 | { |
859 | return hypot(__c.real(), __c.imag()); |
860 | } |
861 | |
862 | // arg |
863 | |
864 | template<class _Tp> |
865 | inline _LIBCPP_INLINE_VISIBILITY |
866 | _Tp |
867 | arg(const complex<_Tp>& __c) |
868 | { |
869 | return atan2(__c.imag(), __c.real()); |
870 | } |
871 | |
872 | template <class _Tp> |
873 | inline _LIBCPP_INLINE_VISIBILITY |
874 | typename enable_if< |
875 | is_same<_Tp, long double>::value, |
876 | long double |
877 | >::type |
878 | arg(_Tp __re) |
879 | { |
880 | return atan2l(0.L, __re); |
881 | } |
882 | |
883 | template<class _Tp> |
884 | inline _LIBCPP_INLINE_VISIBILITY |
885 | typename enable_if |
886 | < |
887 | is_integral<_Tp>::value || is_same<_Tp, double>::value, |
888 | double |
889 | >::type |
890 | arg(_Tp __re) |
891 | { |
892 | return atan2(0., __re); |
893 | } |
894 | |
895 | template <class _Tp> |
896 | inline _LIBCPP_INLINE_VISIBILITY |
897 | typename enable_if< |
898 | is_same<_Tp, float>::value, |
899 | float |
900 | >::type |
901 | arg(_Tp __re) |
902 | { |
903 | return atan2f(0.F, __re); |
904 | } |
905 | |
906 | // norm |
907 | |
908 | template<class _Tp> |
909 | inline _LIBCPP_INLINE_VISIBILITY |
910 | _Tp |
911 | norm(const complex<_Tp>& __c) |
912 | { |
913 | if (__libcpp_isinf_or_builtin(__c.real())) |
914 | return abs(__c.real()); |
915 | if (__libcpp_isinf_or_builtin(__c.imag())) |
916 | return abs(__c.imag()); |
917 | return __c.real() * __c.real() + __c.imag() * __c.imag(); |
918 | } |
919 | |
920 | template <class _Tp> |
921 | inline _LIBCPP_INLINE_VISIBILITY |
922 | typename __libcpp_complex_overload_traits<_Tp>::_ValueType |
923 | norm(_Tp __re) |
924 | { |
925 | typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; |
926 | return static_cast<_ValueType>(__re) * __re; |
927 | } |
928 | |
929 | // conj |
930 | |
931 | template<class _Tp> |
932 | inline _LIBCPP_INLINE_VISIBILITY |
933 | complex<_Tp> |
934 | conj(const complex<_Tp>& __c) |
935 | { |
936 | return complex<_Tp>(__c.real(), -__c.imag()); |
937 | } |
938 | |
939 | template <class _Tp> |
940 | inline _LIBCPP_INLINE_VISIBILITY |
941 | typename __libcpp_complex_overload_traits<_Tp>::_ComplexType |
942 | conj(_Tp __re) |
943 | { |
944 | typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; |
945 | return _ComplexType(__re); |
946 | } |
947 | |
948 | |
949 | |
950 | // proj |
951 | |
952 | template<class _Tp> |
953 | inline _LIBCPP_INLINE_VISIBILITY |
954 | complex<_Tp> |
955 | proj(const complex<_Tp>& __c) |
956 | { |
957 | std::complex<_Tp> __r = __c; |
958 | if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag())) |
959 | __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); |
960 | return __r; |
961 | } |
962 | |
963 | template <class _Tp> |
964 | inline _LIBCPP_INLINE_VISIBILITY |
965 | typename enable_if |
966 | < |
967 | is_floating_point<_Tp>::value, |
968 | typename __libcpp_complex_overload_traits<_Tp>::_ComplexType |
969 | >::type |
970 | proj(_Tp __re) |
971 | { |
972 | if (__libcpp_isinf_or_builtin(__re)) |
973 | __re = abs(__re); |
974 | return complex<_Tp>(__re); |
975 | } |
976 | |
977 | template <class _Tp> |
978 | inline _LIBCPP_INLINE_VISIBILITY |
979 | typename enable_if |
980 | < |
981 | is_integral<_Tp>::value, |
982 | typename __libcpp_complex_overload_traits<_Tp>::_ComplexType |
983 | >::type |
984 | proj(_Tp __re) |
985 | { |
986 | typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; |
987 | return _ComplexType(__re); |
988 | } |
989 | |
990 | // polar |
991 | |
992 | template<class _Tp> |
993 | complex<_Tp> |
994 | polar(const _Tp& __rho, const _Tp& __theta = _Tp()) |
995 | { |
996 | if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho)) |
997 | return complex<_Tp>(_Tp(NAN), _Tp(NAN)); |
998 | if (__libcpp_isnan_or_builtin(__theta)) |
999 | { |
1000 | if (__libcpp_isinf_or_builtin(__rho)) |
1001 | return complex<_Tp>(__rho, __theta); |
1002 | return complex<_Tp>(__theta, __theta); |
1003 | } |
1004 | if (__libcpp_isinf_or_builtin(__theta)) |
1005 | { |
1006 | if (__libcpp_isinf_or_builtin(__rho)) |
1007 | return complex<_Tp>(__rho, _Tp(NAN)); |
1008 | return complex<_Tp>(_Tp(NAN), _Tp(NAN)); |
1009 | } |
1010 | _Tp __x = __rho * cos(__theta); |
1011 | if (__libcpp_isnan_or_builtin(__x)) |
1012 | __x = 0; |
1013 | _Tp __y = __rho * sin(__theta); |
1014 | if (__libcpp_isnan_or_builtin(__y)) |
1015 | __y = 0; |
1016 | return complex<_Tp>(__x, __y); |
1017 | } |
1018 | |
1019 | // log |
1020 | |
1021 | template<class _Tp> |
1022 | inline _LIBCPP_INLINE_VISIBILITY |
1023 | complex<_Tp> |
1024 | log(const complex<_Tp>& __x) |
1025 | { |
1026 | return complex<_Tp>(log(abs(__x)), arg(__x)); |
1027 | } |
1028 | |
1029 | // log10 |
1030 | |
1031 | template<class _Tp> |
1032 | inline _LIBCPP_INLINE_VISIBILITY |
1033 | complex<_Tp> |
1034 | log10(const complex<_Tp>& __x) |
1035 | { |
1036 | return log(__x) / log(_Tp(10)); |
1037 | } |
1038 | |
1039 | // sqrt |
1040 | |
1041 | template<class _Tp> |
1042 | complex<_Tp> |
1043 | sqrt(const complex<_Tp>& __x) |
1044 | { |
1045 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1046 | return complex<_Tp>(_Tp(INFINITY), __x.imag()); |
1047 | if (__libcpp_isinf_or_builtin(__x.real())) |
1048 | { |
1049 | if (__x.real() > _Tp(0)) |
1050 | return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); |
1051 | return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); |
1052 | } |
1053 | return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); |
1054 | } |
1055 | |
1056 | // exp |
1057 | |
1058 | template<class _Tp> |
1059 | complex<_Tp> |
1060 | exp(const complex<_Tp>& __x) |
1061 | { |
1062 | _Tp __i = __x.imag(); |
1063 | if (__libcpp_isinf_or_builtin(__x.real())) |
1064 | { |
1065 | if (__x.real() < _Tp(0)) |
1066 | { |
1067 | if (!__libcpp_isfinite_or_builtin(__i)) |
1068 | __i = _Tp(1); |
1069 | } |
1070 | else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i)) |
1071 | { |
1072 | if (__libcpp_isinf_or_builtin(__i)) |
1073 | __i = _Tp(NAN); |
1074 | return complex<_Tp>(__x.real(), __i); |
1075 | } |
1076 | } |
1077 | else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) |
1078 | return __x; |
1079 | _Tp __e = exp(__x.real()); |
1080 | return complex<_Tp>(__e * cos(__i), __e * sin(__i)); |
1081 | } |
1082 | |
1083 | // pow |
1084 | |
1085 | template<class _Tp> |
1086 | inline _LIBCPP_INLINE_VISIBILITY |
1087 | complex<_Tp> |
1088 | pow(const complex<_Tp>& __x, const complex<_Tp>& __y) |
1089 | { |
1090 | return exp(__y * log(__x)); |
1091 | } |
1092 | |
1093 | template<class _Tp, class _Up> |
1094 | inline _LIBCPP_INLINE_VISIBILITY |
1095 | complex<typename __promote<_Tp, _Up>::type> |
1096 | pow(const complex<_Tp>& __x, const complex<_Up>& __y) |
1097 | { |
1098 | typedef complex<typename __promote<_Tp, _Up>::type> result_type; |
1099 | return _VSTD::pow(result_type(__x), result_type(__y)); |
1100 | } |
1101 | |
1102 | template<class _Tp, class _Up> |
1103 | inline _LIBCPP_INLINE_VISIBILITY |
1104 | typename enable_if |
1105 | < |
1106 | is_arithmetic<_Up>::value, |
1107 | complex<typename __promote<_Tp, _Up>::type> |
1108 | >::type |
1109 | pow(const complex<_Tp>& __x, const _Up& __y) |
1110 | { |
1111 | typedef complex<typename __promote<_Tp, _Up>::type> result_type; |
1112 | return _VSTD::pow(result_type(__x), result_type(__y)); |
1113 | } |
1114 | |
1115 | template<class _Tp, class _Up> |
1116 | inline _LIBCPP_INLINE_VISIBILITY |
1117 | typename enable_if |
1118 | < |
1119 | is_arithmetic<_Tp>::value, |
1120 | complex<typename __promote<_Tp, _Up>::type> |
1121 | >::type |
1122 | pow(const _Tp& __x, const complex<_Up>& __y) |
1123 | { |
1124 | typedef complex<typename __promote<_Tp, _Up>::type> result_type; |
1125 | return _VSTD::pow(result_type(__x), result_type(__y)); |
1126 | } |
1127 | |
1128 | // __sqr, computes pow(x, 2) |
1129 | |
1130 | template<class _Tp> |
1131 | inline _LIBCPP_INLINE_VISIBILITY |
1132 | complex<_Tp> |
1133 | __sqr(const complex<_Tp>& __x) |
1134 | { |
1135 | return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), |
1136 | _Tp(2) * __x.real() * __x.imag()); |
1137 | } |
1138 | |
1139 | // asinh |
1140 | |
1141 | template<class _Tp> |
1142 | complex<_Tp> |
1143 | asinh(const complex<_Tp>& __x) |
1144 | { |
1145 | const _Tp __pi(atan2(+0., -0.)); |
1146 | if (__libcpp_isinf_or_builtin(__x.real())) |
1147 | { |
1148 | if (__libcpp_isnan_or_builtin(__x.imag())) |
1149 | return __x; |
1150 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1151 | return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); |
1152 | return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); |
1153 | } |
1154 | if (__libcpp_isnan_or_builtin(__x.real())) |
1155 | { |
1156 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1157 | return complex<_Tp>(__x.imag(), __x.real()); |
1158 | if (__x.imag() == 0) |
1159 | return __x; |
1160 | return complex<_Tp>(__x.real(), __x.real()); |
1161 | } |
1162 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1163 | return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); |
1164 | complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1))); |
1165 | return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); |
1166 | } |
1167 | |
1168 | // acosh |
1169 | |
1170 | template<class _Tp> |
1171 | complex<_Tp> |
1172 | acosh(const complex<_Tp>& __x) |
1173 | { |
1174 | const _Tp __pi(atan2(+0., -0.)); |
1175 | if (__libcpp_isinf_or_builtin(__x.real())) |
1176 | { |
1177 | if (__libcpp_isnan_or_builtin(__x.imag())) |
1178 | return complex<_Tp>(abs(__x.real()), __x.imag()); |
1179 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1180 | { |
1181 | if (__x.real() > 0) |
1182 | return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); |
1183 | else |
1184 | return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag())); |
1185 | } |
1186 | if (__x.real() < 0) |
1187 | return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); |
1188 | return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); |
1189 | } |
1190 | if (__libcpp_isnan_or_builtin(__x.real())) |
1191 | { |
1192 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1193 | return complex<_Tp>(abs(__x.imag()), __x.real()); |
1194 | return complex<_Tp>(__x.real(), __x.real()); |
1195 | } |
1196 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1197 | return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); |
1198 | complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); |
1199 | return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); |
1200 | } |
1201 | |
1202 | // atanh |
1203 | |
1204 | template<class _Tp> |
1205 | complex<_Tp> |
1206 | atanh(const complex<_Tp>& __x) |
1207 | { |
1208 | const _Tp __pi(atan2(+0., -0.)); |
1209 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1210 | { |
1211 | return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); |
1212 | } |
1213 | if (__libcpp_isnan_or_builtin(__x.imag())) |
1214 | { |
1215 | if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0) |
1216 | return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); |
1217 | return complex<_Tp>(__x.imag(), __x.imag()); |
1218 | } |
1219 | if (__libcpp_isnan_or_builtin(__x.real())) |
1220 | { |
1221 | return complex<_Tp>(__x.real(), __x.real()); |
1222 | } |
1223 | if (__libcpp_isinf_or_builtin(__x.real())) |
1224 | { |
1225 | return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); |
1226 | } |
1227 | if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) |
1228 | { |
1229 | return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag())); |
1230 | } |
1231 | complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); |
1232 | return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); |
1233 | } |
1234 | |
1235 | // sinh |
1236 | |
1237 | template<class _Tp> |
1238 | complex<_Tp> |
1239 | sinh(const complex<_Tp>& __x) |
1240 | { |
1241 | if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) |
1242 | return complex<_Tp>(__x.real(), _Tp(NAN)); |
1243 | if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) |
1244 | return complex<_Tp>(__x.real(), _Tp(NAN)); |
1245 | if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) |
1246 | return __x; |
1247 | return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); |
1248 | } |
1249 | |
1250 | // cosh |
1251 | |
1252 | template<class _Tp> |
1253 | complex<_Tp> |
1254 | cosh(const complex<_Tp>& __x) |
1255 | { |
1256 | if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) |
1257 | return complex<_Tp>(abs(__x.real()), _Tp(NAN)); |
1258 | if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) |
1259 | return complex<_Tp>(_Tp(NAN), __x.real()); |
1260 | if (__x.real() == 0 && __x.imag() == 0) |
1261 | return complex<_Tp>(_Tp(1), __x.imag()); |
1262 | if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) |
1263 | return complex<_Tp>(abs(__x.real()), __x.imag()); |
1264 | return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); |
1265 | } |
1266 | |
1267 | // tanh |
1268 | |
1269 | template<class _Tp> |
1270 | complex<_Tp> |
1271 | tanh(const complex<_Tp>& __x) |
1272 | { |
1273 | if (__libcpp_isinf_or_builtin(__x.real())) |
1274 | { |
1275 | if (!__libcpp_isfinite_or_builtin(__x.imag())) |
1276 | return complex<_Tp>(_Tp(1), _Tp(0)); |
1277 | return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); |
1278 | } |
1279 | if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) |
1280 | return __x; |
1281 | _Tp __2r(_Tp(2) * __x.real()); |
1282 | _Tp __2i(_Tp(2) * __x.imag()); |
1283 | _Tp __d(cosh(__2r) + cos(__2i)); |
1284 | _Tp __2rsh(sinh(__2r)); |
1285 | if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d)) |
1286 | return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), |
1287 | __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); |
1288 | return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); |
1289 | } |
1290 | |
1291 | // asin |
1292 | |
1293 | template<class _Tp> |
1294 | complex<_Tp> |
1295 | asin(const complex<_Tp>& __x) |
1296 | { |
1297 | complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real())); |
1298 | return complex<_Tp>(__z.imag(), -__z.real()); |
1299 | } |
1300 | |
1301 | // acos |
1302 | |
1303 | template<class _Tp> |
1304 | complex<_Tp> |
1305 | acos(const complex<_Tp>& __x) |
1306 | { |
1307 | const _Tp __pi(atan2(+0., -0.)); |
1308 | if (__libcpp_isinf_or_builtin(__x.real())) |
1309 | { |
1310 | if (__libcpp_isnan_or_builtin(__x.imag())) |
1311 | return complex<_Tp>(__x.imag(), __x.real()); |
1312 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1313 | { |
1314 | if (__x.real() < _Tp(0)) |
1315 | return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); |
1316 | return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); |
1317 | } |
1318 | if (__x.real() < _Tp(0)) |
1319 | return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); |
1320 | return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); |
1321 | } |
1322 | if (__libcpp_isnan_or_builtin(__x.real())) |
1323 | { |
1324 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1325 | return complex<_Tp>(__x.real(), -__x.imag()); |
1326 | return complex<_Tp>(__x.real(), __x.real()); |
1327 | } |
1328 | if (__libcpp_isinf_or_builtin(__x.imag())) |
1329 | return complex<_Tp>(__pi/_Tp(2), -__x.imag()); |
1330 | if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) |
1331 | return complex<_Tp>(__pi/_Tp(2), -__x.imag()); |
1332 | complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); |
1333 | if (signbit(__x.imag())) |
1334 | return complex<_Tp>(abs(__z.imag()), abs(__z.real())); |
1335 | return complex<_Tp>(abs(__z.imag()), -abs(__z.real())); |
1336 | } |
1337 | |
1338 | // atan |
1339 | |
1340 | template<class _Tp> |
1341 | complex<_Tp> |
1342 | atan(const complex<_Tp>& __x) |
1343 | { |
1344 | complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real())); |
1345 | return complex<_Tp>(__z.imag(), -__z.real()); |
1346 | } |
1347 | |
1348 | // sin |
1349 | |
1350 | template<class _Tp> |
1351 | complex<_Tp> |
1352 | sin(const complex<_Tp>& __x) |
1353 | { |
1354 | complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real())); |
1355 | return complex<_Tp>(__z.imag(), -__z.real()); |
1356 | } |
1357 | |
1358 | // cos |
1359 | |
1360 | template<class _Tp> |
1361 | inline _LIBCPP_INLINE_VISIBILITY |
1362 | complex<_Tp> |
1363 | cos(const complex<_Tp>& __x) |
1364 | { |
1365 | return cosh(complex<_Tp>(-__x.imag(), __x.real())); |
1366 | } |
1367 | |
1368 | // tan |
1369 | |
1370 | template<class _Tp> |
1371 | complex<_Tp> |
1372 | tan(const complex<_Tp>& __x) |
1373 | { |
1374 | complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real())); |
1375 | return complex<_Tp>(__z.imag(), -__z.real()); |
1376 | } |
1377 | |
1378 | template<class _Tp, class _CharT, class _Traits> |
1379 | basic_istream<_CharT, _Traits>& |
1380 | operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) |
1381 | { |
1382 | if (__is.good()) |
1383 | { |
1384 | ws(__is); |
1385 | if (__is.peek() == _CharT('(')) |
1386 | { |
1387 | __is.get(); |
1388 | _Tp __r; |
1389 | __is >> __r; |
1390 | if (!__is.fail()) |
1391 | { |
1392 | ws(__is); |
1393 | _CharT __c = __is.peek(); |
1394 | if (__c == _CharT(',')) |
1395 | { |
1396 | __is.get(); |
1397 | _Tp __i; |
1398 | __is >> __i; |
1399 | if (!__is.fail()) |
1400 | { |
1401 | ws(__is); |
1402 | __c = __is.peek(); |
1403 | if (__c == _CharT(')')) |
1404 | { |
1405 | __is.get(); |
1406 | __x = complex<_Tp>(__r, __i); |
1407 | } |
1408 | else |
1409 | __is.setstate(ios_base::failbit); |
1410 | } |
1411 | else |
1412 | __is.setstate(ios_base::failbit); |
1413 | } |
1414 | else if (__c == _CharT(')')) |
1415 | { |
1416 | __is.get(); |
1417 | __x = complex<_Tp>(__r, _Tp(0)); |
1418 | } |
1419 | else |
1420 | __is.setstate(ios_base::failbit); |
1421 | } |
1422 | else |
1423 | __is.setstate(ios_base::failbit); |
1424 | } |
1425 | else |
1426 | { |
1427 | _Tp __r; |
1428 | __is >> __r; |
1429 | if (!__is.fail()) |
1430 | __x = complex<_Tp>(__r, _Tp(0)); |
1431 | else |
1432 | __is.setstate(ios_base::failbit); |
1433 | } |
1434 | } |
1435 | else |
1436 | __is.setstate(ios_base::failbit); |
1437 | return __is; |
1438 | } |
1439 | |
1440 | template<class _Tp, class _CharT, class _Traits> |
1441 | basic_ostream<_CharT, _Traits>& |
1442 | operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) |
1443 | { |
1444 | basic_ostringstream<_CharT, _Traits> __s; |
1445 | __s.flags(__os.flags()); |
1446 | __s.imbue(__os.getloc()); |
1447 | __s.precision(__os.precision()); |
1448 | __s << '(' << __x.real() << ',' << __x.imag() << ')'; |
1449 | return __os << __s.str(); |
1450 | } |
1451 | |
1452 | #if _LIBCPP_STD_VER > 11 |
1453 | // Literal suffix for complex number literals [complex.literals] |
1454 | inline namespace literals |
1455 | { |
1456 | inline namespace complex_literals |
1457 | { |
1458 | constexpr complex<long double> operator""il (long double __im) |
1459 | { |
1460 | return { 0.0l, __im }; |
1461 | } |
1462 | |
1463 | constexpr complex<long double> operator""il (unsigned long long __im) |
1464 | { |
1465 | return { 0.0l, static_cast<long double>(__im) }; |
1466 | } |
1467 | |
1468 | |
1469 | constexpr complex<double> operator""i (long double __im) |
1470 | { |
1471 | return { 0.0, static_cast<double>(__im) }; |
1472 | } |
1473 | |
1474 | constexpr complex<double> operator""i (unsigned long long __im) |
1475 | { |
1476 | return { 0.0, static_cast<double>(__im) }; |
1477 | } |
1478 | |
1479 | |
1480 | constexpr complex<float> operator""if (long double __im) |
1481 | { |
1482 | return { 0.0f, static_cast<float>(__im) }; |
1483 | } |
1484 | |
1485 | constexpr complex<float> operator""if (unsigned long long __im) |
1486 | { |
1487 | return { 0.0f, static_cast<float>(__im) }; |
1488 | } |
1489 | } |
1490 | } |
1491 | #endif |
1492 | |
1493 | _LIBCPP_END_NAMESPACE_STD |
1494 | |
1495 | #endif // _LIBCPP_COMPLEX |
1496 | |