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