xref: /freebsd/contrib/llvm-project/libcxx/include/complex (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_COMPLEX
110b57cec5SDimitry Andric#define _LIBCPP_COMPLEX
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    complex synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate<class T>
200b57cec5SDimitry Andricclass complex
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andricpublic:
230b57cec5SDimitry Andric    typedef T value_type;
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
260b57cec5SDimitry Andric    complex(const complex&);  // constexpr in C++14
270b57cec5SDimitry Andric    template<class X> complex(const complex<X>&);  // constexpr in C++14
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric    T real() const; // constexpr in C++14
300b57cec5SDimitry Andric    T imag() const; // constexpr in C++14
310b57cec5SDimitry Andric
32*bdd1243dSDimitry Andric    void real(T); // constexpr in C++20
33*bdd1243dSDimitry Andric    void imag(T); // constexpr in C++20
340b57cec5SDimitry Andric
35*bdd1243dSDimitry Andric    complex<T>& operator= (const T&); // constexpr in C++20
36*bdd1243dSDimitry Andric    complex<T>& operator+=(const T&); // constexpr in C++20
37*bdd1243dSDimitry Andric    complex<T>& operator-=(const T&); // constexpr in C++20
38*bdd1243dSDimitry Andric    complex<T>& operator*=(const T&); // constexpr in C++20
39*bdd1243dSDimitry Andric    complex<T>& operator/=(const T&); // constexpr in C++20
400b57cec5SDimitry Andric
41*bdd1243dSDimitry Andric    complex& operator=(const complex&); // constexpr in C++20
42*bdd1243dSDimitry Andric    template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20
43*bdd1243dSDimitry Andric    template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20
44*bdd1243dSDimitry Andric    template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20
45*bdd1243dSDimitry Andric    template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20
46*bdd1243dSDimitry Andric    template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++20
470b57cec5SDimitry Andric};
480b57cec5SDimitry Andric
490b57cec5SDimitry Andrictemplate<>
500b57cec5SDimitry Andricclass complex<float>
510b57cec5SDimitry Andric{
520b57cec5SDimitry Andricpublic:
530b57cec5SDimitry Andric    typedef float value_type;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric    constexpr complex(float re = 0.0f, float im = 0.0f);
560b57cec5SDimitry Andric    explicit constexpr complex(const complex<double>&);
570b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    constexpr float real() const;
60*bdd1243dSDimitry Andric    void real(float); // constexpr in C++20
610b57cec5SDimitry Andric    constexpr float imag() const;
62*bdd1243dSDimitry Andric    void imag(float); // constexpr in C++20
630b57cec5SDimitry Andric
64*bdd1243dSDimitry Andric    complex<float>& operator= (float); // constexpr in C++20
65*bdd1243dSDimitry Andric    complex<float>& operator+=(float); // constexpr in C++20
66*bdd1243dSDimitry Andric    complex<float>& operator-=(float); // constexpr in C++20
67*bdd1243dSDimitry Andric    complex<float>& operator*=(float); // constexpr in C++20
68*bdd1243dSDimitry Andric    complex<float>& operator/=(float); // constexpr in C++20
690b57cec5SDimitry Andric
70*bdd1243dSDimitry Andric    complex<float>& operator=(const complex<float>&); // constexpr in C++20
71*bdd1243dSDimitry Andric    template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20
72*bdd1243dSDimitry Andric    template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20
73*bdd1243dSDimitry Andric    template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20
74*bdd1243dSDimitry Andric    template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20
75*bdd1243dSDimitry Andric    template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++20
760b57cec5SDimitry Andric};
770b57cec5SDimitry Andric
780b57cec5SDimitry Andrictemplate<>
790b57cec5SDimitry Andricclass complex<double>
800b57cec5SDimitry Andric{
810b57cec5SDimitry Andricpublic:
820b57cec5SDimitry Andric    typedef double value_type;
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    constexpr complex(double re = 0.0, double im = 0.0);
850b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
860b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    constexpr double real() const;
89*bdd1243dSDimitry Andric    void real(double); // constexpr in C++20
900b57cec5SDimitry Andric    constexpr double imag() const;
91*bdd1243dSDimitry Andric    void imag(double); // constexpr in C++20
920b57cec5SDimitry Andric
93*bdd1243dSDimitry Andric    complex<double>& operator= (double); // constexpr in C++20
94*bdd1243dSDimitry Andric    complex<double>& operator+=(double); // constexpr in C++20
95*bdd1243dSDimitry Andric    complex<double>& operator-=(double); // constexpr in C++20
96*bdd1243dSDimitry Andric    complex<double>& operator*=(double); // constexpr in C++20
97*bdd1243dSDimitry Andric    complex<double>& operator/=(double); // constexpr in C++20
98*bdd1243dSDimitry Andric    complex<double>& operator=(const complex<double>&); // constexpr in C++20
990b57cec5SDimitry Andric
100*bdd1243dSDimitry Andric    template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20
101*bdd1243dSDimitry Andric    template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20
102*bdd1243dSDimitry Andric    template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20
103*bdd1243dSDimitry Andric    template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20
104*bdd1243dSDimitry Andric    template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20
1050b57cec5SDimitry Andric};
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andrictemplate<>
1080b57cec5SDimitry Andricclass complex<long double>
1090b57cec5SDimitry Andric{
1100b57cec5SDimitry Andricpublic:
1110b57cec5SDimitry Andric    typedef long double value_type;
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric    constexpr complex(long double re = 0.0L, long double im = 0.0L);
1140b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
1150b57cec5SDimitry Andric    constexpr complex(const complex<double>&);
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric    constexpr long double real() const;
118*bdd1243dSDimitry Andric    void real(long double); // constexpr in C++20
1190b57cec5SDimitry Andric    constexpr long double imag() const;
120*bdd1243dSDimitry Andric    void imag(long double); // constexpr in C++20
1210b57cec5SDimitry Andric
122*bdd1243dSDimitry Andric    complex<long double>& operator=(const complex<long double>&); // constexpr in C++20
123*bdd1243dSDimitry Andric    complex<long double>& operator= (long double); // constexpr in C++20
124*bdd1243dSDimitry Andric    complex<long double>& operator+=(long double); // constexpr in C++20
125*bdd1243dSDimitry Andric    complex<long double>& operator-=(long double); // constexpr in C++20
126*bdd1243dSDimitry Andric    complex<long double>& operator*=(long double); // constexpr in C++20
127*bdd1243dSDimitry Andric    complex<long double>& operator/=(long double); // constexpr in C++20
1280b57cec5SDimitry Andric
129*bdd1243dSDimitry Andric    template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20
130*bdd1243dSDimitry Andric    template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20
131*bdd1243dSDimitry Andric    template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20
132*bdd1243dSDimitry Andric    template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20
133*bdd1243dSDimitry Andric    template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20
1340b57cec5SDimitry Andric};
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric// 26.3.6 operators:
137*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20
138*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const T&);          // constexpr in C++20
139*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const T&, const complex<T>&);          // constexpr in C++20
140*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20
141*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const T&);          // constexpr in C++20
142*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const T&, const complex<T>&);          // constexpr in C++20
143*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20
144*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const T&);          // constexpr in C++20
145*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const T&, const complex<T>&);          // constexpr in C++20
146*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20
147*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const T&);          // constexpr in C++20
148*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const T&, const complex<T>&);          // constexpr in C++20
149*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&);                    // constexpr in C++20
150*bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&);                    // constexpr in C++20
1510b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
1520b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
1530b57cec5SDimitry Andrictemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
1540b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
1550b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
1560b57cec5SDimitry Andrictemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
1590b57cec5SDimitry Andric  basic_istream<charT, traits>&
1600b57cec5SDimitry Andric  operator>>(basic_istream<charT, traits>&, complex<T>&);
1610b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
1620b57cec5SDimitry Andric  basic_ostream<charT, traits>&
1630b57cec5SDimitry Andric  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric// 26.3.7 values:
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andrictemplate<class T>              T real(const complex<T>&); // constexpr in C++14
1680b57cec5SDimitry Andric                     long double real(long double);       // constexpr in C++14
1690b57cec5SDimitry Andric                          double real(double);            // constexpr in C++14
1700b57cec5SDimitry Andrictemplate<Integral T>      double real(T);                 // constexpr in C++14
1710b57cec5SDimitry Andric                          float  real(float);             // constexpr in C++14
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andrictemplate<class T>              T imag(const complex<T>&); // constexpr in C++14
1740b57cec5SDimitry Andric                     long double imag(long double);       // constexpr in C++14
1750b57cec5SDimitry Andric                          double imag(double);            // constexpr in C++14
1760b57cec5SDimitry Andrictemplate<Integral T>      double imag(T);                 // constexpr in C++14
1770b57cec5SDimitry Andric                          float  imag(float);             // constexpr in C++14
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andrictemplate<class T> T abs(const complex<T>&);
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andrictemplate<class T>              T arg(const complex<T>&);
1820b57cec5SDimitry Andric                     long double arg(long double);
1830b57cec5SDimitry Andric                          double arg(double);
1840b57cec5SDimitry Andrictemplate<Integral T>      double arg(T);
1850b57cec5SDimitry Andric                          float  arg(float);
1860b57cec5SDimitry Andric
187*bdd1243dSDimitry Andrictemplate<class T>              T norm(const complex<T>&); // constexpr in C++20
188*bdd1243dSDimitry Andric                     long double norm(long double);       // constexpr in C++20
189*bdd1243dSDimitry Andric                          double norm(double);            // constexpr in C++20
190*bdd1243dSDimitry Andrictemplate<Integral T>      double norm(T);                 // constexpr in C++20
191*bdd1243dSDimitry Andric                          float  norm(float);             // constexpr in C++20
1920b57cec5SDimitry Andric
193*bdd1243dSDimitry Andrictemplate<class T>      complex<T>           conj(const complex<T>&); // constexpr in C++20
194*bdd1243dSDimitry Andric                       complex<long double> conj(long double);       // constexpr in C++20
195*bdd1243dSDimitry Andric                       complex<double>      conj(double);            // constexpr in C++20
196*bdd1243dSDimitry Andrictemplate<Integral T>   complex<double>      conj(T);                 // constexpr in C++20
197*bdd1243dSDimitry Andric                       complex<float>       conj(float);             // constexpr in C++20
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andrictemplate<class T>    complex<T>           proj(const complex<T>&);
2000b57cec5SDimitry Andric                     complex<long double> proj(long double);
2010b57cec5SDimitry Andric                     complex<double>      proj(double);
2020b57cec5SDimitry Andrictemplate<Integral T> complex<double>      proj(T);
2030b57cec5SDimitry Andric                     complex<float>       proj(float);
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andrictemplate<class T> complex<T> polar(const T&, const T& = T());
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andric// 26.3.8 transcendentals:
2080b57cec5SDimitry Andrictemplate<class T> complex<T> acos(const complex<T>&);
2090b57cec5SDimitry Andrictemplate<class T> complex<T> asin(const complex<T>&);
2100b57cec5SDimitry Andrictemplate<class T> complex<T> atan(const complex<T>&);
2110b57cec5SDimitry Andrictemplate<class T> complex<T> acosh(const complex<T>&);
2120b57cec5SDimitry Andrictemplate<class T> complex<T> asinh(const complex<T>&);
2130b57cec5SDimitry Andrictemplate<class T> complex<T> atanh(const complex<T>&);
2140b57cec5SDimitry Andrictemplate<class T> complex<T> cos (const complex<T>&);
2150b57cec5SDimitry Andrictemplate<class T> complex<T> cosh (const complex<T>&);
2160b57cec5SDimitry Andrictemplate<class T> complex<T> exp (const complex<T>&);
2170b57cec5SDimitry Andrictemplate<class T> complex<T> log (const complex<T>&);
2180b57cec5SDimitry Andrictemplate<class T> complex<T> log10(const complex<T>&);
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const T&);
2210b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);
2220b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const T&, const complex<T>&);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andrictemplate<class T> complex<T> sin (const complex<T>&);
2250b57cec5SDimitry Andrictemplate<class T> complex<T> sinh (const complex<T>&);
2260b57cec5SDimitry Andrictemplate<class T> complex<T> sqrt (const complex<T>&);
2270b57cec5SDimitry Andrictemplate<class T> complex<T> tan (const complex<T>&);
2280b57cec5SDimitry Andrictemplate<class T> complex<T> tanh (const complex<T>&);
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric}  // std
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric*/
2330b57cec5SDimitry Andric
23481ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
2350b57cec5SDimitry Andric#include <__config>
2360b57cec5SDimitry Andric#include <cmath>
2375ffd83dbSDimitry Andric#include <iosfwd>
238fe6060f1SDimitry Andric#include <stdexcept>
239fe6060f1SDimitry Andric#include <type_traits>
2400b57cec5SDimitry Andric#include <version>
2410b57cec5SDimitry Andric
242e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
243e8d8bef9SDimitry Andric#   include <sstream> // for std::basic_ostringstream
244e8d8bef9SDimitry Andric#endif
245e8d8bef9SDimitry Andric
2460b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2470b57cec5SDimitry Andric#  pragma GCC system_header
2480b57cec5SDimitry Andric#endif
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
2530b57cec5SDimitry Andric
254*bdd1243dSDimitry Andrictemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
255*bdd1243dSDimitry Andrictemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andrictemplate<class _Tp>
2580b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex
2590b57cec5SDimitry Andric{
2600b57cec5SDimitry Andricpublic:
2610b57cec5SDimitry Andric    typedef _Tp value_type;
2620b57cec5SDimitry Andricprivate:
2630b57cec5SDimitry Andric    value_type __re_;
2640b57cec5SDimitry Andric    value_type __im_;
2650b57cec5SDimitry Andricpublic:
266*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
2670b57cec5SDimitry Andric    complex(const value_type& __re = value_type(), const value_type& __im = value_type())
2680b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
269*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
2700b57cec5SDimitry Andric    complex(const complex<_Xp>& __c)
2710b57cec5SDimitry Andric        : __re_(__c.real()), __im_(__c.imag()) {}
2720b57cec5SDimitry Andric
273*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const {return __re_;}
274*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const {return __im_;}
2750b57cec5SDimitry Andric
276*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
277*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
2780b57cec5SDimitry Andric
279*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const value_type& __re)
2800b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
281*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
282*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
283*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
284*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
2850b57cec5SDimitry Andric
286*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
2870b57cec5SDimitry Andric        {
2880b57cec5SDimitry Andric            __re_ = __c.real();
2890b57cec5SDimitry Andric            __im_ = __c.imag();
2900b57cec5SDimitry Andric            return *this;
2910b57cec5SDimitry Andric        }
292*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
2930b57cec5SDimitry Andric        {
2940b57cec5SDimitry Andric            __re_ += __c.real();
2950b57cec5SDimitry Andric            __im_ += __c.imag();
2960b57cec5SDimitry Andric            return *this;
2970b57cec5SDimitry Andric        }
298*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
2990b57cec5SDimitry Andric        {
3000b57cec5SDimitry Andric            __re_ -= __c.real();
3010b57cec5SDimitry Andric            __im_ -= __c.imag();
3020b57cec5SDimitry Andric            return *this;
3030b57cec5SDimitry Andric        }
304*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
3050b57cec5SDimitry Andric        {
3060b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
3070b57cec5SDimitry Andric            return *this;
3080b57cec5SDimitry Andric        }
309*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
3100b57cec5SDimitry Andric        {
3110b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
3120b57cec5SDimitry Andric            return *this;
3130b57cec5SDimitry Andric        }
3140b57cec5SDimitry Andric};
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>;
3170b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andrictemplate<>
3200b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float>
3210b57cec5SDimitry Andric{
3220b57cec5SDimitry Andric    float __re_;
3230b57cec5SDimitry Andric    float __im_;
3240b57cec5SDimitry Andricpublic:
3250b57cec5SDimitry Andric    typedef float value_type;
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
3280b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
3290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3300b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
3310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3320b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
3350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
3360b57cec5SDimitry Andric
337*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
338*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
3390b57cec5SDimitry Andric
340*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (float __re)
3410b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
342*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) {__re_ += __re; return *this;}
343*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) {__re_ -= __re; return *this;}
344*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
345*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
3460b57cec5SDimitry Andric
347*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
3480b57cec5SDimitry Andric        {
3490b57cec5SDimitry Andric            __re_ = __c.real();
3500b57cec5SDimitry Andric            __im_ = __c.imag();
3510b57cec5SDimitry Andric            return *this;
3520b57cec5SDimitry Andric        }
353*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
3540b57cec5SDimitry Andric        {
3550b57cec5SDimitry Andric            __re_ += __c.real();
3560b57cec5SDimitry Andric            __im_ += __c.imag();
3570b57cec5SDimitry Andric            return *this;
3580b57cec5SDimitry Andric        }
359*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
3600b57cec5SDimitry Andric        {
3610b57cec5SDimitry Andric            __re_ -= __c.real();
3620b57cec5SDimitry Andric            __im_ -= __c.imag();
3630b57cec5SDimitry Andric            return *this;
3640b57cec5SDimitry Andric        }
365*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
3660b57cec5SDimitry Andric        {
3670b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
3680b57cec5SDimitry Andric            return *this;
3690b57cec5SDimitry Andric        }
370*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
3710b57cec5SDimitry Andric        {
3720b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
3730b57cec5SDimitry Andric            return *this;
3740b57cec5SDimitry Andric        }
3750b57cec5SDimitry Andric};
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andrictemplate<>
3780b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double>
3790b57cec5SDimitry Andric{
3800b57cec5SDimitry Andric    double __re_;
3810b57cec5SDimitry Andric    double __im_;
3820b57cec5SDimitry Andricpublic:
3830b57cec5SDimitry Andric    typedef double value_type;
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
3860b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
3870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3880b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
3890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3900b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
3930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
3940b57cec5SDimitry Andric
395*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
396*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
3970b57cec5SDimitry Andric
398*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (double __re)
3990b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
400*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) {__re_ += __re; return *this;}
401*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) {__re_ -= __re; return *this;}
402*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
403*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
4040b57cec5SDimitry Andric
405*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
4060b57cec5SDimitry Andric        {
4070b57cec5SDimitry Andric            __re_ = __c.real();
4080b57cec5SDimitry Andric            __im_ = __c.imag();
4090b57cec5SDimitry Andric            return *this;
4100b57cec5SDimitry Andric        }
411*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
4120b57cec5SDimitry Andric        {
4130b57cec5SDimitry Andric            __re_ += __c.real();
4140b57cec5SDimitry Andric            __im_ += __c.imag();
4150b57cec5SDimitry Andric            return *this;
4160b57cec5SDimitry Andric        }
417*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
4180b57cec5SDimitry Andric        {
4190b57cec5SDimitry Andric            __re_ -= __c.real();
4200b57cec5SDimitry Andric            __im_ -= __c.imag();
4210b57cec5SDimitry Andric            return *this;
4220b57cec5SDimitry Andric        }
423*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
4240b57cec5SDimitry Andric        {
4250b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
4260b57cec5SDimitry Andric            return *this;
4270b57cec5SDimitry Andric        }
428*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
4290b57cec5SDimitry Andric        {
4300b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
4310b57cec5SDimitry Andric            return *this;
4320b57cec5SDimitry Andric        }
4330b57cec5SDimitry Andric};
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andrictemplate<>
4360b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double>
4370b57cec5SDimitry Andric{
4380b57cec5SDimitry Andric    long double __re_;
4390b57cec5SDimitry Andric    long double __im_;
4400b57cec5SDimitry Andricpublic:
4410b57cec5SDimitry Andric    typedef long double value_type;
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
4440b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
4450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4460b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
4470b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4480b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
4510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
4520b57cec5SDimitry Andric
453*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;}
454*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;}
4550b57cec5SDimitry Andric
456*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (long double __re)
4570b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
458*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) {__re_ += __re; return *this;}
459*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) {__re_ -= __re; return *this;}
460*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
461*bdd1243dSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
4620b57cec5SDimitry Andric
463*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c)
4640b57cec5SDimitry Andric        {
4650b57cec5SDimitry Andric            __re_ = __c.real();
4660b57cec5SDimitry Andric            __im_ = __c.imag();
4670b57cec5SDimitry Andric            return *this;
4680b57cec5SDimitry Andric        }
469*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c)
4700b57cec5SDimitry Andric        {
4710b57cec5SDimitry Andric            __re_ += __c.real();
4720b57cec5SDimitry Andric            __im_ += __c.imag();
4730b57cec5SDimitry Andric            return *this;
4740b57cec5SDimitry Andric        }
475*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c)
4760b57cec5SDimitry Andric        {
4770b57cec5SDimitry Andric            __re_ -= __c.real();
4780b57cec5SDimitry Andric            __im_ -= __c.imag();
4790b57cec5SDimitry Andric            return *this;
4800b57cec5SDimitry Andric        }
481*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c)
4820b57cec5SDimitry Andric        {
4830b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
4840b57cec5SDimitry Andric            return *this;
4850b57cec5SDimitry Andric        }
486*bdd1243dSDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c)
4870b57cec5SDimitry Andric        {
4880b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
4890b57cec5SDimitry Andric            return *this;
4900b57cec5SDimitry Andric        }
4910b57cec5SDimitry Andric};
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andricinline
4940b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
4950b57cec5SDimitry Andriccomplex<float>::complex(const complex<double>& __c)
4960b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andricinline
4990b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
5000b57cec5SDimitry Andriccomplex<float>::complex(const complex<long double>& __c)
5010b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andricinline
5040b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
5050b57cec5SDimitry Andriccomplex<double>::complex(const complex<float>& __c)
5060b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andricinline
5090b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
5100b57cec5SDimitry Andriccomplex<double>::complex(const complex<long double>& __c)
5110b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andricinline
5140b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
5150b57cec5SDimitry Andriccomplex<long double>::complex(const complex<float>& __c)
5160b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andricinline
5190b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
5200b57cec5SDimitry Andriccomplex<long double>::complex(const complex<double>& __c)
5210b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric// 26.3.6 operators:
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andrictemplate<class _Tp>
526*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5270b57cec5SDimitry Andriccomplex<_Tp>
5280b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
5290b57cec5SDimitry Andric{
5300b57cec5SDimitry Andric    complex<_Tp> __t(__x);
5310b57cec5SDimitry Andric    __t += __y;
5320b57cec5SDimitry Andric    return __t;
5330b57cec5SDimitry Andric}
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andrictemplate<class _Tp>
536*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5370b57cec5SDimitry Andriccomplex<_Tp>
5380b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y)
5390b57cec5SDimitry Andric{
5400b57cec5SDimitry Andric    complex<_Tp> __t(__x);
5410b57cec5SDimitry Andric    __t += __y;
5420b57cec5SDimitry Andric    return __t;
5430b57cec5SDimitry Andric}
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andrictemplate<class _Tp>
546*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5470b57cec5SDimitry Andriccomplex<_Tp>
5480b57cec5SDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y)
5490b57cec5SDimitry Andric{
5500b57cec5SDimitry Andric    complex<_Tp> __t(__y);
5510b57cec5SDimitry Andric    __t += __x;
5520b57cec5SDimitry Andric    return __t;
5530b57cec5SDimitry Andric}
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andrictemplate<class _Tp>
556*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5570b57cec5SDimitry Andriccomplex<_Tp>
5580b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
5590b57cec5SDimitry Andric{
5600b57cec5SDimitry Andric    complex<_Tp> __t(__x);
5610b57cec5SDimitry Andric    __t -= __y;
5620b57cec5SDimitry Andric    return __t;
5630b57cec5SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andrictemplate<class _Tp>
566*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5670b57cec5SDimitry Andriccomplex<_Tp>
5680b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y)
5690b57cec5SDimitry Andric{
5700b57cec5SDimitry Andric    complex<_Tp> __t(__x);
5710b57cec5SDimitry Andric    __t -= __y;
5720b57cec5SDimitry Andric    return __t;
5730b57cec5SDimitry Andric}
5740b57cec5SDimitry Andric
5750b57cec5SDimitry Andrictemplate<class _Tp>
576*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
5770b57cec5SDimitry Andriccomplex<_Tp>
5780b57cec5SDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y)
5790b57cec5SDimitry Andric{
5800b57cec5SDimitry Andric    complex<_Tp> __t(-__y);
5810b57cec5SDimitry Andric    __t += __x;
5820b57cec5SDimitry Andric    return __t;
5830b57cec5SDimitry Andric}
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andrictemplate<class _Tp>
586*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
5870b57cec5SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
5880b57cec5SDimitry Andric{
5890b57cec5SDimitry Andric    _Tp __a = __z.real();
5900b57cec5SDimitry Andric    _Tp __b = __z.imag();
5910b57cec5SDimitry Andric    _Tp __c = __w.real();
5920b57cec5SDimitry Andric    _Tp __d = __w.imag();
593*bdd1243dSDimitry Andric
594*bdd1243dSDimitry Andric    // Avoid floating point operations that are invalid during constant evaluation
595*bdd1243dSDimitry Andric    if (__libcpp_is_constant_evaluated()) {
596*bdd1243dSDimitry Andric        bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
597*bdd1243dSDimitry Andric        bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
598*bdd1243dSDimitry Andric        bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
599*bdd1243dSDimitry Andric        bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
600*bdd1243dSDimitry Andric        bool __z_nan = !__z_inf && (
601*bdd1243dSDimitry Andric            (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
602*bdd1243dSDimitry Andric            || (std::__constexpr_isnan(__a) && __b == _Tp(0))
603*bdd1243dSDimitry Andric            || (__a == _Tp(0) && std::__constexpr_isnan(__b))
604*bdd1243dSDimitry Andric        );
605*bdd1243dSDimitry Andric        bool __w_nan = !__w_inf && (
606*bdd1243dSDimitry Andric            (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
607*bdd1243dSDimitry Andric            || (std::__constexpr_isnan(__c) && __d == _Tp(0))
608*bdd1243dSDimitry Andric            || (__c == _Tp(0) && std::__constexpr_isnan(__d))
609*bdd1243dSDimitry Andric        );
610*bdd1243dSDimitry Andric        if (__z_nan || __w_nan) {
611*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
612*bdd1243dSDimitry Andric        }
613*bdd1243dSDimitry Andric        if (__z_inf || __w_inf) {
614*bdd1243dSDimitry Andric            if (__z_zero || __w_zero) {
615*bdd1243dSDimitry Andric                return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
616*bdd1243dSDimitry Andric            }
617*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
618*bdd1243dSDimitry Andric        }
619*bdd1243dSDimitry Andric        bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
620*bdd1243dSDimitry Andric        bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
621*bdd1243dSDimitry Andric        if (__z_nonzero_nan || __w_nonzero_nan) {
622*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
623*bdd1243dSDimitry Andric        }
624*bdd1243dSDimitry Andric    }
625*bdd1243dSDimitry Andric
6260b57cec5SDimitry Andric    _Tp __ac = __a * __c;
6270b57cec5SDimitry Andric    _Tp __bd = __b * __d;
6280b57cec5SDimitry Andric    _Tp __ad = __a * __d;
6290b57cec5SDimitry Andric    _Tp __bc = __b * __c;
6300b57cec5SDimitry Andric    _Tp __x = __ac - __bd;
6310b57cec5SDimitry Andric    _Tp __y = __ad + __bc;
632*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
6330b57cec5SDimitry Andric    {
6340b57cec5SDimitry Andric        bool __recalc = false;
635*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b))
6360b57cec5SDimitry Andric        {
637*bdd1243dSDimitry Andric            __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
638*bdd1243dSDimitry Andric            __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
639*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__c))
640*bdd1243dSDimitry Andric                __c = std::__constexpr_copysign(_Tp(0), __c);
641*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__d))
642*bdd1243dSDimitry Andric                __d = std::__constexpr_copysign(_Tp(0), __d);
6430b57cec5SDimitry Andric            __recalc = true;
6440b57cec5SDimitry Andric        }
645*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d))
6460b57cec5SDimitry Andric        {
647*bdd1243dSDimitry Andric            __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
648*bdd1243dSDimitry Andric            __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
649*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__a))
650*bdd1243dSDimitry Andric                __a = std::__constexpr_copysign(_Tp(0), __a);
651*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__b))
652*bdd1243dSDimitry Andric                __b = std::__constexpr_copysign(_Tp(0), __b);
6530b57cec5SDimitry Andric            __recalc = true;
6540b57cec5SDimitry Andric        }
655*bdd1243dSDimitry Andric        if (!__recalc && (std::__constexpr_isinf(__ac) || std::__constexpr_isinf(__bd) ||
656*bdd1243dSDimitry Andric                          std::__constexpr_isinf(__ad) || std::__constexpr_isinf(__bc)))
6570b57cec5SDimitry Andric        {
658*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__a))
659*bdd1243dSDimitry Andric                __a = std::__constexpr_copysign(_Tp(0), __a);
660*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__b))
661*bdd1243dSDimitry Andric                __b = std::__constexpr_copysign(_Tp(0), __b);
662*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__c))
663*bdd1243dSDimitry Andric                __c = std::__constexpr_copysign(_Tp(0), __c);
664*bdd1243dSDimitry Andric            if (std::__constexpr_isnan(__d))
665*bdd1243dSDimitry Andric                __d = std::__constexpr_copysign(_Tp(0), __d);
6660b57cec5SDimitry Andric            __recalc = true;
6670b57cec5SDimitry Andric        }
6680b57cec5SDimitry Andric        if (__recalc)
6690b57cec5SDimitry Andric        {
6700b57cec5SDimitry Andric            __x = _Tp(INFINITY) * (__a * __c - __b * __d);
6710b57cec5SDimitry Andric            __y = _Tp(INFINITY) * (__a * __d + __b * __c);
6720b57cec5SDimitry Andric        }
6730b57cec5SDimitry Andric    }
6740b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
6750b57cec5SDimitry Andric}
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andrictemplate<class _Tp>
678*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
6790b57cec5SDimitry Andriccomplex<_Tp>
6800b57cec5SDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y)
6810b57cec5SDimitry Andric{
6820b57cec5SDimitry Andric    complex<_Tp> __t(__x);
6830b57cec5SDimitry Andric    __t *= __y;
6840b57cec5SDimitry Andric    return __t;
6850b57cec5SDimitry Andric}
6860b57cec5SDimitry Andric
6870b57cec5SDimitry Andrictemplate<class _Tp>
688*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
6890b57cec5SDimitry Andriccomplex<_Tp>
6900b57cec5SDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y)
6910b57cec5SDimitry Andric{
6920b57cec5SDimitry Andric    complex<_Tp> __t(__y);
6930b57cec5SDimitry Andric    __t *= __x;
6940b57cec5SDimitry Andric    return __t;
6950b57cec5SDimitry Andric}
6960b57cec5SDimitry Andric
6970b57cec5SDimitry Andrictemplate<class _Tp>
698*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
6990b57cec5SDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
7000b57cec5SDimitry Andric{
7010b57cec5SDimitry Andric    int __ilogbw = 0;
7020b57cec5SDimitry Andric    _Tp __a = __z.real();
7030b57cec5SDimitry Andric    _Tp __b = __z.imag();
7040b57cec5SDimitry Andric    _Tp __c = __w.real();
7050b57cec5SDimitry Andric    _Tp __d = __w.imag();
706*bdd1243dSDimitry Andric    _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d)));
707*bdd1243dSDimitry Andric    if (std::__constexpr_isfinite(__logbw))
7080b57cec5SDimitry Andric    {
7090b57cec5SDimitry Andric        __ilogbw = static_cast<int>(__logbw);
710*bdd1243dSDimitry Andric        __c = std::__constexpr_scalbn(__c, -__ilogbw);
711*bdd1243dSDimitry Andric        __d = std::__constexpr_scalbn(__d, -__ilogbw);
7120b57cec5SDimitry Andric    }
713*bdd1243dSDimitry Andric
714*bdd1243dSDimitry Andric    // Avoid floating point operations that are invalid during constant evaluation
715*bdd1243dSDimitry Andric    if (__libcpp_is_constant_evaluated()) {
716*bdd1243dSDimitry Andric        bool __z_zero = __a == _Tp(0) && __b == _Tp(0);
717*bdd1243dSDimitry Andric        bool __w_zero = __c == _Tp(0) && __d == _Tp(0);
718*bdd1243dSDimitry Andric        bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b);
719*bdd1243dSDimitry Andric        bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d);
720*bdd1243dSDimitry Andric        bool __z_nan = !__z_inf && (
721*bdd1243dSDimitry Andric            (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b))
722*bdd1243dSDimitry Andric            || (std::__constexpr_isnan(__a) && __b == _Tp(0))
723*bdd1243dSDimitry Andric            || (__a == _Tp(0) && std::__constexpr_isnan(__b))
724*bdd1243dSDimitry Andric        );
725*bdd1243dSDimitry Andric        bool __w_nan = !__w_inf && (
726*bdd1243dSDimitry Andric            (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d))
727*bdd1243dSDimitry Andric            || (std::__constexpr_isnan(__c) && __d == _Tp(0))
728*bdd1243dSDimitry Andric            || (__c == _Tp(0) && std::__constexpr_isnan(__d))
729*bdd1243dSDimitry Andric        );
730*bdd1243dSDimitry Andric        if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) {
731*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
732*bdd1243dSDimitry Andric        }
733*bdd1243dSDimitry Andric        bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b));
734*bdd1243dSDimitry Andric        bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d));
735*bdd1243dSDimitry Andric        if (__z_nonzero_nan || __w_nonzero_nan) {
736*bdd1243dSDimitry Andric            if (__w_zero) {
737*bdd1243dSDimitry Andric                return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
738*bdd1243dSDimitry Andric            }
739*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
740*bdd1243dSDimitry Andric        }
741*bdd1243dSDimitry Andric        if (__w_inf) {
742*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(0), _Tp(0));
743*bdd1243dSDimitry Andric        }
744*bdd1243dSDimitry Andric        if (__z_inf) {
745*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
746*bdd1243dSDimitry Andric        }
747*bdd1243dSDimitry Andric        if (__w_zero) {
748*bdd1243dSDimitry Andric            if (__z_zero) {
749*bdd1243dSDimitry Andric                return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));
750*bdd1243dSDimitry Andric            }
751*bdd1243dSDimitry Andric            return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));
752*bdd1243dSDimitry Andric        }
753*bdd1243dSDimitry Andric    }
754*bdd1243dSDimitry Andric
7550b57cec5SDimitry Andric    _Tp __denom = __c * __c + __d * __d;
756*bdd1243dSDimitry Andric    _Tp __x = std::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
757*bdd1243dSDimitry Andric    _Tp __y = std::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
758*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y))
7590b57cec5SDimitry Andric    {
760*bdd1243dSDimitry Andric        if ((__denom == _Tp(0)) && (!std::__constexpr_isnan(__a) || !std::__constexpr_isnan(__b)))
7610b57cec5SDimitry Andric        {
762*bdd1243dSDimitry Andric            __x = std::__constexpr_copysign(_Tp(INFINITY), __c) * __a;
763*bdd1243dSDimitry Andric            __y = std::__constexpr_copysign(_Tp(INFINITY), __c) * __b;
764*bdd1243dSDimitry Andric        } else if ((std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) && std::__constexpr_isfinite(__c) &&
765*bdd1243dSDimitry Andric                   std::__constexpr_isfinite(__d)) {
766*bdd1243dSDimitry Andric            __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);
767*bdd1243dSDimitry Andric            __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);
7680b57cec5SDimitry Andric            __x = _Tp(INFINITY) * (__a * __c + __b * __d);
7690b57cec5SDimitry Andric            __y = _Tp(INFINITY) * (__b * __c - __a * __d);
770*bdd1243dSDimitry Andric        } else if (std::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && std::__constexpr_isfinite(__a) &&
771*bdd1243dSDimitry Andric                   std::__constexpr_isfinite(__b)) {
772*bdd1243dSDimitry Andric            __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);
773*bdd1243dSDimitry Andric            __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);
7740b57cec5SDimitry Andric            __x = _Tp(0) * (__a * __c + __b * __d);
7750b57cec5SDimitry Andric            __y = _Tp(0) * (__b * __c - __a * __d);
7760b57cec5SDimitry Andric        }
7770b57cec5SDimitry Andric    }
7780b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
7790b57cec5SDimitry Andric}
7800b57cec5SDimitry Andric
7810b57cec5SDimitry Andrictemplate<class _Tp>
782*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
7830b57cec5SDimitry Andriccomplex<_Tp>
7840b57cec5SDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y)
7850b57cec5SDimitry Andric{
7860b57cec5SDimitry Andric    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
7870b57cec5SDimitry Andric}
7880b57cec5SDimitry Andric
7890b57cec5SDimitry Andrictemplate<class _Tp>
790*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
7910b57cec5SDimitry Andriccomplex<_Tp>
7920b57cec5SDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y)
7930b57cec5SDimitry Andric{
7940b57cec5SDimitry Andric    complex<_Tp> __t(__x);
7950b57cec5SDimitry Andric    __t /= __y;
7960b57cec5SDimitry Andric    return __t;
7970b57cec5SDimitry Andric}
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andrictemplate<class _Tp>
800*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
8010b57cec5SDimitry Andriccomplex<_Tp>
8020b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x)
8030b57cec5SDimitry Andric{
8040b57cec5SDimitry Andric    return __x;
8050b57cec5SDimitry Andric}
8060b57cec5SDimitry Andric
8070b57cec5SDimitry Andrictemplate<class _Tp>
808*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
8090b57cec5SDimitry Andriccomplex<_Tp>
8100b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x)
8110b57cec5SDimitry Andric{
8120b57cec5SDimitry Andric    return complex<_Tp>(-__x.real(), -__x.imag());
8130b57cec5SDimitry Andric}
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andrictemplate<class _Tp>
816*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8170b57cec5SDimitry Andricbool
8180b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
8190b57cec5SDimitry Andric{
8200b57cec5SDimitry Andric    return __x.real() == __y.real() && __x.imag() == __y.imag();
8210b57cec5SDimitry Andric}
8220b57cec5SDimitry Andric
8230b57cec5SDimitry Andrictemplate<class _Tp>
824*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8250b57cec5SDimitry Andricbool
8260b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const _Tp& __y)
8270b57cec5SDimitry Andric{
8280b57cec5SDimitry Andric    return __x.real() == __y && __x.imag() == 0;
8290b57cec5SDimitry Andric}
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andrictemplate<class _Tp>
832*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8330b57cec5SDimitry Andricbool
8340b57cec5SDimitry Andricoperator==(const _Tp& __x, const complex<_Tp>& __y)
8350b57cec5SDimitry Andric{
8360b57cec5SDimitry Andric    return __x == __y.real() && 0 == __y.imag();
8370b57cec5SDimitry Andric}
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andrictemplate<class _Tp>
840*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8410b57cec5SDimitry Andricbool
8420b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
8430b57cec5SDimitry Andric{
8440b57cec5SDimitry Andric    return !(__x == __y);
8450b57cec5SDimitry Andric}
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andrictemplate<class _Tp>
848*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8490b57cec5SDimitry Andricbool
8500b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const _Tp& __y)
8510b57cec5SDimitry Andric{
8520b57cec5SDimitry Andric    return !(__x == __y);
8530b57cec5SDimitry Andric}
8540b57cec5SDimitry Andric
8550b57cec5SDimitry Andrictemplate<class _Tp>
856*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8570b57cec5SDimitry Andricbool
8580b57cec5SDimitry Andricoperator!=(const _Tp& __x, const complex<_Tp>& __y)
8590b57cec5SDimitry Andric{
8600b57cec5SDimitry Andric    return !(__x == __y);
8610b57cec5SDimitry Andric}
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andric// 26.3.7 values:
8640b57cec5SDimitry Andric
8650b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value,
8660b57cec5SDimitry Andric                     bool = is_floating_point<_Tp>::value
8670b57cec5SDimitry Andric                     >
8680b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {};
8690b57cec5SDimitry Andric
8700b57cec5SDimitry Andric// Integral Types
8710b57cec5SDimitry Andrictemplate <class _Tp>
8720b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false>
8730b57cec5SDimitry Andric{
8740b57cec5SDimitry Andric    typedef double _ValueType;
8750b57cec5SDimitry Andric    typedef complex<double> _ComplexType;
8760b57cec5SDimitry Andric};
8770b57cec5SDimitry Andric
8780b57cec5SDimitry Andric// Floating point types
8790b57cec5SDimitry Andrictemplate <class _Tp>
8800b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true>
8810b57cec5SDimitry Andric{
8820b57cec5SDimitry Andric    typedef _Tp _ValueType;
8830b57cec5SDimitry Andric    typedef complex<_Tp> _ComplexType;
8840b57cec5SDimitry Andric};
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andric// real
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andrictemplate<class _Tp>
889*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8900b57cec5SDimitry Andric_Tp
8910b57cec5SDimitry Andricreal(const complex<_Tp>& __c)
8920b57cec5SDimitry Andric{
8930b57cec5SDimitry Andric    return __c.real();
8940b57cec5SDimitry Andric}
8950b57cec5SDimitry Andric
8960b57cec5SDimitry Andrictemplate <class _Tp>
897*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
8980b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
8990b57cec5SDimitry Andricreal(_Tp __re)
9000b57cec5SDimitry Andric{
9010b57cec5SDimitry Andric    return __re;
9020b57cec5SDimitry Andric}
9030b57cec5SDimitry Andric
9040b57cec5SDimitry Andric// imag
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andrictemplate<class _Tp>
907*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
9080b57cec5SDimitry Andric_Tp
9090b57cec5SDimitry Andricimag(const complex<_Tp>& __c)
9100b57cec5SDimitry Andric{
9110b57cec5SDimitry Andric    return __c.imag();
9120b57cec5SDimitry Andric}
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andrictemplate <class _Tp>
915*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
9160b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
9170b57cec5SDimitry Andricimag(_Tp)
9180b57cec5SDimitry Andric{
9190b57cec5SDimitry Andric    return 0;
9200b57cec5SDimitry Andric}
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andric// abs
9230b57cec5SDimitry Andric
9240b57cec5SDimitry Andrictemplate<class _Tp>
9250b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9260b57cec5SDimitry Andric_Tp
9270b57cec5SDimitry Andricabs(const complex<_Tp>& __c)
9280b57cec5SDimitry Andric{
929*bdd1243dSDimitry Andric    return std::hypot(__c.real(), __c.imag());
9300b57cec5SDimitry Andric}
9310b57cec5SDimitry Andric
9320b57cec5SDimitry Andric// arg
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andrictemplate<class _Tp>
9350b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9360b57cec5SDimitry Andric_Tp
9370b57cec5SDimitry Andricarg(const complex<_Tp>& __c)
9380b57cec5SDimitry Andric{
939*bdd1243dSDimitry Andric    return std::atan2(__c.imag(), __c.real());
9400b57cec5SDimitry Andric}
9410b57cec5SDimitry Andric
9420b57cec5SDimitry Andrictemplate <class _Tp>
9430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9440b57cec5SDimitry Andrictypename enable_if<
9450b57cec5SDimitry Andric    is_same<_Tp, long double>::value,
9460b57cec5SDimitry Andric    long double
9470b57cec5SDimitry Andric>::type
9480b57cec5SDimitry Andricarg(_Tp __re)
9490b57cec5SDimitry Andric{
950*bdd1243dSDimitry Andric    return std::atan2l(0.L, __re);
9510b57cec5SDimitry Andric}
9520b57cec5SDimitry Andric
9530b57cec5SDimitry Andrictemplate<class _Tp>
9540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9550b57cec5SDimitry Andrictypename enable_if
9560b57cec5SDimitry Andric<
9570b57cec5SDimitry Andric    is_integral<_Tp>::value || is_same<_Tp, double>::value,
9580b57cec5SDimitry Andric    double
9590b57cec5SDimitry Andric>::type
9600b57cec5SDimitry Andricarg(_Tp __re)
9610b57cec5SDimitry Andric{
962*bdd1243dSDimitry Andric    return std::atan2(0., __re);
9630b57cec5SDimitry Andric}
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andrictemplate <class _Tp>
9660b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
9670b57cec5SDimitry Andrictypename enable_if<
9680b57cec5SDimitry Andric    is_same<_Tp, float>::value,
9690b57cec5SDimitry Andric    float
9700b57cec5SDimitry Andric>::type
9710b57cec5SDimitry Andricarg(_Tp __re)
9720b57cec5SDimitry Andric{
973*bdd1243dSDimitry Andric    return std::atan2f(0.F, __re);
9740b57cec5SDimitry Andric}
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric// norm
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andrictemplate<class _Tp>
979*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
9800b57cec5SDimitry Andric_Tp
9810b57cec5SDimitry Andricnorm(const complex<_Tp>& __c)
9820b57cec5SDimitry Andric{
983*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__c.real()))
984*bdd1243dSDimitry Andric        return std::abs(__c.real());
985*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__c.imag()))
986*bdd1243dSDimitry Andric        return std::abs(__c.imag());
9870b57cec5SDimitry Andric    return __c.real() * __c.real() + __c.imag() * __c.imag();
9880b57cec5SDimitry Andric}
9890b57cec5SDimitry Andric
9900b57cec5SDimitry Andrictemplate <class _Tp>
991*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
9920b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
9930b57cec5SDimitry Andricnorm(_Tp __re)
9940b57cec5SDimitry Andric{
9950b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
9960b57cec5SDimitry Andric    return static_cast<_ValueType>(__re) * __re;
9970b57cec5SDimitry Andric}
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric// conj
10000b57cec5SDimitry Andric
10010b57cec5SDimitry Andrictemplate<class _Tp>
1002*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
10030b57cec5SDimitry Andriccomplex<_Tp>
10040b57cec5SDimitry Andricconj(const complex<_Tp>& __c)
10050b57cec5SDimitry Andric{
10060b57cec5SDimitry Andric    return complex<_Tp>(__c.real(), -__c.imag());
10070b57cec5SDimitry Andric}
10080b57cec5SDimitry Andric
10090b57cec5SDimitry Andrictemplate <class _Tp>
1010*bdd1243dSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
10110b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType
10120b57cec5SDimitry Andricconj(_Tp __re)
10130b57cec5SDimitry Andric{
10140b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
10150b57cec5SDimitry Andric    return _ComplexType(__re);
10160b57cec5SDimitry Andric}
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andric// proj
10210b57cec5SDimitry Andric
10220b57cec5SDimitry Andrictemplate<class _Tp>
10230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10240b57cec5SDimitry Andriccomplex<_Tp>
10250b57cec5SDimitry Andricproj(const complex<_Tp>& __c)
10260b57cec5SDimitry Andric{
1027e8d8bef9SDimitry Andric    complex<_Tp> __r = __c;
1028*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag()))
1029*bdd1243dSDimitry Andric        __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag()));
10300b57cec5SDimitry Andric    return __r;
10310b57cec5SDimitry Andric}
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andrictemplate <class _Tp>
10340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10350b57cec5SDimitry Andrictypename enable_if
10360b57cec5SDimitry Andric<
10370b57cec5SDimitry Andric    is_floating_point<_Tp>::value,
10380b57cec5SDimitry Andric    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
10390b57cec5SDimitry Andric>::type
10400b57cec5SDimitry Andricproj(_Tp __re)
10410b57cec5SDimitry Andric{
1042*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__re))
1043*bdd1243dSDimitry Andric        __re = std::abs(__re);
10440b57cec5SDimitry Andric    return complex<_Tp>(__re);
10450b57cec5SDimitry Andric}
10460b57cec5SDimitry Andric
10470b57cec5SDimitry Andrictemplate <class _Tp>
10480b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10490b57cec5SDimitry Andrictypename enable_if
10500b57cec5SDimitry Andric<
10510b57cec5SDimitry Andric    is_integral<_Tp>::value,
10520b57cec5SDimitry Andric    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
10530b57cec5SDimitry Andric>::type
10540b57cec5SDimitry Andricproj(_Tp __re)
10550b57cec5SDimitry Andric{
10560b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
10570b57cec5SDimitry Andric    return _ComplexType(__re);
10580b57cec5SDimitry Andric}
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andric// polar
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andrictemplate<class _Tp>
1063*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
10640b57cec5SDimitry Andricpolar(const _Tp& __rho, const _Tp& __theta = _Tp())
10650b57cec5SDimitry Andric{
1066*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__rho) || std::signbit(__rho))
10670b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1068*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__theta))
10690b57cec5SDimitry Andric    {
1070*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__rho))
10710b57cec5SDimitry Andric            return complex<_Tp>(__rho, __theta);
10720b57cec5SDimitry Andric        return complex<_Tp>(__theta, __theta);
10730b57cec5SDimitry Andric    }
1074*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__theta))
10750b57cec5SDimitry Andric    {
1076*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__rho))
10770b57cec5SDimitry Andric            return complex<_Tp>(__rho, _Tp(NAN));
10780b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
10790b57cec5SDimitry Andric    }
1080*bdd1243dSDimitry Andric    _Tp __x = __rho * std::cos(__theta);
1081*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x))
10820b57cec5SDimitry Andric        __x = 0;
1083*bdd1243dSDimitry Andric    _Tp __y = __rho * std::sin(__theta);
1084*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__y))
10850b57cec5SDimitry Andric        __y = 0;
10860b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
10870b57cec5SDimitry Andric}
10880b57cec5SDimitry Andric
10890b57cec5SDimitry Andric// log
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andrictemplate<class _Tp>
10920b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
10930b57cec5SDimitry Andriccomplex<_Tp>
10940b57cec5SDimitry Andriclog(const complex<_Tp>& __x)
10950b57cec5SDimitry Andric{
1096*bdd1243dSDimitry Andric    return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x));
10970b57cec5SDimitry Andric}
10980b57cec5SDimitry Andric
10990b57cec5SDimitry Andric// log10
11000b57cec5SDimitry Andric
11010b57cec5SDimitry Andrictemplate<class _Tp>
11020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11030b57cec5SDimitry Andriccomplex<_Tp>
11040b57cec5SDimitry Andriclog10(const complex<_Tp>& __x)
11050b57cec5SDimitry Andric{
1106*bdd1243dSDimitry Andric    return std::log(__x) / std::log(_Tp(10));
11070b57cec5SDimitry Andric}
11080b57cec5SDimitry Andric
11090b57cec5SDimitry Andric// sqrt
11100b57cec5SDimitry Andric
11110b57cec5SDimitry Andrictemplate<class _Tp>
1112*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
11130b57cec5SDimitry Andricsqrt(const complex<_Tp>& __x)
11140b57cec5SDimitry Andric{
1115*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
11160b57cec5SDimitry Andric        return complex<_Tp>(_Tp(INFINITY), __x.imag());
1117*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
11180b57cec5SDimitry Andric    {
11190b57cec5SDimitry Andric        if (__x.real() > _Tp(0))
1120*bdd1243dSDimitry Andric            return complex<_Tp>(__x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag()));
1121*bdd1243dSDimitry Andric        return complex<_Tp>(std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag()));
11220b57cec5SDimitry Andric    }
1123*bdd1243dSDimitry Andric    return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2));
11240b57cec5SDimitry Andric}
11250b57cec5SDimitry Andric
11260b57cec5SDimitry Andric// exp
11270b57cec5SDimitry Andric
11280b57cec5SDimitry Andrictemplate<class _Tp>
1129*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
11300b57cec5SDimitry Andricexp(const complex<_Tp>& __x)
11310b57cec5SDimitry Andric{
11320b57cec5SDimitry Andric    _Tp __i = __x.imag();
1133349cc55cSDimitry Andric    if (__i == 0) {
1134*bdd1243dSDimitry Andric        return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag()));
1135349cc55cSDimitry Andric    }
1136*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
11370b57cec5SDimitry Andric    {
11380b57cec5SDimitry Andric        if (__x.real() < _Tp(0))
11390b57cec5SDimitry Andric        {
1140*bdd1243dSDimitry Andric            if (!std::__constexpr_isfinite(__i))
11410b57cec5SDimitry Andric                __i = _Tp(1);
11420b57cec5SDimitry Andric        }
1143*bdd1243dSDimitry Andric        else if (__i == 0 || !std::__constexpr_isfinite(__i))
11440b57cec5SDimitry Andric        {
1145*bdd1243dSDimitry Andric            if (std::__constexpr_isinf(__i))
11460b57cec5SDimitry Andric                __i = _Tp(NAN);
11470b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), __i);
11480b57cec5SDimitry Andric        }
11490b57cec5SDimitry Andric    }
1150*bdd1243dSDimitry Andric    _Tp __e = std::exp(__x.real());
1151*bdd1243dSDimitry Andric    return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i));
11520b57cec5SDimitry Andric}
11530b57cec5SDimitry Andric
11540b57cec5SDimitry Andric// pow
11550b57cec5SDimitry Andric
11560b57cec5SDimitry Andrictemplate<class _Tp>
11570b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11580b57cec5SDimitry Andriccomplex<_Tp>
11590b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Tp>& __y)
11600b57cec5SDimitry Andric{
1161*bdd1243dSDimitry Andric    return std::exp(__y * std::log(__x));
11620b57cec5SDimitry Andric}
11630b57cec5SDimitry Andric
11640b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
11650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11660b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type>
11670b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y)
11680b57cec5SDimitry Andric{
11690b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11700b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
11710b57cec5SDimitry Andric}
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
11740b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11750b57cec5SDimitry Andrictypename enable_if
11760b57cec5SDimitry Andric<
11770b57cec5SDimitry Andric    is_arithmetic<_Up>::value,
11780b57cec5SDimitry Andric    complex<typename __promote<_Tp, _Up>::type>
11790b57cec5SDimitry Andric>::type
11800b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const _Up& __y)
11810b57cec5SDimitry Andric{
11820b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11830b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
11840b57cec5SDimitry Andric}
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
11870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11880b57cec5SDimitry Andrictypename enable_if
11890b57cec5SDimitry Andric<
11900b57cec5SDimitry Andric    is_arithmetic<_Tp>::value,
11910b57cec5SDimitry Andric    complex<typename __promote<_Tp, _Up>::type>
11920b57cec5SDimitry Andric>::type
11930b57cec5SDimitry Andricpow(const _Tp& __x, const complex<_Up>& __y)
11940b57cec5SDimitry Andric{
11950b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11960b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
11970b57cec5SDimitry Andric}
11980b57cec5SDimitry Andric
11990b57cec5SDimitry Andric// __sqr, computes pow(x, 2)
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andrictemplate<class _Tp>
12020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
12030b57cec5SDimitry Andriccomplex<_Tp>
12040b57cec5SDimitry Andric__sqr(const complex<_Tp>& __x)
12050b57cec5SDimitry Andric{
12060b57cec5SDimitry Andric    return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
12070b57cec5SDimitry Andric                        _Tp(2) * __x.real() * __x.imag());
12080b57cec5SDimitry Andric}
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andric// asinh
12110b57cec5SDimitry Andric
12120b57cec5SDimitry Andrictemplate<class _Tp>
1213*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
12140b57cec5SDimitry Andricasinh(const complex<_Tp>& __x)
12150b57cec5SDimitry Andric{
12160b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1217*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
12180b57cec5SDimitry Andric    {
1219*bdd1243dSDimitry Andric        if (std::__constexpr_isnan(__x.imag()))
12200b57cec5SDimitry Andric            return __x;
1221*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
1222*bdd1243dSDimitry Andric            return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
1223*bdd1243dSDimitry Andric        return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
12240b57cec5SDimitry Andric    }
1225*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.real()))
12260b57cec5SDimitry Andric    {
1227*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
12280b57cec5SDimitry Andric            return complex<_Tp>(__x.imag(), __x.real());
12290b57cec5SDimitry Andric        if (__x.imag() == 0)
12300b57cec5SDimitry Andric            return __x;
12310b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
12320b57cec5SDimitry Andric    }
1233*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
1234*bdd1243dSDimitry Andric        return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
1235*bdd1243dSDimitry Andric    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
1236*bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
12370b57cec5SDimitry Andric}
12380b57cec5SDimitry Andric
12390b57cec5SDimitry Andric// acosh
12400b57cec5SDimitry Andric
12410b57cec5SDimitry Andrictemplate<class _Tp>
1242*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
12430b57cec5SDimitry Andricacosh(const complex<_Tp>& __x)
12440b57cec5SDimitry Andric{
12450b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1246*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
12470b57cec5SDimitry Andric    {
1248*bdd1243dSDimitry Andric        if (std::__constexpr_isnan(__x.imag()))
1249*bdd1243dSDimitry Andric            return complex<_Tp>(std::abs(__x.real()), __x.imag());
1250*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
12510b57cec5SDimitry Andric        {
12520b57cec5SDimitry Andric            if (__x.real() > 0)
1253*bdd1243dSDimitry Andric                return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
12540b57cec5SDimitry Andric            else
1255*bdd1243dSDimitry Andric                return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
12560b57cec5SDimitry Andric        }
12570b57cec5SDimitry Andric        if (__x.real() < 0)
1258*bdd1243dSDimitry Andric            return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
1259*bdd1243dSDimitry Andric        return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
12600b57cec5SDimitry Andric    }
1261*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.real()))
12620b57cec5SDimitry Andric    {
1263*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
1264*bdd1243dSDimitry Andric            return complex<_Tp>(std::abs(__x.imag()), __x.real());
12650b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
12660b57cec5SDimitry Andric    }
1267*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
1268*bdd1243dSDimitry Andric        return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi/_Tp(2), __x.imag()));
1269*bdd1243dSDimitry Andric    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1270*bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
12710b57cec5SDimitry Andric}
12720b57cec5SDimitry Andric
12730b57cec5SDimitry Andric// atanh
12740b57cec5SDimitry Andric
12750b57cec5SDimitry Andrictemplate<class _Tp>
1276*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
12770b57cec5SDimitry Andricatanh(const complex<_Tp>& __x)
12780b57cec5SDimitry Andric{
12790b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1280*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
12810b57cec5SDimitry Andric    {
1282*bdd1243dSDimitry Andric        return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
12830b57cec5SDimitry Andric    }
1284*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.imag()))
12850b57cec5SDimitry Andric    {
1286*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.real()) || __x.real() == 0)
1287*bdd1243dSDimitry Andric            return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
12880b57cec5SDimitry Andric        return complex<_Tp>(__x.imag(), __x.imag());
12890b57cec5SDimitry Andric    }
1290*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.real()))
12910b57cec5SDimitry Andric    {
12920b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
12930b57cec5SDimitry Andric    }
1294*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
12950b57cec5SDimitry Andric    {
1296*bdd1243dSDimitry Andric        return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag()));
12970b57cec5SDimitry Andric    }
1298*bdd1243dSDimitry Andric    if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
12990b57cec5SDimitry Andric    {
1300*bdd1243dSDimitry Andric        return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
13010b57cec5SDimitry Andric    }
1302*bdd1243dSDimitry Andric    complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1303*bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
13040b57cec5SDimitry Andric}
13050b57cec5SDimitry Andric
13060b57cec5SDimitry Andric// sinh
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andrictemplate<class _Tp>
1309*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
13100b57cec5SDimitry Andricsinh(const complex<_Tp>& __x)
13110b57cec5SDimitry Andric{
1312*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
13130b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), _Tp(NAN));
1314*bdd1243dSDimitry Andric    if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
13150b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), _Tp(NAN));
1316*bdd1243dSDimitry Andric    if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
13170b57cec5SDimitry Andric        return __x;
1318*bdd1243dSDimitry Andric    return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag()));
13190b57cec5SDimitry Andric}
13200b57cec5SDimitry Andric
13210b57cec5SDimitry Andric// cosh
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andrictemplate<class _Tp>
1324*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
13250b57cec5SDimitry Andriccosh(const complex<_Tp>& __x)
13260b57cec5SDimitry Andric{
1327*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
1328*bdd1243dSDimitry Andric        return complex<_Tp>(std::abs(__x.real()), _Tp(NAN));
1329*bdd1243dSDimitry Andric    if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
13300b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), __x.real());
13310b57cec5SDimitry Andric    if (__x.real() == 0 && __x.imag() == 0)
13320b57cec5SDimitry Andric        return complex<_Tp>(_Tp(1), __x.imag());
1333*bdd1243dSDimitry Andric    if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
1334*bdd1243dSDimitry Andric        return complex<_Tp>(std::abs(__x.real()), __x.imag());
1335*bdd1243dSDimitry Andric    return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag()));
13360b57cec5SDimitry Andric}
13370b57cec5SDimitry Andric
13380b57cec5SDimitry Andric// tanh
13390b57cec5SDimitry Andric
13400b57cec5SDimitry Andrictemplate<class _Tp>
1341*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
13420b57cec5SDimitry Andrictanh(const complex<_Tp>& __x)
13430b57cec5SDimitry Andric{
1344*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
13450b57cec5SDimitry Andric    {
1346*bdd1243dSDimitry Andric        if (!std::__constexpr_isfinite(__x.imag()))
1347*bdd1243dSDimitry Andric            return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0));
1348*bdd1243dSDimitry Andric        return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag())));
13490b57cec5SDimitry Andric    }
1350*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0)
13510b57cec5SDimitry Andric        return __x;
13520b57cec5SDimitry Andric    _Tp __2r(_Tp(2) * __x.real());
13530b57cec5SDimitry Andric    _Tp __2i(_Tp(2) * __x.imag());
1354*bdd1243dSDimitry Andric    _Tp __d(std::cosh(__2r) + std::cos(__2i));
1355*bdd1243dSDimitry Andric    _Tp __2rsh(std::sinh(__2r));
1356*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d))
13570b57cec5SDimitry Andric        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
13580b57cec5SDimitry Andric                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1359*bdd1243dSDimitry Andric    return  complex<_Tp>(__2rsh/__d, std::sin(__2i)/__d);
13600b57cec5SDimitry Andric}
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andric// asin
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andrictemplate<class _Tp>
1365*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
13660b57cec5SDimitry Andricasin(const complex<_Tp>& __x)
13670b57cec5SDimitry Andric{
1368*bdd1243dSDimitry Andric    complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real()));
13690b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
13700b57cec5SDimitry Andric}
13710b57cec5SDimitry Andric
13720b57cec5SDimitry Andric// acos
13730b57cec5SDimitry Andric
13740b57cec5SDimitry Andrictemplate<class _Tp>
1375*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
13760b57cec5SDimitry Andricacos(const complex<_Tp>& __x)
13770b57cec5SDimitry Andric{
13780b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1379*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()))
13800b57cec5SDimitry Andric    {
1381*bdd1243dSDimitry Andric        if (std::__constexpr_isnan(__x.imag()))
13820b57cec5SDimitry Andric            return complex<_Tp>(__x.imag(), __x.real());
1383*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
13840b57cec5SDimitry Andric        {
13850b57cec5SDimitry Andric            if (__x.real() < _Tp(0))
13860b57cec5SDimitry Andric                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
13870b57cec5SDimitry Andric            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
13880b57cec5SDimitry Andric        }
13890b57cec5SDimitry Andric        if (__x.real() < _Tp(0))
1390*bdd1243dSDimitry Andric            return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real());
1391*bdd1243dSDimitry Andric        return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real());
13920b57cec5SDimitry Andric    }
1393*bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.real()))
13940b57cec5SDimitry Andric    {
1395*bdd1243dSDimitry Andric        if (std::__constexpr_isinf(__x.imag()))
13960b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), -__x.imag());
13970b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
13980b57cec5SDimitry Andric    }
1399*bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
14000b57cec5SDimitry Andric        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1401*bdd1243dSDimitry Andric    if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag())))
14020b57cec5SDimitry Andric        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1403*bdd1243dSDimitry Andric    complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1404*bdd1243dSDimitry Andric    if (std::signbit(__x.imag()))
1405*bdd1243dSDimitry Andric        return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real()));
1406*bdd1243dSDimitry Andric    return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real()));
14070b57cec5SDimitry Andric}
14080b57cec5SDimitry Andric
14090b57cec5SDimitry Andric// atan
14100b57cec5SDimitry Andric
14110b57cec5SDimitry Andrictemplate<class _Tp>
1412*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
14130b57cec5SDimitry Andricatan(const complex<_Tp>& __x)
14140b57cec5SDimitry Andric{
1415*bdd1243dSDimitry Andric    complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real()));
14160b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
14170b57cec5SDimitry Andric}
14180b57cec5SDimitry Andric
14190b57cec5SDimitry Andric// sin
14200b57cec5SDimitry Andric
14210b57cec5SDimitry Andrictemplate<class _Tp>
1422*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
14230b57cec5SDimitry Andricsin(const complex<_Tp>& __x)
14240b57cec5SDimitry Andric{
1425*bdd1243dSDimitry Andric    complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real()));
14260b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
14270b57cec5SDimitry Andric}
14280b57cec5SDimitry Andric
14290b57cec5SDimitry Andric// cos
14300b57cec5SDimitry Andric
14310b57cec5SDimitry Andrictemplate<class _Tp>
14320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
14330b57cec5SDimitry Andriccomplex<_Tp>
14340b57cec5SDimitry Andriccos(const complex<_Tp>& __x)
14350b57cec5SDimitry Andric{
1436*bdd1243dSDimitry Andric    return std::cosh(complex<_Tp>(-__x.imag(), __x.real()));
14370b57cec5SDimitry Andric}
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andric// tan
14400b57cec5SDimitry Andric
14410b57cec5SDimitry Andrictemplate<class _Tp>
1442*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp>
14430b57cec5SDimitry Andrictan(const complex<_Tp>& __x)
14440b57cec5SDimitry Andric{
1445*bdd1243dSDimitry Andric    complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real()));
14460b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
14470b57cec5SDimitry Andric}
14480b57cec5SDimitry Andric
1449*bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
14500b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits>
1451*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
14520b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
14530b57cec5SDimitry Andric{
14540b57cec5SDimitry Andric    if (__is.good())
14550b57cec5SDimitry Andric    {
1456*bdd1243dSDimitry Andric        std::ws(__is);
14570b57cec5SDimitry Andric        if (__is.peek() == _CharT('('))
14580b57cec5SDimitry Andric        {
14590b57cec5SDimitry Andric            __is.get();
14600b57cec5SDimitry Andric            _Tp __r;
14610b57cec5SDimitry Andric            __is >> __r;
14620b57cec5SDimitry Andric            if (!__is.fail())
14630b57cec5SDimitry Andric            {
1464*bdd1243dSDimitry Andric                std::ws(__is);
14650b57cec5SDimitry Andric                _CharT __c = __is.peek();
14660b57cec5SDimitry Andric                if (__c == _CharT(','))
14670b57cec5SDimitry Andric                {
14680b57cec5SDimitry Andric                    __is.get();
14690b57cec5SDimitry Andric                    _Tp __i;
14700b57cec5SDimitry Andric                    __is >> __i;
14710b57cec5SDimitry Andric                    if (!__is.fail())
14720b57cec5SDimitry Andric                    {
1473*bdd1243dSDimitry Andric                        std::ws(__is);
14740b57cec5SDimitry Andric                        __c = __is.peek();
14750b57cec5SDimitry Andric                        if (__c == _CharT(')'))
14760b57cec5SDimitry Andric                        {
14770b57cec5SDimitry Andric                            __is.get();
14780b57cec5SDimitry Andric                            __x = complex<_Tp>(__r, __i);
14790b57cec5SDimitry Andric                        }
14800b57cec5SDimitry Andric                        else
14815ffd83dbSDimitry Andric                            __is.setstate(__is.failbit);
14820b57cec5SDimitry Andric                    }
14830b57cec5SDimitry Andric                    else
14845ffd83dbSDimitry Andric                        __is.setstate(__is.failbit);
14850b57cec5SDimitry Andric                }
14860b57cec5SDimitry Andric                else if (__c == _CharT(')'))
14870b57cec5SDimitry Andric                {
14880b57cec5SDimitry Andric                    __is.get();
14890b57cec5SDimitry Andric                    __x = complex<_Tp>(__r, _Tp(0));
14900b57cec5SDimitry Andric                }
14910b57cec5SDimitry Andric                else
14925ffd83dbSDimitry Andric                    __is.setstate(__is.failbit);
14930b57cec5SDimitry Andric            }
14940b57cec5SDimitry Andric            else
14955ffd83dbSDimitry Andric                __is.setstate(__is.failbit);
14960b57cec5SDimitry Andric        }
14970b57cec5SDimitry Andric        else
14980b57cec5SDimitry Andric        {
14990b57cec5SDimitry Andric            _Tp __r;
15000b57cec5SDimitry Andric            __is >> __r;
15010b57cec5SDimitry Andric            if (!__is.fail())
15020b57cec5SDimitry Andric                __x = complex<_Tp>(__r, _Tp(0));
15030b57cec5SDimitry Andric            else
15045ffd83dbSDimitry Andric                __is.setstate(__is.failbit);
15050b57cec5SDimitry Andric        }
15060b57cec5SDimitry Andric    }
15070b57cec5SDimitry Andric    else
15085ffd83dbSDimitry Andric        __is.setstate(__is.failbit);
15090b57cec5SDimitry Andric    return __is;
15100b57cec5SDimitry Andric}
15110b57cec5SDimitry Andric
15120b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits>
1513*bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
15140b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
15150b57cec5SDimitry Andric{
15160b57cec5SDimitry Andric    basic_ostringstream<_CharT, _Traits> __s;
15170b57cec5SDimitry Andric    __s.flags(__os.flags());
15180b57cec5SDimitry Andric    __s.imbue(__os.getloc());
15190b57cec5SDimitry Andric    __s.precision(__os.precision());
15200b57cec5SDimitry Andric    __s << '(' << __x.real() << ',' << __x.imag() << ')';
15210b57cec5SDimitry Andric    return __os << __s.str();
15220b57cec5SDimitry Andric}
1523e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION
15240b57cec5SDimitry Andric
15250b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
15260b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals]
15270b57cec5SDimitry Andricinline namespace literals
15280b57cec5SDimitry Andric{
15290b57cec5SDimitry Andric  inline namespace complex_literals
15300b57cec5SDimitry Andric  {
1531*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<long double> operator""il(long double __im)
15320b57cec5SDimitry Andric    {
15330b57cec5SDimitry Andric        return { 0.0l, __im };
15340b57cec5SDimitry Andric    }
15350b57cec5SDimitry Andric
1536*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<long double> operator""il(unsigned long long __im)
15370b57cec5SDimitry Andric    {
15380b57cec5SDimitry Andric        return { 0.0l, static_cast<long double>(__im) };
15390b57cec5SDimitry Andric    }
15400b57cec5SDimitry Andric
15410b57cec5SDimitry Andric
1542*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<double> operator""i(long double __im)
15430b57cec5SDimitry Andric    {
15440b57cec5SDimitry Andric        return { 0.0, static_cast<double>(__im) };
15450b57cec5SDimitry Andric    }
15460b57cec5SDimitry Andric
1547*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<double> operator""i(unsigned long long __im)
15480b57cec5SDimitry Andric    {
15490b57cec5SDimitry Andric        return { 0.0, static_cast<double>(__im) };
15500b57cec5SDimitry Andric    }
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric
1553*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<float> operator""if(long double __im)
15540b57cec5SDimitry Andric    {
15550b57cec5SDimitry Andric        return { 0.0f, static_cast<float>(__im) };
15560b57cec5SDimitry Andric    }
15570b57cec5SDimitry Andric
1558*bdd1243dSDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr complex<float> operator""if(unsigned long long __im)
15590b57cec5SDimitry Andric    {
15600b57cec5SDimitry Andric        return { 0.0f, static_cast<float>(__im) };
15610b57cec5SDimitry Andric    }
15620eae32dcSDimitry Andric  } // namespace complex_literals
15630eae32dcSDimitry Andric} // namespace literals
15640b57cec5SDimitry Andric#endif
15650b57cec5SDimitry Andric
15660b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
15670b57cec5SDimitry Andric
15680b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX
1569