xref: /openbsd-src/gnu/llvm/libcxx/include/complex (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_COMPLEX
1146035553Spatrick#define _LIBCPP_COMPLEX
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    complex synopsis
1546035553Spatrick
1646035553Spatricknamespace std
1746035553Spatrick{
1846035553Spatrick
1946035553Spatricktemplate<class T>
2046035553Spatrickclass complex
2146035553Spatrick{
2246035553Spatrickpublic:
2346035553Spatrick    typedef T value_type;
2446035553Spatrick
2546035553Spatrick    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
2646035553Spatrick    complex(const complex&);  // constexpr in C++14
2746035553Spatrick    template<class X> complex(const complex<X>&);  // constexpr in C++14
2846035553Spatrick
2946035553Spatrick    T real() const; // constexpr in C++14
3046035553Spatrick    T imag() const; // constexpr in C++14
3146035553Spatrick
32*4bdff4beSrobert    void real(T); // constexpr in C++20
33*4bdff4beSrobert    void imag(T); // constexpr in C++20
3446035553Spatrick
35*4bdff4beSrobert    complex<T>& operator= (const T&); // constexpr in C++20
36*4bdff4beSrobert    complex<T>& operator+=(const T&); // constexpr in C++20
37*4bdff4beSrobert    complex<T>& operator-=(const T&); // constexpr in C++20
38*4bdff4beSrobert    complex<T>& operator*=(const T&); // constexpr in C++20
39*4bdff4beSrobert    complex<T>& operator/=(const T&); // constexpr in C++20
4046035553Spatrick
41*4bdff4beSrobert    complex& operator=(const complex&); // constexpr in C++20
42*4bdff4beSrobert    template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20
43*4bdff4beSrobert    template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20
44*4bdff4beSrobert    template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20
45*4bdff4beSrobert    template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20
46*4bdff4beSrobert    template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++20
4746035553Spatrick};
4846035553Spatrick
4946035553Spatricktemplate<>
5046035553Spatrickclass complex<float>
5146035553Spatrick{
5246035553Spatrickpublic:
5346035553Spatrick    typedef float value_type;
5446035553Spatrick
5546035553Spatrick    constexpr complex(float re = 0.0f, float im = 0.0f);
5646035553Spatrick    explicit constexpr complex(const complex<double>&);
5746035553Spatrick    explicit constexpr complex(const complex<long double>&);
5846035553Spatrick
5946035553Spatrick    constexpr float real() const;
60*4bdff4beSrobert    void real(float); // constexpr in C++20
6146035553Spatrick    constexpr float imag() const;
62*4bdff4beSrobert    void imag(float); // constexpr in C++20
6346035553Spatrick
64*4bdff4beSrobert    complex<float>& operator= (float); // constexpr in C++20
65*4bdff4beSrobert    complex<float>& operator+=(float); // constexpr in C++20
66*4bdff4beSrobert    complex<float>& operator-=(float); // constexpr in C++20
67*4bdff4beSrobert    complex<float>& operator*=(float); // constexpr in C++20
68*4bdff4beSrobert    complex<float>& operator/=(float); // constexpr in C++20
6946035553Spatrick
70*4bdff4beSrobert    complex<float>& operator=(const complex<float>&); // constexpr in C++20
71*4bdff4beSrobert    template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20
72*4bdff4beSrobert    template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20
73*4bdff4beSrobert    template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20
74*4bdff4beSrobert    template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20
75*4bdff4beSrobert    template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++20
7646035553Spatrick};
7746035553Spatrick
7846035553Spatricktemplate<>
7946035553Spatrickclass complex<double>
8046035553Spatrick{
8146035553Spatrickpublic:
8246035553Spatrick    typedef double value_type;
8346035553Spatrick
8446035553Spatrick    constexpr complex(double re = 0.0, double im = 0.0);
8546035553Spatrick    constexpr complex(const complex<float>&);
8646035553Spatrick    explicit constexpr complex(const complex<long double>&);
8746035553Spatrick
8846035553Spatrick    constexpr double real() const;
89*4bdff4beSrobert    void real(double); // constexpr in C++20
9046035553Spatrick    constexpr double imag() const;
91*4bdff4beSrobert    void imag(double); // constexpr in C++20
9246035553Spatrick
93*4bdff4beSrobert    complex<double>& operator= (double); // constexpr in C++20
94*4bdff4beSrobert    complex<double>& operator+=(double); // constexpr in C++20
95*4bdff4beSrobert    complex<double>& operator-=(double); // constexpr in C++20
96*4bdff4beSrobert    complex<double>& operator*=(double); // constexpr in C++20
97*4bdff4beSrobert    complex<double>& operator/=(double); // constexpr in C++20
98*4bdff4beSrobert    complex<double>& operator=(const complex<double>&); // constexpr in C++20
9946035553Spatrick
100*4bdff4beSrobert    template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20
101*4bdff4beSrobert    template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20
102*4bdff4beSrobert    template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20
103*4bdff4beSrobert    template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20
104*4bdff4beSrobert    template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20
10546035553Spatrick};
10646035553Spatrick
10746035553Spatricktemplate<>
10846035553Spatrickclass complex<long double>
10946035553Spatrick{
11046035553Spatrickpublic:
11146035553Spatrick    typedef long double value_type;
11246035553Spatrick
11346035553Spatrick    constexpr complex(long double re = 0.0L, long double im = 0.0L);
11446035553Spatrick    constexpr complex(const complex<float>&);
11546035553Spatrick    constexpr complex(const complex<double>&);
11646035553Spatrick
11746035553Spatrick    constexpr long double real() const;
118*4bdff4beSrobert    void real(long double); // constexpr in C++20
11946035553Spatrick    constexpr long double imag() const;
120*4bdff4beSrobert    void imag(long double); // constexpr in C++20
12146035553Spatrick
122*4bdff4beSrobert    complex<long double>& operator=(const complex<long double>&); // constexpr in C++20
123*4bdff4beSrobert    complex<long double>& operator= (long double); // constexpr in C++20
124*4bdff4beSrobert    complex<long double>& operator+=(long double); // constexpr in C++20
125*4bdff4beSrobert    complex<long double>& operator-=(long double); // constexpr in C++20
126*4bdff4beSrobert    complex<long double>& operator*=(long double); // constexpr in C++20
127*4bdff4beSrobert    complex<long double>& operator/=(long double); // constexpr in C++20
12846035553Spatrick
129*4bdff4beSrobert    template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20
130*4bdff4beSrobert    template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20
131*4bdff4beSrobert    template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20
132*4bdff4beSrobert    template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20
133*4bdff4beSrobert    template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20
13446035553Spatrick};
13546035553Spatrick
13646035553Spatrick// 26.3.6 operators:
137*4bdff4beSroberttemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20
138*4bdff4beSroberttemplate<class T> complex<T> operator+(const complex<T>&, const T&);          // constexpr in C++20
139*4bdff4beSroberttemplate<class T> complex<T> operator+(const T&, const complex<T>&);          // constexpr in C++20
140*4bdff4beSroberttemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20
141*4bdff4beSroberttemplate<class T> complex<T> operator-(const complex<T>&, const T&);          // constexpr in C++20
142*4bdff4beSroberttemplate<class T> complex<T> operator-(const T&, const complex<T>&);          // constexpr in C++20
143*4bdff4beSroberttemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20
144*4bdff4beSroberttemplate<class T> complex<T> operator*(const complex<T>&, const T&);          // constexpr in C++20
145*4bdff4beSroberttemplate<class T> complex<T> operator*(const T&, const complex<T>&);          // constexpr in C++20
146*4bdff4beSroberttemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20
147*4bdff4beSroberttemplate<class T> complex<T> operator/(const complex<T>&, const T&);          // constexpr in C++20
148*4bdff4beSroberttemplate<class T> complex<T> operator/(const T&, const complex<T>&);          // constexpr in C++20
149*4bdff4beSroberttemplate<class T> complex<T> operator+(const complex<T>&);                    // constexpr in C++20
150*4bdff4beSroberttemplate<class T> complex<T> operator-(const complex<T>&);                    // constexpr in C++20
15146035553Spatricktemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
15246035553Spatricktemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
15346035553Spatricktemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
15446035553Spatricktemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
15546035553Spatricktemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
15646035553Spatricktemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
15746035553Spatrick
15846035553Spatricktemplate<class T, class charT, class traits>
15946035553Spatrick  basic_istream<charT, traits>&
16046035553Spatrick  operator>>(basic_istream<charT, traits>&, complex<T>&);
16146035553Spatricktemplate<class T, class charT, class traits>
16246035553Spatrick  basic_ostream<charT, traits>&
16346035553Spatrick  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
16446035553Spatrick
16546035553Spatrick// 26.3.7 values:
16646035553Spatrick
16746035553Spatricktemplate<class T>              T real(const complex<T>&); // constexpr in C++14
16846035553Spatrick                     long double real(long double);       // constexpr in C++14
16946035553Spatrick                          double real(double);            // constexpr in C++14
17046035553Spatricktemplate<Integral T>      double real(T);                 // constexpr in C++14
17146035553Spatrick                          float  real(float);             // constexpr in C++14
17246035553Spatrick
17346035553Spatricktemplate<class T>              T imag(const complex<T>&); // constexpr in C++14
17446035553Spatrick                     long double imag(long double);       // constexpr in C++14
17546035553Spatrick                          double imag(double);            // constexpr in C++14
17646035553Spatricktemplate<Integral T>      double imag(T);                 // constexpr in C++14
17746035553Spatrick                          float  imag(float);             // constexpr in C++14
17846035553Spatrick
17946035553Spatricktemplate<class T> T abs(const complex<T>&);
18046035553Spatrick
18146035553Spatricktemplate<class T>              T arg(const complex<T>&);
18246035553Spatrick                     long double arg(long double);
18346035553Spatrick                          double arg(double);
18446035553Spatricktemplate<Integral T>      double arg(T);
18546035553Spatrick                          float  arg(float);
18646035553Spatrick
187*4bdff4beSroberttemplate<class T>              T norm(const complex<T>&); // constexpr in C++20
188*4bdff4beSrobert                     long double norm(long double);       // constexpr in C++20
189*4bdff4beSrobert                          double norm(double);            // constexpr in C++20
190*4bdff4beSroberttemplate<Integral T>      double norm(T);                 // constexpr in C++20
191*4bdff4beSrobert                          float  norm(float);             // constexpr in C++20
19246035553Spatrick
193*4bdff4beSroberttemplate<class T>      complex<T>           conj(const complex<T>&); // constexpr in C++20
194*4bdff4beSrobert                       complex<long double> conj(long double);       // constexpr in C++20
195*4bdff4beSrobert                       complex<double>      conj(double);            // constexpr in C++20
196*4bdff4beSroberttemplate<Integral T>   complex<double>      conj(T);                 // constexpr in C++20
197*4bdff4beSrobert                       complex<float>       conj(float);             // constexpr in C++20
19846035553Spatrick
19946035553Spatricktemplate<class T>    complex<T>           proj(const complex<T>&);
20046035553Spatrick                     complex<long double> proj(long double);
20146035553Spatrick                     complex<double>      proj(double);
20246035553Spatricktemplate<Integral T> complex<double>      proj(T);
20346035553Spatrick                     complex<float>       proj(float);
20446035553Spatrick
20546035553Spatricktemplate<class T> complex<T> polar(const T&, const T& = T());
20646035553Spatrick
20746035553Spatrick// 26.3.8 transcendentals:
20846035553Spatricktemplate<class T> complex<T> acos(const complex<T>&);
20946035553Spatricktemplate<class T> complex<T> asin(const complex<T>&);
21046035553Spatricktemplate<class T> complex<T> atan(const complex<T>&);
21146035553Spatricktemplate<class T> complex<T> acosh(const complex<T>&);
21246035553Spatricktemplate<class T> complex<T> asinh(const complex<T>&);
21346035553Spatricktemplate<class T> complex<T> atanh(const complex<T>&);
21446035553Spatricktemplate<class T> complex<T> cos (const complex<T>&);
21546035553Spatricktemplate<class T> complex<T> cosh (const complex<T>&);
21646035553Spatricktemplate<class T> complex<T> exp (const complex<T>&);
21746035553Spatricktemplate<class T> complex<T> log (const complex<T>&);
21846035553Spatricktemplate<class T> complex<T> log10(const complex<T>&);
21946035553Spatrick
22046035553Spatricktemplate<class T> complex<T> pow(const complex<T>&, const T&);
22146035553Spatricktemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);
22246035553Spatricktemplate<class T> complex<T> pow(const T&, const complex<T>&);
22346035553Spatrick
22446035553Spatricktemplate<class T> complex<T> sin (const complex<T>&);
22546035553Spatricktemplate<class T> complex<T> sinh (const complex<T>&);
22646035553Spatricktemplate<class T> complex<T> sqrt (const complex<T>&);
22746035553Spatricktemplate<class T> complex<T> tan (const complex<T>&);
22846035553Spatricktemplate<class T> complex<T> tanh (const complex<T>&);
22946035553Spatrick
23046035553Spatrick}  // std
23146035553Spatrick
23246035553Spatrick*/
23346035553Spatrick
234*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
23546035553Spatrick#include <__config>
23646035553Spatrick#include <cmath>
237037e7968Spatrick#include <iosfwd>
23876d0caaeSpatrick#include <stdexcept>
23976d0caaeSpatrick#include <type_traits>
24046035553Spatrick#include <version>
24146035553Spatrick
24276d0caaeSpatrick#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
24376d0caaeSpatrick#   include <sstream> // for std::basic_ostringstream
24476d0caaeSpatrick#endif
24576d0caaeSpatrick
24646035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24746035553Spatrick#  pragma GCC system_header
24846035553Spatrick#endif
24946035553Spatrick
25046035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
25146035553Spatrick
25246035553Spatricktemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
25346035553Spatrick
254*4bdff4beSroberttemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
255*4bdff4beSroberttemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
25646035553Spatrick
25746035553Spatricktemplate<class _Tp>
25846035553Spatrickclass _LIBCPP_TEMPLATE_VIS complex
25946035553Spatrick{
26046035553Spatrickpublic:
26146035553Spatrick    typedef _Tp value_type;
26246035553Spatrickprivate:
26346035553Spatrick    value_type __re_;
26446035553Spatrick    value_type __im_;
26546035553Spatrickpublic:
266*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
26746035553Spatrick    complex(const value_type& __re = value_type(), const value_type& __im = value_type())
26846035553Spatrick        : __re_(__re), __im_(__im) {}
269*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
27046035553Spatrick    complex(const complex<_Xp>& __c)
27146035553Spatrick        : __re_(__c.real()), __im_(__c.imag()) {}
27246035553Spatrick
273*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const {return __re_;}
274*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const {return __im_;}
27546035553Spatrick
276*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
277*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
27846035553Spatrick
279*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const value_type& __re)
28046035553Spatrick        {__re_ = __re; __im_ = value_type(); return *this;}
281*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
282*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
283*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
284*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
28546035553Spatrick
286*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
28746035553Spatrick        {
28846035553Spatrick            __re_ = __c.real();
28946035553Spatrick            __im_ = __c.imag();
29046035553Spatrick            return *this;
29146035553Spatrick        }
292*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
29346035553Spatrick        {
29446035553Spatrick            __re_ += __c.real();
29546035553Spatrick            __im_ += __c.imag();
29646035553Spatrick            return *this;
29746035553Spatrick        }
298*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
29946035553Spatrick        {
30046035553Spatrick            __re_ -= __c.real();
30146035553Spatrick            __im_ -= __c.imag();
30246035553Spatrick            return *this;
30346035553Spatrick        }
304*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
30546035553Spatrick        {
30646035553Spatrick            *this = *this * complex(__c.real(), __c.imag());
30746035553Spatrick            return *this;
30846035553Spatrick        }
309*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
31046035553Spatrick        {
31146035553Spatrick            *this = *this / complex(__c.real(), __c.imag());
31246035553Spatrick            return *this;
31346035553Spatrick        }
31446035553Spatrick};
31546035553Spatrick
31646035553Spatricktemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>;
31746035553Spatricktemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
31846035553Spatrick
31946035553Spatricktemplate<>
32046035553Spatrickclass _LIBCPP_TEMPLATE_VIS complex<float>
32146035553Spatrick{
32246035553Spatrick    float __re_;
32346035553Spatrick    float __im_;
32446035553Spatrickpublic:
32546035553Spatrick    typedef float value_type;
32646035553Spatrick
32746035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
32846035553Spatrick        : __re_(__re), __im_(__im) {}
32946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
33046035553Spatrick    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
33146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
33246035553Spatrick    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
33346035553Spatrick
33446035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
33546035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
33646035553Spatrick
337*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
338*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
33946035553Spatrick
340*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (float __re)
34146035553Spatrick        {__re_ = __re; __im_ = value_type(); return *this;}
342*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) {__re_ += __re; return *this;}
343*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) {__re_ -= __re; return *this;}
344*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
345*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
34646035553Spatrick
347*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
34846035553Spatrick        {
34946035553Spatrick            __re_ = __c.real();
35046035553Spatrick            __im_ = __c.imag();
35146035553Spatrick            return *this;
35246035553Spatrick        }
353*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
35446035553Spatrick        {
35546035553Spatrick            __re_ += __c.real();
35646035553Spatrick            __im_ += __c.imag();
35746035553Spatrick            return *this;
35846035553Spatrick        }
359*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
36046035553Spatrick        {
36146035553Spatrick            __re_ -= __c.real();
36246035553Spatrick            __im_ -= __c.imag();
36346035553Spatrick            return *this;
36446035553Spatrick        }
365*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
36646035553Spatrick        {
36746035553Spatrick            *this = *this * complex(__c.real(), __c.imag());
36846035553Spatrick            return *this;
36946035553Spatrick        }
370*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
37146035553Spatrick        {
37246035553Spatrick            *this = *this / complex(__c.real(), __c.imag());
37346035553Spatrick            return *this;
37446035553Spatrick        }
37546035553Spatrick};
37646035553Spatrick
37746035553Spatricktemplate<>
37846035553Spatrickclass _LIBCPP_TEMPLATE_VIS complex<double>
37946035553Spatrick{
38046035553Spatrick    double __re_;
38146035553Spatrick    double __im_;
38246035553Spatrickpublic:
38346035553Spatrick    typedef double value_type;
38446035553Spatrick
38546035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
38646035553Spatrick        : __re_(__re), __im_(__im) {}
38746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
38846035553Spatrick    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
38946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
39046035553Spatrick    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
39146035553Spatrick
39246035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
39346035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
39446035553Spatrick
395*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
396*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
39746035553Spatrick
398*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (double __re)
39946035553Spatrick        {__re_ = __re; __im_ = value_type(); return *this;}
400*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) {__re_ += __re; return *this;}
401*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) {__re_ -= __re; return *this;}
402*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
403*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
40446035553Spatrick
405*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
40646035553Spatrick        {
40746035553Spatrick            __re_ = __c.real();
40846035553Spatrick            __im_ = __c.imag();
40946035553Spatrick            return *this;
41046035553Spatrick        }
411*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
41246035553Spatrick        {
41346035553Spatrick            __re_ += __c.real();
41446035553Spatrick            __im_ += __c.imag();
41546035553Spatrick            return *this;
41646035553Spatrick        }
417*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
41846035553Spatrick        {
41946035553Spatrick            __re_ -= __c.real();
42046035553Spatrick            __im_ -= __c.imag();
42146035553Spatrick            return *this;
42246035553Spatrick        }
423*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
42446035553Spatrick        {
42546035553Spatrick            *this = *this * complex(__c.real(), __c.imag());
42646035553Spatrick            return *this;
42746035553Spatrick        }
428*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
42946035553Spatrick        {
43046035553Spatrick            *this = *this / complex(__c.real(), __c.imag());
43146035553Spatrick            return *this;
43246035553Spatrick        }
43346035553Spatrick};
43446035553Spatrick
43546035553Spatricktemplate<>
43646035553Spatrickclass _LIBCPP_TEMPLATE_VIS complex<long double>
43746035553Spatrick{
43846035553Spatrick    long double __re_;
43946035553Spatrick    long double __im_;
44046035553Spatrickpublic:
44146035553Spatrick    typedef long double value_type;
44246035553Spatrick
44346035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
44446035553Spatrick        : __re_(__re), __im_(__im) {}
44546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
44646035553Spatrick    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
44746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
44846035553Spatrick    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
44946035553Spatrick
45046035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
45146035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
45246035553Spatrick
453*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
454*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
45546035553Spatrick
456*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (long double __re)
45746035553Spatrick        {__re_ = __re; __im_ = value_type(); return *this;}
458*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) {__re_ += __re; return *this;}
459*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) {__re_ -= __re; return *this;}
460*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
461*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
46246035553Spatrick
463*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
46446035553Spatrick        {
46546035553Spatrick            __re_ = __c.real();
46646035553Spatrick            __im_ = __c.imag();
46746035553Spatrick            return *this;
46846035553Spatrick        }
469*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
47046035553Spatrick        {
47146035553Spatrick            __re_ += __c.real();
47246035553Spatrick            __im_ += __c.imag();
47346035553Spatrick            return *this;
47446035553Spatrick        }
475*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
47646035553Spatrick        {
47746035553Spatrick            __re_ -= __c.real();
47846035553Spatrick            __im_ -= __c.imag();
47946035553Spatrick            return *this;
48046035553Spatrick        }
481*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
48246035553Spatrick        {
48346035553Spatrick            *this = *this * complex(__c.real(), __c.imag());
48446035553Spatrick            return *this;
48546035553Spatrick        }
486*4bdff4beSrobert    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
48746035553Spatrick        {
48846035553Spatrick            *this = *this / complex(__c.real(), __c.imag());
48946035553Spatrick            return *this;
49046035553Spatrick        }
49146035553Spatrick};
49246035553Spatrick
49346035553Spatrickinline
49446035553Spatrick_LIBCPP_CONSTEXPR
49546035553Spatrickcomplex<float>::complex(const complex<double>& __c)
49646035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
49746035553Spatrick
49846035553Spatrickinline
49946035553Spatrick_LIBCPP_CONSTEXPR
50046035553Spatrickcomplex<float>::complex(const complex<long double>& __c)
50146035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
50246035553Spatrick
50346035553Spatrickinline
50446035553Spatrick_LIBCPP_CONSTEXPR
50546035553Spatrickcomplex<double>::complex(const complex<float>& __c)
50646035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
50746035553Spatrick
50846035553Spatrickinline
50946035553Spatrick_LIBCPP_CONSTEXPR
51046035553Spatrickcomplex<double>::complex(const complex<long double>& __c)
51146035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
51246035553Spatrick
51346035553Spatrickinline
51446035553Spatrick_LIBCPP_CONSTEXPR
51546035553Spatrickcomplex<long double>::complex(const complex<float>& __c)
51646035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
51746035553Spatrick
51846035553Spatrickinline
51946035553Spatrick_LIBCPP_CONSTEXPR
52046035553Spatrickcomplex<long double>::complex(const complex<double>& __c)
52146035553Spatrick    : __re_(__c.real()), __im_(__c.imag()) {}
52246035553Spatrick
52346035553Spatrick// 26.3.6 operators:
52446035553Spatrick
52546035553Spatricktemplate<class _Tp>
526*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
52746035553Spatrickcomplex<_Tp>
52846035553Spatrickoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
52946035553Spatrick{
53046035553Spatrick    complex<_Tp> __t(__x);
53146035553Spatrick    __t += __y;
53246035553Spatrick    return __t;
53346035553Spatrick}
53446035553Spatrick
53546035553Spatricktemplate<class _Tp>
536*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
53746035553Spatrickcomplex<_Tp>
53846035553Spatrickoperator+(const complex<_Tp>& __x, const _Tp& __y)
53946035553Spatrick{
54046035553Spatrick    complex<_Tp> __t(__x);
54146035553Spatrick    __t += __y;
54246035553Spatrick    return __t;
54346035553Spatrick}
54446035553Spatrick
54546035553Spatricktemplate<class _Tp>
546*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
54746035553Spatrickcomplex<_Tp>
54846035553Spatrickoperator+(const _Tp& __x, const complex<_Tp>& __y)
54946035553Spatrick{
55046035553Spatrick    complex<_Tp> __t(__y);
55146035553Spatrick    __t += __x;
55246035553Spatrick    return __t;
55346035553Spatrick}
55446035553Spatrick
55546035553Spatricktemplate<class _Tp>
556*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
55746035553Spatrickcomplex<_Tp>
55846035553Spatrickoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
55946035553Spatrick{
56046035553Spatrick    complex<_Tp> __t(__x);
56146035553Spatrick    __t -= __y;
56246035553Spatrick    return __t;
56346035553Spatrick}
56446035553Spatrick
56546035553Spatricktemplate<class _Tp>
566*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
56746035553Spatrickcomplex<_Tp>
56846035553Spatrickoperator-(const complex<_Tp>& __x, const _Tp& __y)
56946035553Spatrick{
57046035553Spatrick    complex<_Tp> __t(__x);
57146035553Spatrick    __t -= __y;
57246035553Spatrick    return __t;
57346035553Spatrick}
57446035553Spatrick
57546035553Spatricktemplate<class _Tp>
576*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
57746035553Spatrickcomplex<_Tp>
57846035553Spatrickoperator-(const _Tp& __x, const complex<_Tp>& __y)
57946035553Spatrick{
58046035553Spatrick    complex<_Tp> __t(-__y);
58146035553Spatrick    __t += __x;
58246035553Spatrick    return __t;
58346035553Spatrick}
58446035553Spatrick
58546035553Spatricktemplate<class _Tp>
586*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
58746035553Spatrickoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
58846035553Spatrick{
58946035553Spatrick    _Tp __a = __z.real();
59046035553Spatrick    _Tp __b = __z.imag();
59146035553Spatrick    _Tp __c = __w.real();
59246035553Spatrick    _Tp __d = __w.imag();
593*4bdff4beSrobert
594*4bdff4beSrobert    // Avoid floating point operations that are invalid during constant evaluation
595*4bdff4beSrobert    if (__libcpp_is_constant_evaluated()) {
596*4bdff4beSrobert        bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
597*4bdff4beSrobert        bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
598*4bdff4beSrobert        bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
599*4bdff4beSrobert        bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
600*4bdff4beSrobert        bool __z_nan = !__z_inf && (
601*4bdff4beSrobert            (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
602*4bdff4beSrobert            || (std::__constexpr_isnan(__a) && __b == _Tp(0))
603*4bdff4beSrobert            || (__a == _Tp(0) && std::__constexpr_isnan(__b))
604*4bdff4beSrobert        );
605*4bdff4beSrobert        bool __w_nan = !__w_inf && (
606*4bdff4beSrobert            (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
607*4bdff4beSrobert            || (std::__constexpr_isnan(__c) && __d == _Tp(0))
608*4bdff4beSrobert            || (__c == _Tp(0) && std::__constexpr_isnan(__d))
609*4bdff4beSrobert        );
610*4bdff4beSrobert        if (__z_nan || __w_nan) {
611*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
612*4bdff4beSrobert        }
613*4bdff4beSrobert        if (__z_inf || __w_inf) {
614*4bdff4beSrobert            if (__z_zero || __w_zero) {
615*4bdff4beSrobert                return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
616*4bdff4beSrobert            }
617*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
618*4bdff4beSrobert        }
619*4bdff4beSrobert        bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
620*4bdff4beSrobert        bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
621*4bdff4beSrobert        if (__z_nonzero_nan || __w_nonzero_nan) {
622*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
623*4bdff4beSrobert        }
624*4bdff4beSrobert    }
625*4bdff4beSrobert
62646035553Spatrick    _Tp __ac = __a * __c;
62746035553Spatrick    _Tp __bd = __b * __d;
62846035553Spatrick    _Tp __ad = __a * __d;
62946035553Spatrick    _Tp __bc = __b * __c;
63046035553Spatrick    _Tp __x = __ac - __bd;
63146035553Spatrick    _Tp __y = __ad + __bc;
632*4bdff4beSrobert    if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
63346035553Spatrick    {
63446035553Spatrick        bool __recalc = false;
635*4bdff4beSrobert        if (std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b))
63646035553Spatrick        {
637*4bdff4beSrobert            __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
638*4bdff4beSrobert            __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
639*4bdff4beSrobert            if (std::__constexpr_isnan(__c))
640*4bdff4beSrobert                __c = std::__constexpr_copysign(_Tp(0), __c);
641*4bdff4beSrobert            if (std::__constexpr_isnan(__d))
642*4bdff4beSrobert                __d = std::__constexpr_copysign(_Tp(0), __d);
64346035553Spatrick            __recalc = true;
64446035553Spatrick        }
645*4bdff4beSrobert        if (std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d))
64646035553Spatrick        {
647*4bdff4beSrobert            __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
648*4bdff4beSrobert            __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
649*4bdff4beSrobert            if (std::__constexpr_isnan(__a))
650*4bdff4beSrobert                __a = std::__constexpr_copysign(_Tp(0), __a);
651*4bdff4beSrobert            if (std::__constexpr_isnan(__b))
652*4bdff4beSrobert                __b = std::__constexpr_copysign(_Tp(0), __b);
65346035553Spatrick            __recalc = true;
65446035553Spatrick        }
655*4bdff4beSrobert        if (!__recalc && (std::__constexpr_isinf(__ac) || std::__constexpr_isinf(__bd) ||
656*4bdff4beSrobert                          std::__constexpr_isinf(__ad) || std::__constexpr_isinf(__bc)))
65746035553Spatrick        {
658*4bdff4beSrobert            if (std::__constexpr_isnan(__a))
659*4bdff4beSrobert                __a = std::__constexpr_copysign(_Tp(0), __a);
660*4bdff4beSrobert            if (std::__constexpr_isnan(__b))
661*4bdff4beSrobert                __b = std::__constexpr_copysign(_Tp(0), __b);
662*4bdff4beSrobert            if (std::__constexpr_isnan(__c))
663*4bdff4beSrobert                __c = std::__constexpr_copysign(_Tp(0), __c);
664*4bdff4beSrobert            if (std::__constexpr_isnan(__d))
665*4bdff4beSrobert                __d = std::__constexpr_copysign(_Tp(0), __d);
66646035553Spatrick            __recalc = true;
66746035553Spatrick        }
66846035553Spatrick        if (__recalc)
66946035553Spatrick        {
67046035553Spatrick            __x = _Tp(INFINITY) * (__a * __c - __b * __d);
67146035553Spatrick            __y = _Tp(INFINITY) * (__a * __d + __b * __c);
67246035553Spatrick        }
67346035553Spatrick    }
67446035553Spatrick    return complex<_Tp>(__x, __y);
67546035553Spatrick}
67646035553Spatrick
67746035553Spatricktemplate<class _Tp>
678*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
67946035553Spatrickcomplex<_Tp>
68046035553Spatrickoperator*(const complex<_Tp>& __x, const _Tp& __y)
68146035553Spatrick{
68246035553Spatrick    complex<_Tp> __t(__x);
68346035553Spatrick    __t *= __y;
68446035553Spatrick    return __t;
68546035553Spatrick}
68646035553Spatrick
68746035553Spatricktemplate<class _Tp>
688*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
68946035553Spatrickcomplex<_Tp>
69046035553Spatrickoperator*(const _Tp& __x, const complex<_Tp>& __y)
69146035553Spatrick{
69246035553Spatrick    complex<_Tp> __t(__y);
69346035553Spatrick    __t *= __x;
69446035553Spatrick    return __t;
69546035553Spatrick}
69646035553Spatrick
69746035553Spatricktemplate<class _Tp>
698*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
69946035553Spatrickoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
70046035553Spatrick{
70146035553Spatrick    int __ilogbw = 0;
70246035553Spatrick    _Tp __a = __z.real();
70346035553Spatrick    _Tp __b = __z.imag();
70446035553Spatrick    _Tp __c = __w.real();
70546035553Spatrick    _Tp __d = __w.imag();
706*4bdff4beSrobert    _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d)));
707*4bdff4beSrobert    if (std::__constexpr_isfinite(__logbw))
70846035553Spatrick    {
70946035553Spatrick        __ilogbw = static_cast<int>(__logbw);
710*4bdff4beSrobert        __c = std::__constexpr_scalbn(__c, -__ilogbw);
711*4bdff4beSrobert        __d = std::__constexpr_scalbn(__d, -__ilogbw);
71246035553Spatrick    }
713*4bdff4beSrobert
714*4bdff4beSrobert    // Avoid floating point operations that are invalid during constant evaluation
715*4bdff4beSrobert    if (__libcpp_is_constant_evaluated()) {
716*4bdff4beSrobert        bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
717*4bdff4beSrobert        bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
718*4bdff4beSrobert        bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
719*4bdff4beSrobert        bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
720*4bdff4beSrobert        bool __z_nan = !__z_inf && (
721*4bdff4beSrobert            (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
722*4bdff4beSrobert            || (std::__constexpr_isnan(__a) && __b == _Tp(0))
723*4bdff4beSrobert            || (__a == _Tp(0) && std::__constexpr_isnan(__b))
724*4bdff4beSrobert        );
725*4bdff4beSrobert        bool __w_nan = !__w_inf && (
726*4bdff4beSrobert            (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
727*4bdff4beSrobert            || (std::__constexpr_isnan(__c) && __d == _Tp(0))
728*4bdff4beSrobert            || (__c == _Tp(0) && std::__constexpr_isnan(__d))
729*4bdff4beSrobert        );
730*4bdff4beSrobert        if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) {
731*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
732*4bdff4beSrobert        }
733*4bdff4beSrobert        bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
734*4bdff4beSrobert        bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
735*4bdff4beSrobert        if (__z_nonzero_nan || __w_nonzero_nan) {
736*4bdff4beSrobert            if (__w_zero) {
737*4bdff4beSrobert                return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
738*4bdff4beSrobert            }
739*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
740*4bdff4beSrobert        }
741*4bdff4beSrobert        if (__w_inf) {
742*4bdff4beSrobert            return complex<_Tp>(_Tp(0), _Tp(0));
743*4bdff4beSrobert        }
744*4bdff4beSrobert        if (__z_inf) {
745*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
746*4bdff4beSrobert        }
747*4bdff4beSrobert        if (__w_zero) {
748*4bdff4beSrobert            if (__z_zero) {
749*4bdff4beSrobert                return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
750*4bdff4beSrobert            }
751*4bdff4beSrobert            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
752*4bdff4beSrobert        }
753*4bdff4beSrobert    }
754*4bdff4beSrobert
75546035553Spatrick    _Tp __denom = __c * __c + __d * __d;
756*4bdff4beSrobert    _Tp __x = std::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
757*4bdff4beSrobert    _Tp __y = std::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
758*4bdff4beSrobert    if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
75946035553Spatrick    {
760*4bdff4beSrobert        if ((__denom == _Tp(0)) && (!std::__constexpr_isnan(__a) || !std::__constexpr_isnan(__b)))
76146035553Spatrick        {
762*4bdff4beSrobert            __x = std::__constexpr_copysign(_Tp(INFINITY), __c) * __a;
763*4bdff4beSrobert            __y = std::__constexpr_copysign(_Tp(INFINITY), __c) * __b;
764*4bdff4beSrobert        } else if ((std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) && std::__constexpr_isfinite(__c) &&
765*4bdff4beSrobert                   std::__constexpr_isfinite(__d)) {
766*4bdff4beSrobert            __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
767*4bdff4beSrobert            __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
76846035553Spatrick            __x = _Tp(INFINITY) * (__a * __c + __b * __d);
76946035553Spatrick            __y = _Tp(INFINITY) * (__b * __c - __a * __d);
770*4bdff4beSrobert        } else if (std::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && std::__constexpr_isfinite(__a) &&
771*4bdff4beSrobert                   std::__constexpr_isfinite(__b)) {
772*4bdff4beSrobert            __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
773*4bdff4beSrobert            __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
77446035553Spatrick            __x = _Tp(0) * (__a * __c + __b * __d);
77546035553Spatrick            __y = _Tp(0) * (__b * __c - __a * __d);
77646035553Spatrick        }
77746035553Spatrick    }
77846035553Spatrick    return complex<_Tp>(__x, __y);
77946035553Spatrick}
78046035553Spatrick
78146035553Spatricktemplate<class _Tp>
782*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
78346035553Spatrickcomplex<_Tp>
78446035553Spatrickoperator/(const complex<_Tp>& __x, const _Tp& __y)
78546035553Spatrick{
78646035553Spatrick    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
78746035553Spatrick}
78846035553Spatrick
78946035553Spatricktemplate<class _Tp>
790*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
79146035553Spatrickcomplex<_Tp>
79246035553Spatrickoperator/(const _Tp& __x, const complex<_Tp>& __y)
79346035553Spatrick{
79446035553Spatrick    complex<_Tp> __t(__x);
79546035553Spatrick    __t /= __y;
79646035553Spatrick    return __t;
79746035553Spatrick}
79846035553Spatrick
79946035553Spatricktemplate<class _Tp>
800*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
80146035553Spatrickcomplex<_Tp>
80246035553Spatrickoperator+(const complex<_Tp>& __x)
80346035553Spatrick{
80446035553Spatrick    return __x;
80546035553Spatrick}
80646035553Spatrick
80746035553Spatricktemplate<class _Tp>
808*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
80946035553Spatrickcomplex<_Tp>
81046035553Spatrickoperator-(const complex<_Tp>& __x)
81146035553Spatrick{
81246035553Spatrick    return complex<_Tp>(-__x.real(), -__x.imag());
81346035553Spatrick}
81446035553Spatrick
81546035553Spatricktemplate<class _Tp>
816*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
81746035553Spatrickbool
81846035553Spatrickoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
81946035553Spatrick{
82046035553Spatrick    return __x.real() == __y.real() && __x.imag() == __y.imag();
82146035553Spatrick}
82246035553Spatrick
82346035553Spatricktemplate<class _Tp>
824*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
82546035553Spatrickbool
82646035553Spatrickoperator==(const complex<_Tp>& __x, const _Tp& __y)
82746035553Spatrick{
82846035553Spatrick    return __x.real() == __y && __x.imag() == 0;
82946035553Spatrick}
83046035553Spatrick
83146035553Spatricktemplate<class _Tp>
832*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
83346035553Spatrickbool
83446035553Spatrickoperator==(const _Tp& __x, const complex<_Tp>& __y)
83546035553Spatrick{
83646035553Spatrick    return __x == __y.real() && 0 == __y.imag();
83746035553Spatrick}
83846035553Spatrick
83946035553Spatricktemplate<class _Tp>
840*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
84146035553Spatrickbool
84246035553Spatrickoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
84346035553Spatrick{
84446035553Spatrick    return !(__x == __y);
84546035553Spatrick}
84646035553Spatrick
84746035553Spatricktemplate<class _Tp>
848*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
84946035553Spatrickbool
85046035553Spatrickoperator!=(const complex<_Tp>& __x, const _Tp& __y)
85146035553Spatrick{
85246035553Spatrick    return !(__x == __y);
85346035553Spatrick}
85446035553Spatrick
85546035553Spatricktemplate<class _Tp>
856*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
85746035553Spatrickbool
85846035553Spatrickoperator!=(const _Tp& __x, const complex<_Tp>& __y)
85946035553Spatrick{
86046035553Spatrick    return !(__x == __y);
86146035553Spatrick}
86246035553Spatrick
86346035553Spatrick// 26.3.7 values:
86446035553Spatrick
86546035553Spatricktemplate <class _Tp, bool = is_integral<_Tp>::value,
86646035553Spatrick                     bool = is_floating_point<_Tp>::value
86746035553Spatrick                     >
86846035553Spatrickstruct __libcpp_complex_overload_traits {};
86946035553Spatrick
87046035553Spatrick// Integral Types
87146035553Spatricktemplate <class _Tp>
87246035553Spatrickstruct __libcpp_complex_overload_traits<_Tp, true, false>
87346035553Spatrick{
87446035553Spatrick    typedef double _ValueType;
87546035553Spatrick    typedef complex<double> _ComplexType;
87646035553Spatrick};
87746035553Spatrick
87846035553Spatrick// Floating point types
87946035553Spatricktemplate <class _Tp>
88046035553Spatrickstruct __libcpp_complex_overload_traits<_Tp, false, true>
88146035553Spatrick{
88246035553Spatrick    typedef _Tp _ValueType;
88346035553Spatrick    typedef complex<_Tp> _ComplexType;
88446035553Spatrick};
88546035553Spatrick
88646035553Spatrick// real
88746035553Spatrick
88846035553Spatricktemplate<class _Tp>
889*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
89046035553Spatrick_Tp
89146035553Spatrickreal(const complex<_Tp>& __c)
89246035553Spatrick{
89346035553Spatrick    return __c.real();
89446035553Spatrick}
89546035553Spatrick
89646035553Spatricktemplate <class _Tp>
897*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
89846035553Spatricktypename __libcpp_complex_overload_traits<_Tp>::_ValueType
89946035553Spatrickreal(_Tp __re)
90046035553Spatrick{
90146035553Spatrick    return __re;
90246035553Spatrick}
90346035553Spatrick
90446035553Spatrick// imag
90546035553Spatrick
90646035553Spatricktemplate<class _Tp>
907*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
90846035553Spatrick_Tp
90946035553Spatrickimag(const complex<_Tp>& __c)
91046035553Spatrick{
91146035553Spatrick    return __c.imag();
91246035553Spatrick}
91346035553Spatrick
91446035553Spatricktemplate <class _Tp>
915*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
91646035553Spatricktypename __libcpp_complex_overload_traits<_Tp>::_ValueType
91746035553Spatrickimag(_Tp)
91846035553Spatrick{
91946035553Spatrick    return 0;
92046035553Spatrick}
92146035553Spatrick
92246035553Spatrick// abs
92346035553Spatrick
92446035553Spatricktemplate<class _Tp>
92546035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
92646035553Spatrick_Tp
92746035553Spatrickabs(const complex<_Tp>& __c)
92846035553Spatrick{
929*4bdff4beSrobert    return std::hypot(__c.real(), __c.imag());
93046035553Spatrick}
93146035553Spatrick
93246035553Spatrick// arg
93346035553Spatrick
93446035553Spatricktemplate<class _Tp>
93546035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
93646035553Spatrick_Tp
93746035553Spatrickarg(const complex<_Tp>& __c)
93846035553Spatrick{
939*4bdff4beSrobert    return std::atan2(__c.imag(), __c.real());
94046035553Spatrick}
94146035553Spatrick
94246035553Spatricktemplate <class _Tp>
94346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
94446035553Spatricktypename enable_if<
94546035553Spatrick    is_same<_Tp, long double>::value,
94646035553Spatrick    long double
94746035553Spatrick>::type
94846035553Spatrickarg(_Tp __re)
94946035553Spatrick{
950*4bdff4beSrobert    return std::atan2l(0.L, __re);
95146035553Spatrick}
95246035553Spatrick
95346035553Spatricktemplate<class _Tp>
95446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
95546035553Spatricktypename enable_if
95646035553Spatrick<
95746035553Spatrick    is_integral<_Tp>::value || is_same<_Tp, double>::value,
95846035553Spatrick    double
95946035553Spatrick>::type
96046035553Spatrickarg(_Tp __re)
96146035553Spatrick{
962*4bdff4beSrobert    return std::atan2(0., __re);
96346035553Spatrick}
96446035553Spatrick
96546035553Spatricktemplate <class _Tp>
96646035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
96746035553Spatricktypename enable_if<
96846035553Spatrick    is_same<_Tp, float>::value,
96946035553Spatrick    float
97046035553Spatrick>::type
97146035553Spatrickarg(_Tp __re)
97246035553Spatrick{
973*4bdff4beSrobert    return std::atan2f(0.F, __re);
97446035553Spatrick}
97546035553Spatrick
97646035553Spatrick// norm
97746035553Spatrick
97846035553Spatricktemplate<class _Tp>
979*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
98046035553Spatrick_Tp
98146035553Spatricknorm(const complex<_Tp>& __c)
98246035553Spatrick{
983*4bdff4beSrobert    if (std::__constexpr_isinf(__c.real()))
984*4bdff4beSrobert        return std::abs(__c.real());
985*4bdff4beSrobert    if (std::__constexpr_isinf(__c.imag()))
986*4bdff4beSrobert        return std::abs(__c.imag());
98746035553Spatrick    return __c.real() * __c.real() + __c.imag() * __c.imag();
98846035553Spatrick}
98946035553Spatrick
99046035553Spatricktemplate <class _Tp>
991*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
99246035553Spatricktypename __libcpp_complex_overload_traits<_Tp>::_ValueType
99346035553Spatricknorm(_Tp __re)
99446035553Spatrick{
99546035553Spatrick    typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
99646035553Spatrick    return static_cast<_ValueType>(__re) * __re;
99746035553Spatrick}
99846035553Spatrick
99946035553Spatrick// conj
100046035553Spatrick
100146035553Spatricktemplate<class _Tp>
1002*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
100346035553Spatrickcomplex<_Tp>
100446035553Spatrickconj(const complex<_Tp>& __c)
100546035553Spatrick{
100646035553Spatrick    return complex<_Tp>(__c.real(), -__c.imag());
100746035553Spatrick}
100846035553Spatrick
100946035553Spatricktemplate <class _Tp>
1010*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
101146035553Spatricktypename __libcpp_complex_overload_traits<_Tp>::_ComplexType
101246035553Spatrickconj(_Tp __re)
101346035553Spatrick{
101446035553Spatrick    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
101546035553Spatrick    return _ComplexType(__re);
101646035553Spatrick}
101746035553Spatrick
101846035553Spatrick
101946035553Spatrick
102046035553Spatrick// proj
102146035553Spatrick
102246035553Spatricktemplate<class _Tp>
102346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
102446035553Spatrickcomplex<_Tp>
102546035553Spatrickproj(const complex<_Tp>& __c)
102646035553Spatrick{
102776d0caaeSpatrick    complex<_Tp> __r = __c;
1028*4bdff4beSrobert    if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag()))
1029*4bdff4beSrobert        __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag()));
103046035553Spatrick    return __r;
103146035553Spatrick}
103246035553Spatrick
103346035553Spatricktemplate <class _Tp>
103446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
103546035553Spatricktypename enable_if
103646035553Spatrick<
103746035553Spatrick    is_floating_point<_Tp>::value,
103846035553Spatrick    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
103946035553Spatrick>::type
104046035553Spatrickproj(_Tp __re)
104146035553Spatrick{
1042*4bdff4beSrobert    if (std::__constexpr_isinf(__re))
1043*4bdff4beSrobert        __re = std::abs(__re);
104446035553Spatrick    return complex<_Tp>(__re);
104546035553Spatrick}
104646035553Spatrick
104746035553Spatricktemplate <class _Tp>
104846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
104946035553Spatricktypename enable_if
105046035553Spatrick<
105146035553Spatrick    is_integral<_Tp>::value,
105246035553Spatrick    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
105346035553Spatrick>::type
105446035553Spatrickproj(_Tp __re)
105546035553Spatrick{
105646035553Spatrick    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
105746035553Spatrick    return _ComplexType(__re);
105846035553Spatrick}
105946035553Spatrick
106046035553Spatrick// polar
106146035553Spatrick
106246035553Spatricktemplate<class _Tp>
1063*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
106446035553Spatrickpolar(const _Tp& __rho, const _Tp& __theta = _Tp())
106546035553Spatrick{
1066*4bdff4beSrobert    if (std::__constexpr_isnan(__rho) || std::signbit(__rho))
106746035553Spatrick        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1068*4bdff4beSrobert    if (std::__constexpr_isnan(__theta))
106946035553Spatrick    {
1070*4bdff4beSrobert        if (std::__constexpr_isinf(__rho))
107146035553Spatrick            return complex<_Tp>(__rho, __theta);
107246035553Spatrick        return complex<_Tp>(__theta, __theta);
107346035553Spatrick    }
1074*4bdff4beSrobert    if (std::__constexpr_isinf(__theta))
107546035553Spatrick    {
1076*4bdff4beSrobert        if (std::__constexpr_isinf(__rho))
107746035553Spatrick            return complex<_Tp>(__rho, _Tp(NAN));
107846035553Spatrick        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
107946035553Spatrick    }
1080*4bdff4beSrobert    _Tp __x = __rho * std::cos(__theta);
1081*4bdff4beSrobert    if (std::__constexpr_isnan(__x))
108246035553Spatrick        __x = 0;
1083*4bdff4beSrobert    _Tp __y = __rho * std::sin(__theta);
1084*4bdff4beSrobert    if (std::__constexpr_isnan(__y))
108546035553Spatrick        __y = 0;
108646035553Spatrick    return complex<_Tp>(__x, __y);
108746035553Spatrick}
108846035553Spatrick
108946035553Spatrick// log
109046035553Spatrick
109146035553Spatricktemplate<class _Tp>
109246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
109346035553Spatrickcomplex<_Tp>
109446035553Spatricklog(const complex<_Tp>& __x)
109546035553Spatrick{
1096*4bdff4beSrobert    return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x));
109746035553Spatrick}
109846035553Spatrick
109946035553Spatrick// log10
110046035553Spatrick
110146035553Spatricktemplate<class _Tp>
110246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
110346035553Spatrickcomplex<_Tp>
110446035553Spatricklog10(const complex<_Tp>& __x)
110546035553Spatrick{
1106*4bdff4beSrobert    return std::log(__x) / std::log(_Tp(10));
110746035553Spatrick}
110846035553Spatrick
110946035553Spatrick// sqrt
111046035553Spatrick
111146035553Spatricktemplate<class _Tp>
1112*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
111346035553Spatricksqrt(const complex<_Tp>& __x)
111446035553Spatrick{
1115*4bdff4beSrobert    if (std::__constexpr_isinf(__x.imag()))
111646035553Spatrick        return complex<_Tp>(_Tp(INFINITY), __x.imag());
1117*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
111846035553Spatrick    {
111946035553Spatrick        if (__x.real() > _Tp(0))
1120*4bdff4beSrobert            return complex<_Tp>(__x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag()));
1121*4bdff4beSrobert        return complex<_Tp>(std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag()));
112246035553Spatrick    }
1123*4bdff4beSrobert    return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2));
112446035553Spatrick}
112546035553Spatrick
112646035553Spatrick// exp
112746035553Spatrick
112846035553Spatricktemplate<class _Tp>
1129*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
113046035553Spatrickexp(const complex<_Tp>& __x)
113146035553Spatrick{
113246035553Spatrick    _Tp __i = __x.imag();
1133*4bdff4beSrobert    if (__i == 0) {
1134*4bdff4beSrobert        return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag()));
1135*4bdff4beSrobert    }
1136*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
113746035553Spatrick    {
113846035553Spatrick        if (__x.real() < _Tp(0))
113946035553Spatrick        {
1140*4bdff4beSrobert            if (!std::__constexpr_isfinite(__i))
114146035553Spatrick                __i = _Tp(1);
114246035553Spatrick        }
1143*4bdff4beSrobert        else if (__i == 0 || !std::__constexpr_isfinite(__i))
114446035553Spatrick        {
1145*4bdff4beSrobert            if (std::__constexpr_isinf(__i))
114646035553Spatrick                __i = _Tp(NAN);
114746035553Spatrick            return complex<_Tp>(__x.real(), __i);
114846035553Spatrick        }
114946035553Spatrick    }
1150*4bdff4beSrobert    _Tp __e = std::exp(__x.real());
1151*4bdff4beSrobert    return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i));
115246035553Spatrick}
115346035553Spatrick
115446035553Spatrick// pow
115546035553Spatrick
115646035553Spatricktemplate<class _Tp>
115746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
115846035553Spatrickcomplex<_Tp>
115946035553Spatrickpow(const complex<_Tp>& __x, const complex<_Tp>& __y)
116046035553Spatrick{
1161*4bdff4beSrobert    return std::exp(__y * std::log(__x));
116246035553Spatrick}
116346035553Spatrick
116446035553Spatricktemplate<class _Tp, class _Up>
116546035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
116646035553Spatrickcomplex<typename __promote<_Tp, _Up>::type>
116746035553Spatrickpow(const complex<_Tp>& __x, const complex<_Up>& __y)
116846035553Spatrick{
116946035553Spatrick    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
117046035553Spatrick    return _VSTD::pow(result_type(__x), result_type(__y));
117146035553Spatrick}
117246035553Spatrick
117346035553Spatricktemplate<class _Tp, class _Up>
117446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
117546035553Spatricktypename enable_if
117646035553Spatrick<
117746035553Spatrick    is_arithmetic<_Up>::value,
117846035553Spatrick    complex<typename __promote<_Tp, _Up>::type>
117946035553Spatrick>::type
118046035553Spatrickpow(const complex<_Tp>& __x, const _Up& __y)
118146035553Spatrick{
118246035553Spatrick    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
118346035553Spatrick    return _VSTD::pow(result_type(__x), result_type(__y));
118446035553Spatrick}
118546035553Spatrick
118646035553Spatricktemplate<class _Tp, class _Up>
118746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
118846035553Spatricktypename enable_if
118946035553Spatrick<
119046035553Spatrick    is_arithmetic<_Tp>::value,
119146035553Spatrick    complex<typename __promote<_Tp, _Up>::type>
119246035553Spatrick>::type
119346035553Spatrickpow(const _Tp& __x, const complex<_Up>& __y)
119446035553Spatrick{
119546035553Spatrick    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
119646035553Spatrick    return _VSTD::pow(result_type(__x), result_type(__y));
119746035553Spatrick}
119846035553Spatrick
119946035553Spatrick// __sqr, computes pow(x, 2)
120046035553Spatrick
120146035553Spatricktemplate<class _Tp>
120246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
120346035553Spatrickcomplex<_Tp>
120446035553Spatrick__sqr(const complex<_Tp>& __x)
120546035553Spatrick{
120646035553Spatrick    return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
120746035553Spatrick                        _Tp(2) * __x.real() * __x.imag());
120846035553Spatrick}
120946035553Spatrick
121046035553Spatrick// asinh
121146035553Spatrick
121246035553Spatricktemplate<class _Tp>
1213*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
121446035553Spatrickasinh(const complex<_Tp>& __x)
121546035553Spatrick{
121646035553Spatrick    const _Tp __pi(atan2(+0., -0.));
1217*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
121846035553Spatrick    {
1219*4bdff4beSrobert        if (std::__constexpr_isnan(__x.imag()))
122046035553Spatrick            return __x;
1221*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
1222*4bdff4beSrobert            return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
1223*4bdff4beSrobert        return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
122446035553Spatrick    }
1225*4bdff4beSrobert    if (std::__constexpr_isnan(__x.real()))
122646035553Spatrick    {
1227*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
122846035553Spatrick            return complex<_Tp>(__x.imag(), __x.real());
122946035553Spatrick        if (__x.imag() == 0)
123046035553Spatrick            return __x;
123146035553Spatrick        return complex<_Tp>(__x.real(), __x.real());
123246035553Spatrick    }
1233*4bdff4beSrobert    if (std::__constexpr_isinf(__x.imag()))
1234*4bdff4beSrobert        return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
1235*4bdff4beSrobert    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
1236*4bdff4beSrobert    return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
123746035553Spatrick}
123846035553Spatrick
123946035553Spatrick// acosh
124046035553Spatrick
124146035553Spatricktemplate<class _Tp>
1242*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
124346035553Spatrickacosh(const complex<_Tp>& __x)
124446035553Spatrick{
124546035553Spatrick    const _Tp __pi(atan2(+0., -0.));
1246*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
124746035553Spatrick    {
1248*4bdff4beSrobert        if (std::__constexpr_isnan(__x.imag()))
1249*4bdff4beSrobert            return complex<_Tp>(std::abs(__x.real()), __x.imag());
1250*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
125146035553Spatrick        {
125246035553Spatrick            if (__x.real() > 0)
1253*4bdff4beSrobert                return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
125446035553Spatrick            else
1255*4bdff4beSrobert                return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
125646035553Spatrick        }
125746035553Spatrick        if (__x.real() < 0)
1258*4bdff4beSrobert            return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
1259*4bdff4beSrobert        return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
126046035553Spatrick    }
1261*4bdff4beSrobert    if (std::__constexpr_isnan(__x.real()))
126246035553Spatrick    {
1263*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
1264*4bdff4beSrobert            return complex<_Tp>(std::abs(__x.imag()), __x.real());
126546035553Spatrick        return complex<_Tp>(__x.real(), __x.real());
126646035553Spatrick    }
1267*4bdff4beSrobert    if (std::__constexpr_isinf(__x.imag()))
1268*4bdff4beSrobert        return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi/_Tp(2), __x.imag()));
1269*4bdff4beSrobert    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1270*4bdff4beSrobert    return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
127146035553Spatrick}
127246035553Spatrick
127346035553Spatrick// atanh
127446035553Spatrick
127546035553Spatricktemplate<class _Tp>
1276*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
127746035553Spatrickatanh(const complex<_Tp>& __x)
127846035553Spatrick{
127946035553Spatrick    const _Tp __pi(atan2(+0., -0.));
1280*4bdff4beSrobert    if (std::__constexpr_isinf(__x.imag()))
128146035553Spatrick    {
1282*4bdff4beSrobert        return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
128346035553Spatrick    }
1284*4bdff4beSrobert    if (std::__constexpr_isnan(__x.imag()))
128546035553Spatrick    {
1286*4bdff4beSrobert        if (std::__constexpr_isinf(__x.real()) || __x.real() == 0)
1287*4bdff4beSrobert            return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
128846035553Spatrick        return complex<_Tp>(__x.imag(), __x.imag());
128946035553Spatrick    }
1290*4bdff4beSrobert    if (std::__constexpr_isnan(__x.real()))
129146035553Spatrick    {
129246035553Spatrick        return complex<_Tp>(__x.real(), __x.real());
129346035553Spatrick    }
1294*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
129546035553Spatrick    {
1296*4bdff4beSrobert        return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
129746035553Spatrick    }
1298*4bdff4beSrobert    if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
129946035553Spatrick    {
1300*4bdff4beSrobert        return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
130146035553Spatrick    }
1302*4bdff4beSrobert    complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1303*4bdff4beSrobert    return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
130446035553Spatrick}
130546035553Spatrick
130646035553Spatrick// sinh
130746035553Spatrick
130846035553Spatricktemplate<class _Tp>
1309*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
131046035553Spatricksinh(const complex<_Tp>& __x)
131146035553Spatrick{
1312*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
131346035553Spatrick        return complex<_Tp>(__x.real(), _Tp(NAN));
1314*4bdff4beSrobert    if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
131546035553Spatrick        return complex<_Tp>(__x.real(), _Tp(NAN));
1316*4bdff4beSrobert    if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
131746035553Spatrick        return __x;
1318*4bdff4beSrobert    return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag()));
131946035553Spatrick}
132046035553Spatrick
132146035553Spatrick// cosh
132246035553Spatrick
132346035553Spatricktemplate<class _Tp>
1324*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
132546035553Spatrickcosh(const complex<_Tp>& __x)
132646035553Spatrick{
1327*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
1328*4bdff4beSrobert        return complex<_Tp>(std::abs(__x.real()), _Tp(NAN));
1329*4bdff4beSrobert    if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
133046035553Spatrick        return complex<_Tp>(_Tp(NAN), __x.real());
133146035553Spatrick    if (__x.real() == 0 && __x.imag() == 0)
133246035553Spatrick        return complex<_Tp>(_Tp(1), __x.imag());
1333*4bdff4beSrobert    if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
1334*4bdff4beSrobert        return complex<_Tp>(std::abs(__x.real()), __x.imag());
1335*4bdff4beSrobert    return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag()));
133646035553Spatrick}
133746035553Spatrick
133846035553Spatrick// tanh
133946035553Spatrick
134046035553Spatricktemplate<class _Tp>
1341*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
134246035553Spatricktanh(const complex<_Tp>& __x)
134346035553Spatrick{
1344*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
134546035553Spatrick    {
1346*4bdff4beSrobert        if (!std::__constexpr_isfinite(__x.imag()))
1347*4bdff4beSrobert            return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0));
1348*4bdff4beSrobert        return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag())));
134946035553Spatrick    }
1350*4bdff4beSrobert    if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0)
135146035553Spatrick        return __x;
135246035553Spatrick    _Tp __2r(_Tp(2) * __x.real());
135346035553Spatrick    _Tp __2i(_Tp(2) * __x.imag());
1354*4bdff4beSrobert    _Tp __d(std::cosh(__2r) + std::cos(__2i));
1355*4bdff4beSrobert    _Tp __2rsh(std::sinh(__2r));
1356*4bdff4beSrobert    if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d))
135746035553Spatrick        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
135846035553Spatrick                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1359*4bdff4beSrobert    return  complex<_Tp>(__2rsh/__d, std::sin(__2i)/__d);
136046035553Spatrick}
136146035553Spatrick
136246035553Spatrick// asin
136346035553Spatrick
136446035553Spatricktemplate<class _Tp>
1365*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
136646035553Spatrickasin(const complex<_Tp>& __x)
136746035553Spatrick{
1368*4bdff4beSrobert    complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real()));
136946035553Spatrick    return complex<_Tp>(__z.imag(), -__z.real());
137046035553Spatrick}
137146035553Spatrick
137246035553Spatrick// acos
137346035553Spatrick
137446035553Spatricktemplate<class _Tp>
1375*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
137646035553Spatrickacos(const complex<_Tp>& __x)
137746035553Spatrick{
137846035553Spatrick    const _Tp __pi(atan2(+0., -0.));
1379*4bdff4beSrobert    if (std::__constexpr_isinf(__x.real()))
138046035553Spatrick    {
1381*4bdff4beSrobert        if (std::__constexpr_isnan(__x.imag()))
138246035553Spatrick            return complex<_Tp>(__x.imag(), __x.real());
1383*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
138446035553Spatrick        {
138546035553Spatrick            if (__x.real() < _Tp(0))
138646035553Spatrick                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
138746035553Spatrick            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
138846035553Spatrick        }
138946035553Spatrick        if (__x.real() < _Tp(0))
1390*4bdff4beSrobert            return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real());
1391*4bdff4beSrobert        return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real());
139246035553Spatrick    }
1393*4bdff4beSrobert    if (std::__constexpr_isnan(__x.real()))
139446035553Spatrick    {
1395*4bdff4beSrobert        if (std::__constexpr_isinf(__x.imag()))
139646035553Spatrick            return complex<_Tp>(__x.real(), -__x.imag());
139746035553Spatrick        return complex<_Tp>(__x.real(), __x.real());
139846035553Spatrick    }
1399*4bdff4beSrobert    if (std::__constexpr_isinf(__x.imag()))
140046035553Spatrick        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1401*4bdff4beSrobert    if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag())))
140246035553Spatrick        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1403*4bdff4beSrobert    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1404*4bdff4beSrobert    if (std::signbit(__x.imag()))
1405*4bdff4beSrobert        return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real()));
1406*4bdff4beSrobert    return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real()));
140746035553Spatrick}
140846035553Spatrick
140946035553Spatrick// atan
141046035553Spatrick
141146035553Spatricktemplate<class _Tp>
1412*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
141346035553Spatrickatan(const complex<_Tp>& __x)
141446035553Spatrick{
1415*4bdff4beSrobert    complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real()));
141646035553Spatrick    return complex<_Tp>(__z.imag(), -__z.real());
141746035553Spatrick}
141846035553Spatrick
141946035553Spatrick// sin
142046035553Spatrick
142146035553Spatricktemplate<class _Tp>
1422*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
142346035553Spatricksin(const complex<_Tp>& __x)
142446035553Spatrick{
1425*4bdff4beSrobert    complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real()));
142646035553Spatrick    return complex<_Tp>(__z.imag(), -__z.real());
142746035553Spatrick}
142846035553Spatrick
142946035553Spatrick// cos
143046035553Spatrick
143146035553Spatricktemplate<class _Tp>
143246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
143346035553Spatrickcomplex<_Tp>
143446035553Spatrickcos(const complex<_Tp>& __x)
143546035553Spatrick{
1436*4bdff4beSrobert    return std::cosh(complex<_Tp>(-__x.imag(), __x.real()));
143746035553Spatrick}
143846035553Spatrick
143946035553Spatrick// tan
144046035553Spatrick
144146035553Spatricktemplate<class _Tp>
1442*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI complex<_Tp>
144346035553Spatricktan(const complex<_Tp>& __x)
144446035553Spatrick{
1445*4bdff4beSrobert    complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real()));
144646035553Spatrick    return complex<_Tp>(__z.imag(), -__z.real());
144746035553Spatrick}
144846035553Spatrick
1449*4bdff4beSrobert#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
145046035553Spatricktemplate<class _Tp, class _CharT, class _Traits>
1451*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
145246035553Spatrickoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
145346035553Spatrick{
145446035553Spatrick    if (__is.good())
145546035553Spatrick    {
1456*4bdff4beSrobert        std::ws(__is);
145746035553Spatrick        if (__is.peek() == _CharT('('))
145846035553Spatrick        {
145946035553Spatrick            __is.get();
146046035553Spatrick            _Tp __r;
146146035553Spatrick            __is >> __r;
146246035553Spatrick            if (!__is.fail())
146346035553Spatrick            {
1464*4bdff4beSrobert                std::ws(__is);
146546035553Spatrick                _CharT __c = __is.peek();
146646035553Spatrick                if (__c == _CharT(','))
146746035553Spatrick                {
146846035553Spatrick                    __is.get();
146946035553Spatrick                    _Tp __i;
147046035553Spatrick                    __is >> __i;
147146035553Spatrick                    if (!__is.fail())
147246035553Spatrick                    {
1473*4bdff4beSrobert                        std::ws(__is);
147446035553Spatrick                        __c = __is.peek();
147546035553Spatrick                        if (__c == _CharT(')'))
147646035553Spatrick                        {
147746035553Spatrick                            __is.get();
147846035553Spatrick                            __x = complex<_Tp>(__r, __i);
147946035553Spatrick                        }
148046035553Spatrick                        else
1481037e7968Spatrick                            __is.setstate(__is.failbit);
148246035553Spatrick                    }
148346035553Spatrick                    else
1484037e7968Spatrick                        __is.setstate(__is.failbit);
148546035553Spatrick                }
148646035553Spatrick                else if (__c == _CharT(')'))
148746035553Spatrick                {
148846035553Spatrick                    __is.get();
148946035553Spatrick                    __x = complex<_Tp>(__r, _Tp(0));
149046035553Spatrick                }
149146035553Spatrick                else
1492037e7968Spatrick                    __is.setstate(__is.failbit);
149346035553Spatrick            }
149446035553Spatrick            else
1495037e7968Spatrick                __is.setstate(__is.failbit);
149646035553Spatrick        }
149746035553Spatrick        else
149846035553Spatrick        {
149946035553Spatrick            _Tp __r;
150046035553Spatrick            __is >> __r;
150146035553Spatrick            if (!__is.fail())
150246035553Spatrick                __x = complex<_Tp>(__r, _Tp(0));
150346035553Spatrick            else
1504037e7968Spatrick                __is.setstate(__is.failbit);
150546035553Spatrick        }
150646035553Spatrick    }
150746035553Spatrick    else
1508037e7968Spatrick        __is.setstate(__is.failbit);
150946035553Spatrick    return __is;
151046035553Spatrick}
151146035553Spatrick
151246035553Spatricktemplate<class _Tp, class _CharT, class _Traits>
1513*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
151446035553Spatrickoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
151546035553Spatrick{
151646035553Spatrick    basic_ostringstream<_CharT, _Traits> __s;
151746035553Spatrick    __s.flags(__os.flags());
151846035553Spatrick    __s.imbue(__os.getloc());
151946035553Spatrick    __s.precision(__os.precision());
152046035553Spatrick    __s << '(' << __x.real() << ',' << __x.imag() << ')';
152146035553Spatrick    return __os << __s.str();
152246035553Spatrick}
152376d0caaeSpatrick#endif // !_LIBCPP_HAS_NO_LOCALIZATION
152446035553Spatrick
152546035553Spatrick#if _LIBCPP_STD_VER > 11
152646035553Spatrick// Literal suffix for complex number literals [complex.literals]
152746035553Spatrickinline namespace literals
152846035553Spatrick{
152946035553Spatrick  inline namespace complex_literals
153046035553Spatrick  {
1531*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<long double> operator""il(long double __im)
153246035553Spatrick    {
153346035553Spatrick        return { 0.0l, __im };
153446035553Spatrick    }
153546035553Spatrick
1536*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<long double> operator""il(unsigned long long __im)
153746035553Spatrick    {
153846035553Spatrick        return { 0.0l, static_cast<long double>(__im) };
153946035553Spatrick    }
154046035553Spatrick
154146035553Spatrick
1542*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<double> operator""i(long double __im)
154346035553Spatrick    {
154446035553Spatrick        return { 0.0, static_cast<double>(__im) };
154546035553Spatrick    }
154646035553Spatrick
1547*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<double> operator""i(unsigned long long __im)
154846035553Spatrick    {
154946035553Spatrick        return { 0.0, static_cast<double>(__im) };
155046035553Spatrick    }
155146035553Spatrick
155246035553Spatrick
1553*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<float> operator""if(long double __im)
155446035553Spatrick    {
155546035553Spatrick        return { 0.0f, static_cast<float>(__im) };
155646035553Spatrick    }
155746035553Spatrick
1558*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr complex<float> operator""if(unsigned long long __im)
155946035553Spatrick    {
156046035553Spatrick        return { 0.0f, static_cast<float>(__im) };
156146035553Spatrick    }
1562*4bdff4beSrobert  } // namespace complex_literals
1563*4bdff4beSrobert} // namespace literals
156446035553Spatrick#endif
156546035553Spatrick
156646035553Spatrick_LIBCPP_END_NAMESPACE_STD
156746035553Spatrick
156846035553Spatrick#endif // _LIBCPP_COMPLEX
1569