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 32bdd1243dSDimitry Andric void real(T); // constexpr in C++20 33bdd1243dSDimitry Andric void imag(T); // constexpr in C++20 340b57cec5SDimitry Andric 35bdd1243dSDimitry Andric complex<T>& operator= (const T&); // constexpr in C++20 36bdd1243dSDimitry Andric complex<T>& operator+=(const T&); // constexpr in C++20 37bdd1243dSDimitry Andric complex<T>& operator-=(const T&); // constexpr in C++20 38bdd1243dSDimitry Andric complex<T>& operator*=(const T&); // constexpr in C++20 39bdd1243dSDimitry Andric complex<T>& operator/=(const T&); // constexpr in C++20 400b57cec5SDimitry Andric 41bdd1243dSDimitry Andric complex& operator=(const complex&); // constexpr in C++20 42bdd1243dSDimitry Andric template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20 43bdd1243dSDimitry Andric template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20 44bdd1243dSDimitry Andric template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20 45bdd1243dSDimitry Andric template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20 46bdd1243dSDimitry 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; 60bdd1243dSDimitry Andric void real(float); // constexpr in C++20 610b57cec5SDimitry Andric constexpr float imag() const; 62bdd1243dSDimitry Andric void imag(float); // constexpr in C++20 630b57cec5SDimitry Andric 64bdd1243dSDimitry Andric complex<float>& operator= (float); // constexpr in C++20 65bdd1243dSDimitry Andric complex<float>& operator+=(float); // constexpr in C++20 66bdd1243dSDimitry Andric complex<float>& operator-=(float); // constexpr in C++20 67bdd1243dSDimitry Andric complex<float>& operator*=(float); // constexpr in C++20 68bdd1243dSDimitry Andric complex<float>& operator/=(float); // constexpr in C++20 690b57cec5SDimitry Andric 70bdd1243dSDimitry Andric complex<float>& operator=(const complex<float>&); // constexpr in C++20 71bdd1243dSDimitry Andric template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20 72bdd1243dSDimitry Andric template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20 73bdd1243dSDimitry Andric template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20 74bdd1243dSDimitry Andric template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20 75bdd1243dSDimitry 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; 89bdd1243dSDimitry Andric void real(double); // constexpr in C++20 900b57cec5SDimitry Andric constexpr double imag() const; 91bdd1243dSDimitry Andric void imag(double); // constexpr in C++20 920b57cec5SDimitry Andric 93bdd1243dSDimitry Andric complex<double>& operator= (double); // constexpr in C++20 94bdd1243dSDimitry Andric complex<double>& operator+=(double); // constexpr in C++20 95bdd1243dSDimitry Andric complex<double>& operator-=(double); // constexpr in C++20 96bdd1243dSDimitry Andric complex<double>& operator*=(double); // constexpr in C++20 97bdd1243dSDimitry Andric complex<double>& operator/=(double); // constexpr in C++20 98bdd1243dSDimitry Andric complex<double>& operator=(const complex<double>&); // constexpr in C++20 990b57cec5SDimitry Andric 100bdd1243dSDimitry Andric template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20 101bdd1243dSDimitry Andric template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20 102bdd1243dSDimitry Andric template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20 103bdd1243dSDimitry Andric template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20 104bdd1243dSDimitry 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; 118bdd1243dSDimitry Andric void real(long double); // constexpr in C++20 1190b57cec5SDimitry Andric constexpr long double imag() const; 120bdd1243dSDimitry Andric void imag(long double); // constexpr in C++20 1210b57cec5SDimitry Andric 122bdd1243dSDimitry Andric complex<long double>& operator=(const complex<long double>&); // constexpr in C++20 123bdd1243dSDimitry Andric complex<long double>& operator= (long double); // constexpr in C++20 124bdd1243dSDimitry Andric complex<long double>& operator+=(long double); // constexpr in C++20 125bdd1243dSDimitry Andric complex<long double>& operator-=(long double); // constexpr in C++20 126bdd1243dSDimitry Andric complex<long double>& operator*=(long double); // constexpr in C++20 127bdd1243dSDimitry Andric complex<long double>& operator/=(long double); // constexpr in C++20 1280b57cec5SDimitry Andric 129bdd1243dSDimitry Andric template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20 130bdd1243dSDimitry Andric template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20 131bdd1243dSDimitry Andric template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20 132bdd1243dSDimitry Andric template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20 133bdd1243dSDimitry 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: 137bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20 138bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const T&); // constexpr in C++20 139bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const T&, const complex<T>&); // constexpr in C++20 140bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20 141bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const T&); // constexpr in C++20 142bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const T&, const complex<T>&); // constexpr in C++20 143bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20 144bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const T&); // constexpr in C++20 145bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const T&, const complex<T>&); // constexpr in C++20 146bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20 147bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const T&); // constexpr in C++20 148bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++20 149bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&); // constexpr in C++20 150bdd1243dSDimitry 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 15306c3fb27SDimitry Andrictemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14, removed in C++20 15406c3fb27SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14, removed in C++20 15506c3fb27SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14, removed in C++20 15606c3fb27SDimitry Andrictemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14, removed in C++20 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 187bdd1243dSDimitry Andrictemplate<class T> T norm(const complex<T>&); // constexpr in C++20 188bdd1243dSDimitry Andric long double norm(long double); // constexpr in C++20 189bdd1243dSDimitry Andric double norm(double); // constexpr in C++20 190bdd1243dSDimitry Andrictemplate<Integral T> double norm(T); // constexpr in C++20 191bdd1243dSDimitry Andric float norm(float); // constexpr in C++20 1920b57cec5SDimitry Andric 193bdd1243dSDimitry Andrictemplate<class T> complex<T> conj(const complex<T>&); // constexpr in C++20 194bdd1243dSDimitry Andric complex<long double> conj(long double); // constexpr in C++20 195bdd1243dSDimitry Andric complex<double> conj(double); // constexpr in C++20 196bdd1243dSDimitry Andrictemplate<Integral T> complex<double> conj(T); // constexpr in C++20 197bdd1243dSDimitry 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> 2370b57cec5SDimitry Andric#include <version> 2380b57cec5SDimitry Andric 239e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 240e8d8bef9SDimitry Andric# include <sstream> // for std::basic_ostringstream 241e8d8bef9SDimitry Andric#endif 242e8d8bef9SDimitry Andric 2430b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2440b57cec5SDimitry Andric# pragma GCC system_header 2450b57cec5SDimitry Andric#endif 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2480b57cec5SDimitry Andric 249*cb14a3feSDimitry Andrictemplate <class _Tp> 250*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andrictemplate <class _Tp> 253*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 254*cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 255*cb14a3feSDimitry Andrictemplate <class _Tp> 256*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 257*cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 258*cb14a3feSDimitry Andric 259*cb14a3feSDimitry Andrictemplate <class _Tp> 260*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex { 2610b57cec5SDimitry Andricpublic: 2620b57cec5SDimitry Andric typedef _Tp value_type; 263*cb14a3feSDimitry Andric 2640b57cec5SDimitry Andricprivate: 2650b57cec5SDimitry Andric value_type __re_; 2660b57cec5SDimitry Andric value_type __im_; 267*cb14a3feSDimitry Andric 2680b57cec5SDimitry Andricpublic: 2695f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 2700b57cec5SDimitry Andric complex(const value_type& __re = value_type(), const value_type& __im = value_type()) 2710b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 272*cb14a3feSDimitry Andric template <class _Xp> 273*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 complex(const complex<_Xp>& __c) 2740b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 2750b57cec5SDimitry Andric 2765f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const { return __re_; } 2775f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const { return __im_; } 2780b57cec5SDimitry Andric 2795f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 2805f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 2810b57cec5SDimitry Andric 282*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const value_type& __re) { 283*cb14a3feSDimitry Andric __re_ = __re; 284*cb14a3feSDimitry Andric __im_ = value_type(); 285*cb14a3feSDimitry Andric return *this; 286*cb14a3feSDimitry Andric } 287*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) { 288*cb14a3feSDimitry Andric __re_ += __re; 289*cb14a3feSDimitry Andric return *this; 290*cb14a3feSDimitry Andric } 291*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) { 292*cb14a3feSDimitry Andric __re_ -= __re; 293*cb14a3feSDimitry Andric return *this; 294*cb14a3feSDimitry Andric } 295*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) { 296*cb14a3feSDimitry Andric __re_ *= __re; 297*cb14a3feSDimitry Andric __im_ *= __re; 298*cb14a3feSDimitry Andric return *this; 299*cb14a3feSDimitry Andric } 300*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) { 301*cb14a3feSDimitry Andric __re_ /= __re; 302*cb14a3feSDimitry Andric __im_ /= __re; 303*cb14a3feSDimitry Andric return *this; 304*cb14a3feSDimitry Andric } 3050b57cec5SDimitry Andric 306*cb14a3feSDimitry Andric template <class _Xp> 307*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 3080b57cec5SDimitry Andric __re_ = __c.real(); 3090b57cec5SDimitry Andric __im_ = __c.imag(); 3100b57cec5SDimitry Andric return *this; 3110b57cec5SDimitry Andric } 312*cb14a3feSDimitry Andric template <class _Xp> 313*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 3140b57cec5SDimitry Andric __re_ += __c.real(); 3150b57cec5SDimitry Andric __im_ += __c.imag(); 3160b57cec5SDimitry Andric return *this; 3170b57cec5SDimitry Andric } 318*cb14a3feSDimitry Andric template <class _Xp> 319*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 3200b57cec5SDimitry Andric __re_ -= __c.real(); 3210b57cec5SDimitry Andric __im_ -= __c.imag(); 3220b57cec5SDimitry Andric return *this; 3230b57cec5SDimitry Andric } 324*cb14a3feSDimitry Andric template <class _Xp> 325*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 3260b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3270b57cec5SDimitry Andric return *this; 3280b57cec5SDimitry Andric } 329*cb14a3feSDimitry Andric template <class _Xp> 330*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 3310b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3320b57cec5SDimitry Andric return *this; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric}; 3350b57cec5SDimitry Andric 336*cb14a3feSDimitry Andrictemplate <> 337*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double>; 338*cb14a3feSDimitry Andrictemplate <> 339*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double>; 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andrictemplate <> 342*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float> { 3430b57cec5SDimitry Andric float __re_; 3440b57cec5SDimitry Andric float __im_; 345*cb14a3feSDimitry Andric 3460b57cec5SDimitry Andricpublic: 3470b57cec5SDimitry Andric typedef float value_type; 3480b57cec5SDimitry Andric 349*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {} 350*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 351*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 3520b57cec5SDimitry Andric 3535f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; } 3545f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; } 3550b57cec5SDimitry Andric 3565f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 3575f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 3580b57cec5SDimitry Andric 359*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(float __re) { 360*cb14a3feSDimitry Andric __re_ = __re; 361*cb14a3feSDimitry Andric __im_ = value_type(); 362*cb14a3feSDimitry Andric return *this; 363*cb14a3feSDimitry Andric } 364*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) { 365*cb14a3feSDimitry Andric __re_ += __re; 366*cb14a3feSDimitry Andric return *this; 367*cb14a3feSDimitry Andric } 368*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) { 369*cb14a3feSDimitry Andric __re_ -= __re; 370*cb14a3feSDimitry Andric return *this; 371*cb14a3feSDimitry Andric } 372*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) { 373*cb14a3feSDimitry Andric __re_ *= __re; 374*cb14a3feSDimitry Andric __im_ *= __re; 375*cb14a3feSDimitry Andric return *this; 376*cb14a3feSDimitry Andric } 377*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) { 378*cb14a3feSDimitry Andric __re_ /= __re; 379*cb14a3feSDimitry Andric __im_ /= __re; 380*cb14a3feSDimitry Andric return *this; 381*cb14a3feSDimitry Andric } 3820b57cec5SDimitry Andric 383*cb14a3feSDimitry Andric template <class _Xp> 384*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 3850b57cec5SDimitry Andric __re_ = __c.real(); 3860b57cec5SDimitry Andric __im_ = __c.imag(); 3870b57cec5SDimitry Andric return *this; 3880b57cec5SDimitry Andric } 389*cb14a3feSDimitry Andric template <class _Xp> 390*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 3910b57cec5SDimitry Andric __re_ += __c.real(); 3920b57cec5SDimitry Andric __im_ += __c.imag(); 3930b57cec5SDimitry Andric return *this; 3940b57cec5SDimitry Andric } 395*cb14a3feSDimitry Andric template <class _Xp> 396*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 3970b57cec5SDimitry Andric __re_ -= __c.real(); 3980b57cec5SDimitry Andric __im_ -= __c.imag(); 3990b57cec5SDimitry Andric return *this; 4000b57cec5SDimitry Andric } 401*cb14a3feSDimitry Andric template <class _Xp> 402*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 4030b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4040b57cec5SDimitry Andric return *this; 4050b57cec5SDimitry Andric } 406*cb14a3feSDimitry Andric template <class _Xp> 407*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 4080b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4090b57cec5SDimitry Andric return *this; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric}; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andrictemplate <> 414*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> { 4150b57cec5SDimitry Andric double __re_; 4160b57cec5SDimitry Andric double __im_; 417*cb14a3feSDimitry Andric 4180b57cec5SDimitry Andricpublic: 4190b57cec5SDimitry Andric typedef double value_type; 4200b57cec5SDimitry Andric 421*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {} 422*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 423*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 4240b57cec5SDimitry Andric 4255f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; } 4265f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; } 4270b57cec5SDimitry Andric 4285f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 4295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 4300b57cec5SDimitry Andric 431*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(double __re) { 432*cb14a3feSDimitry Andric __re_ = __re; 433*cb14a3feSDimitry Andric __im_ = value_type(); 434*cb14a3feSDimitry Andric return *this; 435*cb14a3feSDimitry Andric } 436*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) { 437*cb14a3feSDimitry Andric __re_ += __re; 438*cb14a3feSDimitry Andric return *this; 439*cb14a3feSDimitry Andric } 440*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) { 441*cb14a3feSDimitry Andric __re_ -= __re; 442*cb14a3feSDimitry Andric return *this; 443*cb14a3feSDimitry Andric } 444*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) { 445*cb14a3feSDimitry Andric __re_ *= __re; 446*cb14a3feSDimitry Andric __im_ *= __re; 447*cb14a3feSDimitry Andric return *this; 448*cb14a3feSDimitry Andric } 449*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) { 450*cb14a3feSDimitry Andric __re_ /= __re; 451*cb14a3feSDimitry Andric __im_ /= __re; 452*cb14a3feSDimitry Andric return *this; 453*cb14a3feSDimitry Andric } 4540b57cec5SDimitry Andric 455*cb14a3feSDimitry Andric template <class _Xp> 456*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 4570b57cec5SDimitry Andric __re_ = __c.real(); 4580b57cec5SDimitry Andric __im_ = __c.imag(); 4590b57cec5SDimitry Andric return *this; 4600b57cec5SDimitry Andric } 461*cb14a3feSDimitry Andric template <class _Xp> 462*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 4630b57cec5SDimitry Andric __re_ += __c.real(); 4640b57cec5SDimitry Andric __im_ += __c.imag(); 4650b57cec5SDimitry Andric return *this; 4660b57cec5SDimitry Andric } 467*cb14a3feSDimitry Andric template <class _Xp> 468*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 4690b57cec5SDimitry Andric __re_ -= __c.real(); 4700b57cec5SDimitry Andric __im_ -= __c.imag(); 4710b57cec5SDimitry Andric return *this; 4720b57cec5SDimitry Andric } 473*cb14a3feSDimitry Andric template <class _Xp> 474*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 4750b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4760b57cec5SDimitry Andric return *this; 4770b57cec5SDimitry Andric } 478*cb14a3feSDimitry Andric template <class _Xp> 479*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 4800b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4810b57cec5SDimitry Andric return *this; 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric}; 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andrictemplate <> 486*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> { 4870b57cec5SDimitry Andric long double __re_; 4880b57cec5SDimitry Andric long double __im_; 489*cb14a3feSDimitry Andric 4900b57cec5SDimitry Andricpublic: 4910b57cec5SDimitry Andric typedef long double value_type; 4920b57cec5SDimitry Andric 4935f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) 4940b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 495*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 496*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 4970b57cec5SDimitry Andric 4985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; } 4995f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; } 5000b57cec5SDimitry Andric 5015f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 5025f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 5030b57cec5SDimitry Andric 504*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(long double __re) { 505*cb14a3feSDimitry Andric __re_ = __re; 506*cb14a3feSDimitry Andric __im_ = value_type(); 507*cb14a3feSDimitry Andric return *this; 508*cb14a3feSDimitry Andric } 509*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) { 510*cb14a3feSDimitry Andric __re_ += __re; 511*cb14a3feSDimitry Andric return *this; 512*cb14a3feSDimitry Andric } 513*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) { 514*cb14a3feSDimitry Andric __re_ -= __re; 515*cb14a3feSDimitry Andric return *this; 516*cb14a3feSDimitry Andric } 517*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) { 518*cb14a3feSDimitry Andric __re_ *= __re; 519*cb14a3feSDimitry Andric __im_ *= __re; 520*cb14a3feSDimitry Andric return *this; 521*cb14a3feSDimitry Andric } 522*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) { 523*cb14a3feSDimitry Andric __re_ /= __re; 524*cb14a3feSDimitry Andric __im_ /= __re; 525*cb14a3feSDimitry Andric return *this; 526*cb14a3feSDimitry Andric } 5270b57cec5SDimitry Andric 528*cb14a3feSDimitry Andric template <class _Xp> 529*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 5300b57cec5SDimitry Andric __re_ = __c.real(); 5310b57cec5SDimitry Andric __im_ = __c.imag(); 5320b57cec5SDimitry Andric return *this; 5330b57cec5SDimitry Andric } 534*cb14a3feSDimitry Andric template <class _Xp> 535*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 5360b57cec5SDimitry Andric __re_ += __c.real(); 5370b57cec5SDimitry Andric __im_ += __c.imag(); 5380b57cec5SDimitry Andric return *this; 5390b57cec5SDimitry Andric } 540*cb14a3feSDimitry Andric template <class _Xp> 541*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 5420b57cec5SDimitry Andric __re_ -= __c.real(); 5430b57cec5SDimitry Andric __im_ -= __c.imag(); 5440b57cec5SDimitry Andric return *this; 5450b57cec5SDimitry Andric } 546*cb14a3feSDimitry Andric template <class _Xp> 547*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 5480b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 5490b57cec5SDimitry Andric return *this; 5500b57cec5SDimitry Andric } 551*cb14a3feSDimitry Andric template <class _Xp> 552*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 5530b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 5540b57cec5SDimitry Andric return *this; 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric}; 5570b57cec5SDimitry Andric 558*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 559*cb14a3feSDimitry Andric 560*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c) 5610b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5620b57cec5SDimitry Andric 563*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 564*cb14a3feSDimitry Andric 565*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c) 5660b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5670b57cec5SDimitry Andric 568*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c) 5690b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5700b57cec5SDimitry Andric 571*cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c) 5720b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric// 26.3.6 operators: 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andrictemplate <class _Tp> 577*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 578*cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) { 5790b57cec5SDimitry Andric complex<_Tp> __t(__x); 5800b57cec5SDimitry Andric __t += __y; 5810b57cec5SDimitry Andric return __t; 5820b57cec5SDimitry Andric} 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andrictemplate <class _Tp> 585*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 586*cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) { 5870b57cec5SDimitry Andric complex<_Tp> __t(__x); 5880b57cec5SDimitry Andric __t += __y; 5890b57cec5SDimitry Andric return __t; 5900b57cec5SDimitry Andric} 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andrictemplate <class _Tp> 593*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 594*cb14a3feSDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) { 5950b57cec5SDimitry Andric complex<_Tp> __t(__y); 5960b57cec5SDimitry Andric __t += __x; 5970b57cec5SDimitry Andric return __t; 5980b57cec5SDimitry Andric} 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andrictemplate <class _Tp> 601*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 602*cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) { 6030b57cec5SDimitry Andric complex<_Tp> __t(__x); 6040b57cec5SDimitry Andric __t -= __y; 6050b57cec5SDimitry Andric return __t; 6060b57cec5SDimitry Andric} 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andrictemplate <class _Tp> 609*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 610*cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) { 6110b57cec5SDimitry Andric complex<_Tp> __t(__x); 6120b57cec5SDimitry Andric __t -= __y; 6130b57cec5SDimitry Andric return __t; 6140b57cec5SDimitry Andric} 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andrictemplate <class _Tp> 617*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 618*cb14a3feSDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) { 6190b57cec5SDimitry Andric complex<_Tp> __t(-__y); 6200b57cec5SDimitry Andric __t += __x; 6210b57cec5SDimitry Andric return __t; 6220b57cec5SDimitry Andric} 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andrictemplate <class _Tp> 625bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 626*cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) { 6270b57cec5SDimitry Andric _Tp __a = __z.real(); 6280b57cec5SDimitry Andric _Tp __b = __z.imag(); 6290b57cec5SDimitry Andric _Tp __c = __w.real(); 6300b57cec5SDimitry Andric _Tp __d = __w.imag(); 631bdd1243dSDimitry Andric 632bdd1243dSDimitry Andric // Avoid floating point operations that are invalid during constant evaluation 633bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) { 634bdd1243dSDimitry Andric bool __z_zero = __a == _Tp(0) && __b == _Tp(0); 635bdd1243dSDimitry Andric bool __w_zero = __c == _Tp(0) && __d == _Tp(0); 636bdd1243dSDimitry Andric bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b); 637bdd1243dSDimitry Andric bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d); 638*cb14a3feSDimitry Andric bool __z_nan = 639*cb14a3feSDimitry Andric !__z_inf && ((std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b)) || 640*cb14a3feSDimitry Andric (std::__constexpr_isnan(__a) && __b == _Tp(0)) || (__a == _Tp(0) && std::__constexpr_isnan(__b))); 641*cb14a3feSDimitry Andric bool __w_nan = 642*cb14a3feSDimitry Andric !__w_inf && ((std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d)) || 643*cb14a3feSDimitry Andric (std::__constexpr_isnan(__c) && __d == _Tp(0)) || (__c == _Tp(0) && std::__constexpr_isnan(__d))); 644bdd1243dSDimitry Andric if (__z_nan || __w_nan) { 645bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 646bdd1243dSDimitry Andric } 647bdd1243dSDimitry Andric if (__z_inf || __w_inf) { 648bdd1243dSDimitry Andric if (__z_zero || __w_zero) { 649bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 650bdd1243dSDimitry Andric } 651bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 652bdd1243dSDimitry Andric } 653bdd1243dSDimitry Andric bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b)); 654bdd1243dSDimitry Andric bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d)); 655bdd1243dSDimitry Andric if (__z_nonzero_nan || __w_nonzero_nan) { 656bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 657bdd1243dSDimitry Andric } 658bdd1243dSDimitry Andric } 659bdd1243dSDimitry Andric 6600b57cec5SDimitry Andric _Tp __ac = __a * __c; 6610b57cec5SDimitry Andric _Tp __bd = __b * __d; 6620b57cec5SDimitry Andric _Tp __ad = __a * __d; 6630b57cec5SDimitry Andric _Tp __bc = __b * __c; 6640b57cec5SDimitry Andric _Tp __x = __ac - __bd; 6650b57cec5SDimitry Andric _Tp __y = __ad + __bc; 666*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y)) { 6670b57cec5SDimitry Andric bool __recalc = false; 668*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) { 669bdd1243dSDimitry Andric __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a); 670bdd1243dSDimitry Andric __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b); 671bdd1243dSDimitry Andric if (std::__constexpr_isnan(__c)) 672bdd1243dSDimitry Andric __c = std::__constexpr_copysign(_Tp(0), __c); 673bdd1243dSDimitry Andric if (std::__constexpr_isnan(__d)) 674bdd1243dSDimitry Andric __d = std::__constexpr_copysign(_Tp(0), __d); 6750b57cec5SDimitry Andric __recalc = true; 6760b57cec5SDimitry Andric } 677*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d)) { 678bdd1243dSDimitry Andric __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c); 679bdd1243dSDimitry Andric __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d); 680bdd1243dSDimitry Andric if (std::__constexpr_isnan(__a)) 681bdd1243dSDimitry Andric __a = std::__constexpr_copysign(_Tp(0), __a); 682bdd1243dSDimitry Andric if (std::__constexpr_isnan(__b)) 683bdd1243dSDimitry Andric __b = std::__constexpr_copysign(_Tp(0), __b); 6840b57cec5SDimitry Andric __recalc = true; 6850b57cec5SDimitry Andric } 686*cb14a3feSDimitry Andric if (!__recalc && (std::__constexpr_isinf(__ac) || std::__constexpr_isinf(__bd) || std::__constexpr_isinf(__ad) || 687*cb14a3feSDimitry Andric std::__constexpr_isinf(__bc))) { 688bdd1243dSDimitry Andric if (std::__constexpr_isnan(__a)) 689bdd1243dSDimitry Andric __a = std::__constexpr_copysign(_Tp(0), __a); 690bdd1243dSDimitry Andric if (std::__constexpr_isnan(__b)) 691bdd1243dSDimitry Andric __b = std::__constexpr_copysign(_Tp(0), __b); 692bdd1243dSDimitry Andric if (std::__constexpr_isnan(__c)) 693bdd1243dSDimitry Andric __c = std::__constexpr_copysign(_Tp(0), __c); 694bdd1243dSDimitry Andric if (std::__constexpr_isnan(__d)) 695bdd1243dSDimitry Andric __d = std::__constexpr_copysign(_Tp(0), __d); 6960b57cec5SDimitry Andric __recalc = true; 6970b57cec5SDimitry Andric } 698*cb14a3feSDimitry Andric if (__recalc) { 6990b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c - __b * __d); 7000b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__a * __d + __b * __c); 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 7040b57cec5SDimitry Andric} 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andrictemplate <class _Tp> 707*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 708*cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) { 7090b57cec5SDimitry Andric complex<_Tp> __t(__x); 7100b57cec5SDimitry Andric __t *= __y; 7110b57cec5SDimitry Andric return __t; 7120b57cec5SDimitry Andric} 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andrictemplate <class _Tp> 715*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 716*cb14a3feSDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) { 7170b57cec5SDimitry Andric complex<_Tp> __t(__y); 7180b57cec5SDimitry Andric __t *= __x; 7190b57cec5SDimitry Andric return __t; 7200b57cec5SDimitry Andric} 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andrictemplate <class _Tp> 723bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 724*cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) { 7250b57cec5SDimitry Andric int __ilogbw = 0; 7260b57cec5SDimitry Andric _Tp __a = __z.real(); 7270b57cec5SDimitry Andric _Tp __b = __z.imag(); 7280b57cec5SDimitry Andric _Tp __c = __w.real(); 7290b57cec5SDimitry Andric _Tp __d = __w.imag(); 730bdd1243dSDimitry Andric _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d))); 731*cb14a3feSDimitry Andric if (std::__constexpr_isfinite(__logbw)) { 7320b57cec5SDimitry Andric __ilogbw = static_cast<int>(__logbw); 733bdd1243dSDimitry Andric __c = std::__constexpr_scalbn(__c, -__ilogbw); 734bdd1243dSDimitry Andric __d = std::__constexpr_scalbn(__d, -__ilogbw); 7350b57cec5SDimitry Andric } 736bdd1243dSDimitry Andric 737bdd1243dSDimitry Andric // Avoid floating point operations that are invalid during constant evaluation 738bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) { 739bdd1243dSDimitry Andric bool __z_zero = __a == _Tp(0) && __b == _Tp(0); 740bdd1243dSDimitry Andric bool __w_zero = __c == _Tp(0) && __d == _Tp(0); 741bdd1243dSDimitry Andric bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b); 742bdd1243dSDimitry Andric bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d); 743*cb14a3feSDimitry Andric bool __z_nan = 744*cb14a3feSDimitry Andric !__z_inf && ((std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b)) || 745*cb14a3feSDimitry Andric (std::__constexpr_isnan(__a) && __b == _Tp(0)) || (__a == _Tp(0) && std::__constexpr_isnan(__b))); 746*cb14a3feSDimitry Andric bool __w_nan = 747*cb14a3feSDimitry Andric !__w_inf && ((std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d)) || 748*cb14a3feSDimitry Andric (std::__constexpr_isnan(__c) && __d == _Tp(0)) || (__c == _Tp(0) && std::__constexpr_isnan(__d))); 749bdd1243dSDimitry Andric if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) { 750bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 751bdd1243dSDimitry Andric } 752bdd1243dSDimitry Andric bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b)); 753bdd1243dSDimitry Andric bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d)); 754bdd1243dSDimitry Andric if (__z_nonzero_nan || __w_nonzero_nan) { 755bdd1243dSDimitry Andric if (__w_zero) { 756bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 757bdd1243dSDimitry Andric } 758bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 759bdd1243dSDimitry Andric } 760bdd1243dSDimitry Andric if (__w_inf) { 761bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), _Tp(0)); 762bdd1243dSDimitry Andric } 763bdd1243dSDimitry Andric if (__z_inf) { 764bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 765bdd1243dSDimitry Andric } 766bdd1243dSDimitry Andric if (__w_zero) { 767bdd1243dSDimitry Andric if (__z_zero) { 768bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 769bdd1243dSDimitry Andric } 770bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 771bdd1243dSDimitry Andric } 772bdd1243dSDimitry Andric } 773bdd1243dSDimitry Andric 7740b57cec5SDimitry Andric _Tp __denom = __c * __c + __d * __d; 775bdd1243dSDimitry Andric _Tp __x = std::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); 776bdd1243dSDimitry Andric _Tp __y = std::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); 777*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y)) { 778*cb14a3feSDimitry Andric if ((__denom == _Tp(0)) && (!std::__constexpr_isnan(__a) || !std::__constexpr_isnan(__b))) { 779bdd1243dSDimitry Andric __x = std::__constexpr_copysign(_Tp(INFINITY), __c) * __a; 780bdd1243dSDimitry Andric __y = std::__constexpr_copysign(_Tp(INFINITY), __c) * __b; 781bdd1243dSDimitry Andric } else if ((std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) && std::__constexpr_isfinite(__c) && 782bdd1243dSDimitry Andric std::__constexpr_isfinite(__d)) { 783bdd1243dSDimitry Andric __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a); 784bdd1243dSDimitry Andric __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b); 7850b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c + __b * __d); 7860b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__b * __c - __a * __d); 787bdd1243dSDimitry Andric } else if (std::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && std::__constexpr_isfinite(__a) && 788bdd1243dSDimitry Andric std::__constexpr_isfinite(__b)) { 789bdd1243dSDimitry Andric __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c); 790bdd1243dSDimitry Andric __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d); 7910b57cec5SDimitry Andric __x = _Tp(0) * (__a * __c + __b * __d); 7920b57cec5SDimitry Andric __y = _Tp(0) * (__b * __c - __a * __d); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 7960b57cec5SDimitry Andric} 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andrictemplate <class _Tp> 799*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 800*cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) { 8010b57cec5SDimitry Andric return complex<_Tp>(__x.real() / __y, __x.imag() / __y); 8020b57cec5SDimitry Andric} 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andrictemplate <class _Tp> 805*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 806*cb14a3feSDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) { 8070b57cec5SDimitry Andric complex<_Tp> __t(__x); 8080b57cec5SDimitry Andric __t /= __y; 8090b57cec5SDimitry Andric return __t; 8100b57cec5SDimitry Andric} 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andrictemplate <class _Tp> 813*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator+(const complex<_Tp>& __x) { 8140b57cec5SDimitry Andric return __x; 8150b57cec5SDimitry Andric} 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andrictemplate <class _Tp> 818*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator-(const complex<_Tp>& __x) { 8190b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), -__x.imag()); 8200b57cec5SDimitry Andric} 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andrictemplate <class _Tp> 823*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 824*cb14a3feSDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8250b57cec5SDimitry Andric return __x.real() == __y.real() && __x.imag() == __y.imag(); 8260b57cec5SDimitry Andric} 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andrictemplate <class _Tp> 829*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const complex<_Tp>& __x, const _Tp& __y) { 8300b57cec5SDimitry Andric return __x.real() == __y && __x.imag() == 0; 8310b57cec5SDimitry Andric} 8320b57cec5SDimitry Andric 83306c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 83406c3fb27SDimitry Andric 8350b57cec5SDimitry Andrictemplate <class _Tp> 836*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const _Tp& __x, const complex<_Tp>& __y) { 8370b57cec5SDimitry Andric return __x == __y.real() && 0 == __y.imag(); 8380b57cec5SDimitry Andric} 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andrictemplate <class _Tp> 841*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 842*cb14a3feSDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8430b57cec5SDimitry Andric return !(__x == __y); 8440b57cec5SDimitry Andric} 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andrictemplate <class _Tp> 847*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const complex<_Tp>& __x, const _Tp& __y) { 8480b57cec5SDimitry Andric return !(__x == __y); 8490b57cec5SDimitry Andric} 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andrictemplate <class _Tp> 852*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const _Tp& __x, const complex<_Tp>& __y) { 8530b57cec5SDimitry Andric return !(__x == __y); 8540b57cec5SDimitry Andric} 8550b57cec5SDimitry Andric 85606c3fb27SDimitry Andric#endif 85706c3fb27SDimitry Andric 8580b57cec5SDimitry Andric// 26.3.7 values: 8590b57cec5SDimitry Andric 860*cb14a3feSDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, bool = is_floating_point<_Tp>::value > 8610b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {}; 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric// Integral Types 8640b57cec5SDimitry Andrictemplate <class _Tp> 865*cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> { 8660b57cec5SDimitry Andric typedef double _ValueType; 8670b57cec5SDimitry Andric typedef complex<double> _ComplexType; 8680b57cec5SDimitry Andric}; 8690b57cec5SDimitry Andric 8700b57cec5SDimitry Andric// Floating point types 8710b57cec5SDimitry Andrictemplate <class _Tp> 872*cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> { 8730b57cec5SDimitry Andric typedef _Tp _ValueType; 8740b57cec5SDimitry Andric typedef complex<_Tp> _ComplexType; 8750b57cec5SDimitry Andric}; 8760b57cec5SDimitry Andric 8770b57cec5SDimitry Andric// real 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andrictemplate <class _Tp> 880*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) { 8810b57cec5SDimitry Andric return __c.real(); 8820b57cec5SDimitry Andric} 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andrictemplate <class _Tp> 885*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 886*cb14a3feSDimitry Andricreal(_Tp __re) { 8870b57cec5SDimitry Andric return __re; 8880b57cec5SDimitry Andric} 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric// imag 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andrictemplate <class _Tp> 893*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) { 8940b57cec5SDimitry Andric return __c.imag(); 8950b57cec5SDimitry Andric} 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andrictemplate <class _Tp> 898*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 899*cb14a3feSDimitry Andricimag(_Tp) { 9000b57cec5SDimitry Andric return 0; 9010b57cec5SDimitry Andric} 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric// abs 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andrictemplate <class _Tp> 906*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) { 907bdd1243dSDimitry Andric return std::hypot(__c.real(), __c.imag()); 9080b57cec5SDimitry Andric} 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric// arg 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andrictemplate <class _Tp> 913*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) { 914bdd1243dSDimitry Andric return std::atan2(__c.imag(), __c.real()); 9150b57cec5SDimitry Andric} 9160b57cec5SDimitry Andric 9175f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0> 918*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) { 919bdd1243dSDimitry Andric return std::atan2l(0.L, __re); 9200b57cec5SDimitry Andric} 9210b57cec5SDimitry Andric 9225f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0> 923*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) { 924bdd1243dSDimitry Andric return std::atan2(0., __re); 9250b57cec5SDimitry Andric} 9260b57cec5SDimitry Andric 9275f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0> 928*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) { 929bdd1243dSDimitry Andric return std::atan2f(0.F, __re); 9300b57cec5SDimitry Andric} 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric// norm 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andrictemplate <class _Tp> 935*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) { 936bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real())) 937bdd1243dSDimitry Andric return std::abs(__c.real()); 938bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.imag())) 939bdd1243dSDimitry Andric return std::abs(__c.imag()); 9400b57cec5SDimitry Andric return __c.real() * __c.real() + __c.imag() * __c.imag(); 9410b57cec5SDimitry Andric} 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andrictemplate <class _Tp> 944*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 945*cb14a3feSDimitry Andricnorm(_Tp __re) { 9460b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; 9470b57cec5SDimitry Andric return static_cast<_ValueType>(__re) * __re; 9480b57cec5SDimitry Andric} 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric// conj 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andrictemplate <class _Tp> 953*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> conj(const complex<_Tp>& __c) { 9540b57cec5SDimitry Andric return complex<_Tp>(__c.real(), -__c.imag()); 9550b57cec5SDimitry Andric} 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andrictemplate <class _Tp> 958*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType 959*cb14a3feSDimitry Andricconj(_Tp __re) { 9600b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9610b57cec5SDimitry Andric return _ComplexType(__re); 9620b57cec5SDimitry Andric} 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric// proj 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andrictemplate <class _Tp> 967*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) { 968e8d8bef9SDimitry Andric complex<_Tp> __r = __c; 969bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag())) 970bdd1243dSDimitry Andric __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag())); 9710b57cec5SDimitry Andric return __r; 9720b57cec5SDimitry Andric} 9730b57cec5SDimitry Andric 9745f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 975*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 976bdd1243dSDimitry Andric if (std::__constexpr_isinf(__re)) 977bdd1243dSDimitry Andric __re = std::abs(__re); 9780b57cec5SDimitry Andric return complex<_Tp>(__re); 9790b57cec5SDimitry Andric} 9800b57cec5SDimitry Andric 9815f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 982*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 9830b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9840b57cec5SDimitry Andric return _ComplexType(__re); 9850b57cec5SDimitry Andric} 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric// polar 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andrictemplate <class _Tp> 990*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) { 991bdd1243dSDimitry Andric if (std::__constexpr_isnan(__rho) || std::signbit(__rho)) 9920b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 993*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__theta)) { 994bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 9950b57cec5SDimitry Andric return complex<_Tp>(__rho, __theta); 9960b57cec5SDimitry Andric return complex<_Tp>(__theta, __theta); 9970b57cec5SDimitry Andric } 998*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__theta)) { 999bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10000b57cec5SDimitry Andric return complex<_Tp>(__rho, _Tp(NAN)); 10010b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 10020b57cec5SDimitry Andric } 1003bdd1243dSDimitry Andric _Tp __x = __rho * std::cos(__theta); 1004bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x)) 10050b57cec5SDimitry Andric __x = 0; 1006bdd1243dSDimitry Andric _Tp __y = __rho * std::sin(__theta); 1007bdd1243dSDimitry Andric if (std::__constexpr_isnan(__y)) 10080b57cec5SDimitry Andric __y = 0; 10090b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 10100b57cec5SDimitry Andric} 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric// log 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andrictemplate <class _Tp> 1015*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) { 1016bdd1243dSDimitry Andric return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x)); 10170b57cec5SDimitry Andric} 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric// log10 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andrictemplate <class _Tp> 1022*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) { 1023bdd1243dSDimitry Andric return std::log(__x) / std::log(_Tp(10)); 10240b57cec5SDimitry Andric} 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric// sqrt 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andrictemplate <class _Tp> 1029*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) { 1030bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 10310b57cec5SDimitry Andric return complex<_Tp>(_Tp(INFINITY), __x.imag()); 1032*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 10330b57cec5SDimitry Andric if (__x.real() > _Tp(0)) 1034*cb14a3feSDimitry Andric return complex<_Tp>( 1035*cb14a3feSDimitry Andric __x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag())); 1036*cb14a3feSDimitry Andric return complex<_Tp>( 1037*cb14a3feSDimitry Andric std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag())); 10380b57cec5SDimitry Andric } 1039bdd1243dSDimitry Andric return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2)); 10400b57cec5SDimitry Andric} 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric// exp 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andrictemplate <class _Tp> 1045*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) { 10460b57cec5SDimitry Andric _Tp __i = __x.imag(); 1047349cc55cSDimitry Andric if (__i == 0) { 1048bdd1243dSDimitry Andric return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag())); 1049349cc55cSDimitry Andric } 1050*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1051*cb14a3feSDimitry Andric if (__x.real() < _Tp(0)) { 1052bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__i)) 10530b57cec5SDimitry Andric __i = _Tp(1); 1054*cb14a3feSDimitry Andric } else if (__i == 0 || !std::__constexpr_isfinite(__i)) { 1055bdd1243dSDimitry Andric if (std::__constexpr_isinf(__i)) 10560b57cec5SDimitry Andric __i = _Tp(NAN); 10570b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __i); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric } 1060bdd1243dSDimitry Andric _Tp __e = std::exp(__x.real()); 1061bdd1243dSDimitry Andric return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i)); 10620b57cec5SDimitry Andric} 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric// pow 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andrictemplate <class _Tp> 1067*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { 1068bdd1243dSDimitry Andric return std::exp(__y * std::log(__x)); 10690b57cec5SDimitry Andric} 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1072*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> 1073*cb14a3feSDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) { 10740b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 10755f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 10760b57cec5SDimitry Andric} 10770b57cec5SDimitry Andric 10785f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0> 1079*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) { 10800b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 10815f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 10820b57cec5SDimitry Andric} 10830b57cec5SDimitry Andric 10845f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value, int> = 0> 1085*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const _Tp& __x, const complex<_Up>& __y) { 10860b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 10875f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 10880b57cec5SDimitry Andric} 10890b57cec5SDimitry Andric 10900b57cec5SDimitry Andric// __sqr, computes pow(x, 2) 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andrictemplate <class _Tp> 1093*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) { 1094*cb14a3feSDimitry Andric return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), _Tp(2) * __x.real() * __x.imag()); 10950b57cec5SDimitry Andric} 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric// asinh 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andrictemplate <class _Tp> 1100*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) { 11010b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1102*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1103bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 11040b57cec5SDimitry Andric return __x; 1105bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1106bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 1107bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11080b57cec5SDimitry Andric } 1109*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1110bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 11110b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 11120b57cec5SDimitry Andric if (__x.imag() == 0) 11130b57cec5SDimitry Andric return __x; 11140b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11150b57cec5SDimitry Andric } 1116bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1117bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 1118bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1))); 1119bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 11200b57cec5SDimitry Andric} 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric// acosh 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andrictemplate <class _Tp> 1125*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) { 11260b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1127*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1128bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 1129bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1130*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 11310b57cec5SDimitry Andric if (__x.real() > 0) 1132bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 11330b57cec5SDimitry Andric else 1134bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag())); 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric if (__x.real() < 0) 1137bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag())); 1138bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11390b57cec5SDimitry Andric } 1140*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1141bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1142bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), __x.real()); 11430b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11440b57cec5SDimitry Andric } 1145bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1146bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag())); 1147bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1148bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag())); 11490b57cec5SDimitry Andric} 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric// atanh 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andrictemplate <class _Tp> 1154*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) { 11550b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1156*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 1157bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 11580b57cec5SDimitry Andric } 1159*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.imag())) { 1160bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) || __x.real() == 0) 1161bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag()); 11620b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.imag()); 11630b57cec5SDimitry Andric } 1164*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 11650b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11660b57cec5SDimitry Andric } 1167*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1168bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 11690b57cec5SDimitry Andric } 1170*cb14a3feSDimitry Andric if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) { 1171bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag())); 11720b57cec5SDimitry Andric } 1173bdd1243dSDimitry Andric complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); 1174bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 11750b57cec5SDimitry Andric} 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric// sinh 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andrictemplate <class _Tp> 1180*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) { 1181bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 11820b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1183bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 11840b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1185bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 11860b57cec5SDimitry Andric return __x; 1187bdd1243dSDimitry Andric return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag())); 11880b57cec5SDimitry Andric} 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric// cosh 11910b57cec5SDimitry Andric 11920b57cec5SDimitry Andrictemplate <class _Tp> 1193*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) { 1194bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 1195bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), _Tp(NAN)); 1196bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 11970b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), __x.real()); 11980b57cec5SDimitry Andric if (__x.real() == 0 && __x.imag() == 0) 11990b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), __x.imag()); 1200bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 1201bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1202bdd1243dSDimitry Andric return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag())); 12030b57cec5SDimitry Andric} 12040b57cec5SDimitry Andric 12050b57cec5SDimitry Andric// tanh 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andrictemplate <class _Tp> 1208*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) { 1209*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1210bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__x.imag())) 1211bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0)); 1212bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag()))); 12130b57cec5SDimitry Andric } 1214bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0) 12150b57cec5SDimitry Andric return __x; 12160b57cec5SDimitry Andric _Tp __2r(_Tp(2) * __x.real()); 12170b57cec5SDimitry Andric _Tp __2i(_Tp(2) * __x.imag()); 1218bdd1243dSDimitry Andric _Tp __d(std::cosh(__2r) + std::cos(__2i)); 1219bdd1243dSDimitry Andric _Tp __2rsh(std::sinh(__2r)); 1220bdd1243dSDimitry Andric if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d)) 1221*cb14a3feSDimitry Andric return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); 1222bdd1243dSDimitry Andric return complex<_Tp>(__2rsh / __d, std::sin(__2i) / __d); 12230b57cec5SDimitry Andric} 12240b57cec5SDimitry Andric 12250b57cec5SDimitry Andric// asin 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andrictemplate <class _Tp> 1228*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) { 1229bdd1243dSDimitry Andric complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real())); 12300b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12310b57cec5SDimitry Andric} 12320b57cec5SDimitry Andric 12330b57cec5SDimitry Andric// acos 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andrictemplate <class _Tp> 1236*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) { 12370b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1238*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1239bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 12400b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 1241*cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 12420b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 12430b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); 12440b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 1247bdd1243dSDimitry Andric return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real()); 1248bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real()); 12490b57cec5SDimitry Andric } 1250*cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1251bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12520b57cec5SDimitry Andric return complex<_Tp>(__x.real(), -__x.imag()); 12530b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12540b57cec5SDimitry Andric } 1255bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12560b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1257bdd1243dSDimitry Andric if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag()))) 12580b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1259bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1260bdd1243dSDimitry Andric if (std::signbit(__x.imag())) 1261bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real())); 1262bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real())); 12630b57cec5SDimitry Andric} 12640b57cec5SDimitry Andric 12650b57cec5SDimitry Andric// atan 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andrictemplate <class _Tp> 1268*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) { 1269bdd1243dSDimitry Andric complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real())); 12700b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12710b57cec5SDimitry Andric} 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric// sin 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andrictemplate <class _Tp> 1276*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) { 1277bdd1243dSDimitry Andric complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real())); 12780b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12790b57cec5SDimitry Andric} 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric// cos 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andrictemplate <class _Tp> 1284*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) { 1285bdd1243dSDimitry Andric return std::cosh(complex<_Tp>(-__x.imag(), __x.real())); 12860b57cec5SDimitry Andric} 12870b57cec5SDimitry Andric 12880b57cec5SDimitry Andric// tan 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andrictemplate <class _Tp> 1291*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) { 1292bdd1243dSDimitry Andric complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real())); 12930b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12940b57cec5SDimitry Andric} 12950b57cec5SDimitry Andric 1296bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 12970b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1298bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 1299*cb14a3feSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) { 1300*cb14a3feSDimitry Andric if (__is.good()) { 1301bdd1243dSDimitry Andric std::ws(__is); 1302*cb14a3feSDimitry Andric if (__is.peek() == _CharT('(')) { 13030b57cec5SDimitry Andric __is.get(); 13040b57cec5SDimitry Andric _Tp __r; 13050b57cec5SDimitry Andric __is >> __r; 1306*cb14a3feSDimitry Andric if (!__is.fail()) { 1307bdd1243dSDimitry Andric std::ws(__is); 13080b57cec5SDimitry Andric _CharT __c = __is.peek(); 1309*cb14a3feSDimitry Andric if (__c == _CharT(',')) { 13100b57cec5SDimitry Andric __is.get(); 13110b57cec5SDimitry Andric _Tp __i; 13120b57cec5SDimitry Andric __is >> __i; 1313*cb14a3feSDimitry Andric if (!__is.fail()) { 1314bdd1243dSDimitry Andric std::ws(__is); 13150b57cec5SDimitry Andric __c = __is.peek(); 1316*cb14a3feSDimitry Andric if (__c == _CharT(')')) { 13170b57cec5SDimitry Andric __is.get(); 13180b57cec5SDimitry Andric __x = complex<_Tp>(__r, __i); 1319*cb14a3feSDimitry Andric } else 13205ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1321*cb14a3feSDimitry Andric } else 13225ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1323*cb14a3feSDimitry Andric } else if (__c == _CharT(')')) { 13240b57cec5SDimitry Andric __is.get(); 13250b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 1326*cb14a3feSDimitry Andric } else 13275ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1328*cb14a3feSDimitry Andric } else 13295ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1330*cb14a3feSDimitry Andric } else { 13310b57cec5SDimitry Andric _Tp __r; 13320b57cec5SDimitry Andric __is >> __r; 13330b57cec5SDimitry Andric if (!__is.fail()) 13340b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 13350b57cec5SDimitry Andric else 13365ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13370b57cec5SDimitry Andric } 1338*cb14a3feSDimitry Andric } else 13395ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13400b57cec5SDimitry Andric return __is; 13410b57cec5SDimitry Andric} 13420b57cec5SDimitry Andric 13430b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1344bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 1345*cb14a3feSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) { 13460b57cec5SDimitry Andric basic_ostringstream<_CharT, _Traits> __s; 13470b57cec5SDimitry Andric __s.flags(__os.flags()); 13480b57cec5SDimitry Andric __s.imbue(__os.getloc()); 13490b57cec5SDimitry Andric __s.precision(__os.precision()); 13500b57cec5SDimitry Andric __s << '(' << __x.real() << ',' << __x.imag() << ')'; 13510b57cec5SDimitry Andric return __os << __s.str(); 13520b57cec5SDimitry Andric} 1353e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION 13540b57cec5SDimitry Andric 135506c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 13560b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals] 1357*cb14a3feSDimitry Andricinline namespace literals { 1358*cb14a3feSDimitry Andricinline namespace complex_literals { 1359*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(long double __im) { return {0.0l, __im}; } 13600b57cec5SDimitry Andric 1361*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(unsigned long long __im) { 13620b57cec5SDimitry Andric return {0.0l, static_cast<long double>(__im)}; 13630b57cec5SDimitry Andric} 13640b57cec5SDimitry Andric 1365*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(long double __im) { 13660b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 13670b57cec5SDimitry Andric} 13680b57cec5SDimitry Andric 1369*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(unsigned long long __im) { 13700b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 13710b57cec5SDimitry Andric} 13720b57cec5SDimitry Andric 1373*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(long double __im) { 13740b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 13750b57cec5SDimitry Andric} 13760b57cec5SDimitry Andric 1377*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long long __im) { 13780b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 13790b57cec5SDimitry Andric} 13800eae32dcSDimitry Andric} // namespace complex_literals 13810eae32dcSDimitry Andric} // namespace literals 13820b57cec5SDimitry Andric#endif 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 13850b57cec5SDimitry Andric 138606c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 13875f757f3fSDimitry Andric# include <iosfwd> 13885f757f3fSDimitry Andric# include <stdexcept> 138906c3fb27SDimitry Andric# include <type_traits> 139006c3fb27SDimitry Andric#endif 139106c3fb27SDimitry Andric 13920b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX 1393