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