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 2490b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex; 2500b57cec5SDimitry Andric 251bdd1243dSDimitry Andrictemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 252bdd1243dSDimitry Andrictemplate<class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andrictemplate<class _Tp> 2550b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex 2560b57cec5SDimitry Andric{ 2570b57cec5SDimitry Andricpublic: 2580b57cec5SDimitry Andric typedef _Tp value_type; 2590b57cec5SDimitry Andricprivate: 2600b57cec5SDimitry Andric value_type __re_; 2610b57cec5SDimitry Andric value_type __im_; 2620b57cec5SDimitry Andricpublic: 263*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 2640b57cec5SDimitry Andric complex(const value_type& __re = value_type(), const value_type& __im = value_type()) 2650b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 266*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 2670b57cec5SDimitry Andric complex(const complex<_Xp>& __c) 2680b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 2690b57cec5SDimitry Andric 270*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const {return __re_;} 271*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const {return __im_;} 2720b57cec5SDimitry Andric 273*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;} 274*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;} 2750b57cec5SDimitry Andric 276*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const value_type& __re) 2770b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 278*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} 279*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} 280*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} 281*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} 2820b57cec5SDimitry Andric 283*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c) 2840b57cec5SDimitry Andric { 2850b57cec5SDimitry Andric __re_ = __c.real(); 2860b57cec5SDimitry Andric __im_ = __c.imag(); 2870b57cec5SDimitry Andric return *this; 2880b57cec5SDimitry Andric } 289*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) 2900b57cec5SDimitry Andric { 2910b57cec5SDimitry Andric __re_ += __c.real(); 2920b57cec5SDimitry Andric __im_ += __c.imag(); 2930b57cec5SDimitry Andric return *this; 2940b57cec5SDimitry Andric } 295*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) 2960b57cec5SDimitry Andric { 2970b57cec5SDimitry Andric __re_ -= __c.real(); 2980b57cec5SDimitry Andric __im_ -= __c.imag(); 2990b57cec5SDimitry Andric return *this; 3000b57cec5SDimitry Andric } 301*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) 3020b57cec5SDimitry Andric { 3030b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3040b57cec5SDimitry Andric return *this; 3050b57cec5SDimitry Andric } 306*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) 3070b57cec5SDimitry Andric { 3080b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3090b57cec5SDimitry Andric return *this; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric}; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>; 3140b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andrictemplate<> 3170b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float> 3180b57cec5SDimitry Andric{ 3190b57cec5SDimitry Andric float __re_; 3200b57cec5SDimitry Andric float __im_; 3210b57cec5SDimitry Andricpublic: 3220b57cec5SDimitry Andric typedef float value_type; 3230b57cec5SDimitry Andric 324*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) 3250b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 326*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3270b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 328*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3290b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 3300b57cec5SDimitry Andric 331*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const {return __re_;} 332*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const {return __im_;} 3330b57cec5SDimitry Andric 334*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;} 335*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;} 3360b57cec5SDimitry Andric 337*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (float __re) 3380b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 339*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) {__re_ += __re; return *this;} 340*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) {__re_ -= __re; return *this;} 341*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} 342*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} 3430b57cec5SDimitry Andric 344*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c) 3450b57cec5SDimitry Andric { 3460b57cec5SDimitry Andric __re_ = __c.real(); 3470b57cec5SDimitry Andric __im_ = __c.imag(); 3480b57cec5SDimitry Andric return *this; 3490b57cec5SDimitry Andric } 350*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) 3510b57cec5SDimitry Andric { 3520b57cec5SDimitry Andric __re_ += __c.real(); 3530b57cec5SDimitry Andric __im_ += __c.imag(); 3540b57cec5SDimitry Andric return *this; 3550b57cec5SDimitry Andric } 356*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) 3570b57cec5SDimitry Andric { 3580b57cec5SDimitry Andric __re_ -= __c.real(); 3590b57cec5SDimitry Andric __im_ -= __c.imag(); 3600b57cec5SDimitry Andric return *this; 3610b57cec5SDimitry Andric } 362*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) 3630b57cec5SDimitry Andric { 3640b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3650b57cec5SDimitry Andric return *this; 3660b57cec5SDimitry Andric } 367*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) 3680b57cec5SDimitry Andric { 3690b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3700b57cec5SDimitry Andric return *this; 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric}; 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andrictemplate<> 3750b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> 3760b57cec5SDimitry Andric{ 3770b57cec5SDimitry Andric double __re_; 3780b57cec5SDimitry Andric double __im_; 3790b57cec5SDimitry Andricpublic: 3800b57cec5SDimitry Andric typedef double value_type; 3810b57cec5SDimitry Andric 382*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) 3830b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 384*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3850b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 386*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 3870b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 3880b57cec5SDimitry Andric 389*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const {return __re_;} 390*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const {return __im_;} 3910b57cec5SDimitry Andric 392*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;} 393*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;} 3940b57cec5SDimitry Andric 395*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (double __re) 3960b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 397*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) {__re_ += __re; return *this;} 398*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) {__re_ -= __re; return *this;} 399*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} 400*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} 4010b57cec5SDimitry Andric 402*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c) 4030b57cec5SDimitry Andric { 4040b57cec5SDimitry Andric __re_ = __c.real(); 4050b57cec5SDimitry Andric __im_ = __c.imag(); 4060b57cec5SDimitry Andric return *this; 4070b57cec5SDimitry Andric } 408*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) 4090b57cec5SDimitry Andric { 4100b57cec5SDimitry Andric __re_ += __c.real(); 4110b57cec5SDimitry Andric __im_ += __c.imag(); 4120b57cec5SDimitry Andric return *this; 4130b57cec5SDimitry Andric } 414*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) 4150b57cec5SDimitry Andric { 4160b57cec5SDimitry Andric __re_ -= __c.real(); 4170b57cec5SDimitry Andric __im_ -= __c.imag(); 4180b57cec5SDimitry Andric return *this; 4190b57cec5SDimitry Andric } 420*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) 4210b57cec5SDimitry Andric { 4220b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4230b57cec5SDimitry Andric return *this; 4240b57cec5SDimitry Andric } 425*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) 4260b57cec5SDimitry Andric { 4270b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4280b57cec5SDimitry Andric return *this; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric}; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andrictemplate<> 4330b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> 4340b57cec5SDimitry Andric{ 4350b57cec5SDimitry Andric long double __re_; 4360b57cec5SDimitry Andric long double __im_; 4370b57cec5SDimitry Andricpublic: 4380b57cec5SDimitry Andric typedef long double value_type; 4390b57cec5SDimitry Andric 440*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) 4410b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 442*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 4430b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 444*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 4450b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 4460b57cec5SDimitry Andric 447*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const {return __re_;} 448*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const {return __im_;} 4490b57cec5SDimitry Andric 450*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) {__re_ = __re;} 451*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) {__im_ = __im;} 4520b57cec5SDimitry Andric 453*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (long double __re) 4540b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 455*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) {__re_ += __re; return *this;} 456*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) {__re_ -= __re; return *this;} 457*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} 458*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} 4590b57cec5SDimitry Andric 460*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator= (const complex<_Xp>& __c) 4610b57cec5SDimitry Andric { 4620b57cec5SDimitry Andric __re_ = __c.real(); 4630b57cec5SDimitry Andric __im_ = __c.imag(); 4640b57cec5SDimitry Andric return *this; 4650b57cec5SDimitry Andric } 466*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) 4670b57cec5SDimitry Andric { 4680b57cec5SDimitry Andric __re_ += __c.real(); 4690b57cec5SDimitry Andric __im_ += __c.imag(); 4700b57cec5SDimitry Andric return *this; 4710b57cec5SDimitry Andric } 472*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) 4730b57cec5SDimitry Andric { 4740b57cec5SDimitry Andric __re_ -= __c.real(); 4750b57cec5SDimitry Andric __im_ -= __c.imag(); 4760b57cec5SDimitry Andric return *this; 4770b57cec5SDimitry Andric } 478*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) 4790b57cec5SDimitry Andric { 4800b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4810b57cec5SDimitry Andric return *this; 4820b57cec5SDimitry Andric } 483*5f757f3fSDimitry Andric template<class _Xp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) 4840b57cec5SDimitry Andric { 4850b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4860b57cec5SDimitry Andric return *this; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric}; 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andricinline 4910b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 4920b57cec5SDimitry Andriccomplex<float>::complex(const complex<double>& __c) 4930b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andricinline 4960b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 4970b57cec5SDimitry Andriccomplex<float>::complex(const complex<long double>& __c) 4980b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andricinline 5010b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5020b57cec5SDimitry Andriccomplex<double>::complex(const complex<float>& __c) 5030b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andricinline 5060b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5070b57cec5SDimitry Andriccomplex<double>::complex(const complex<long double>& __c) 5080b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andricinline 5110b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5120b57cec5SDimitry Andriccomplex<long double>::complex(const complex<float>& __c) 5130b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andricinline 5160b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5170b57cec5SDimitry Andriccomplex<long double>::complex(const complex<double>& __c) 5180b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric// 26.3.6 operators: 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andrictemplate<class _Tp> 523*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5240b57cec5SDimitry Andriccomplex<_Tp> 5250b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 5260b57cec5SDimitry Andric{ 5270b57cec5SDimitry Andric complex<_Tp> __t(__x); 5280b57cec5SDimitry Andric __t += __y; 5290b57cec5SDimitry Andric return __t; 5300b57cec5SDimitry Andric} 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andrictemplate<class _Tp> 533*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5340b57cec5SDimitry Andriccomplex<_Tp> 5350b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) 5360b57cec5SDimitry Andric{ 5370b57cec5SDimitry Andric complex<_Tp> __t(__x); 5380b57cec5SDimitry Andric __t += __y; 5390b57cec5SDimitry Andric return __t; 5400b57cec5SDimitry Andric} 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andrictemplate<class _Tp> 543*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5440b57cec5SDimitry Andriccomplex<_Tp> 5450b57cec5SDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) 5460b57cec5SDimitry Andric{ 5470b57cec5SDimitry Andric complex<_Tp> __t(__y); 5480b57cec5SDimitry Andric __t += __x; 5490b57cec5SDimitry Andric return __t; 5500b57cec5SDimitry Andric} 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andrictemplate<class _Tp> 553*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5540b57cec5SDimitry Andriccomplex<_Tp> 5550b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 5560b57cec5SDimitry Andric{ 5570b57cec5SDimitry Andric complex<_Tp> __t(__x); 5580b57cec5SDimitry Andric __t -= __y; 5590b57cec5SDimitry Andric return __t; 5600b57cec5SDimitry Andric} 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andrictemplate<class _Tp> 563*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5640b57cec5SDimitry Andriccomplex<_Tp> 5650b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) 5660b57cec5SDimitry Andric{ 5670b57cec5SDimitry Andric complex<_Tp> __t(__x); 5680b57cec5SDimitry Andric __t -= __y; 5690b57cec5SDimitry Andric return __t; 5700b57cec5SDimitry Andric} 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andrictemplate<class _Tp> 573*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 5740b57cec5SDimitry Andriccomplex<_Tp> 5750b57cec5SDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) 5760b57cec5SDimitry Andric{ 5770b57cec5SDimitry Andric complex<_Tp> __t(-__y); 5780b57cec5SDimitry Andric __t += __x; 5790b57cec5SDimitry Andric return __t; 5800b57cec5SDimitry Andric} 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andrictemplate<class _Tp> 583bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 5840b57cec5SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) 5850b57cec5SDimitry Andric{ 5860b57cec5SDimitry Andric _Tp __a = __z.real(); 5870b57cec5SDimitry Andric _Tp __b = __z.imag(); 5880b57cec5SDimitry Andric _Tp __c = __w.real(); 5890b57cec5SDimitry Andric _Tp __d = __w.imag(); 590bdd1243dSDimitry Andric 591bdd1243dSDimitry Andric // Avoid floating point operations that are invalid during constant evaluation 592bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) { 593bdd1243dSDimitry Andric bool __z_zero = __a == _Tp(0) && __b == _Tp(0); 594bdd1243dSDimitry Andric bool __w_zero = __c == _Tp(0) && __d == _Tp(0); 595bdd1243dSDimitry Andric bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b); 596bdd1243dSDimitry Andric bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d); 597bdd1243dSDimitry Andric bool __z_nan = !__z_inf && ( 598bdd1243dSDimitry Andric (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b)) 599bdd1243dSDimitry Andric || (std::__constexpr_isnan(__a) && __b == _Tp(0)) 600bdd1243dSDimitry Andric || (__a == _Tp(0) && std::__constexpr_isnan(__b)) 601bdd1243dSDimitry Andric ); 602bdd1243dSDimitry Andric bool __w_nan = !__w_inf && ( 603bdd1243dSDimitry Andric (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d)) 604bdd1243dSDimitry Andric || (std::__constexpr_isnan(__c) && __d == _Tp(0)) 605bdd1243dSDimitry Andric || (__c == _Tp(0) && std::__constexpr_isnan(__d)) 606bdd1243dSDimitry Andric ); 607bdd1243dSDimitry Andric if (__z_nan || __w_nan) { 608bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 609bdd1243dSDimitry Andric } 610bdd1243dSDimitry Andric if (__z_inf || __w_inf) { 611bdd1243dSDimitry Andric if (__z_zero || __w_zero) { 612bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 613bdd1243dSDimitry Andric } 614bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 615bdd1243dSDimitry Andric } 616bdd1243dSDimitry Andric bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b)); 617bdd1243dSDimitry Andric bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d)); 618bdd1243dSDimitry Andric if (__z_nonzero_nan || __w_nonzero_nan) { 619bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 620bdd1243dSDimitry Andric } 621bdd1243dSDimitry Andric } 622bdd1243dSDimitry Andric 6230b57cec5SDimitry Andric _Tp __ac = __a * __c; 6240b57cec5SDimitry Andric _Tp __bd = __b * __d; 6250b57cec5SDimitry Andric _Tp __ad = __a * __d; 6260b57cec5SDimitry Andric _Tp __bc = __b * __c; 6270b57cec5SDimitry Andric _Tp __x = __ac - __bd; 6280b57cec5SDimitry Andric _Tp __y = __ad + __bc; 629bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y)) 6300b57cec5SDimitry Andric { 6310b57cec5SDimitry Andric bool __recalc = false; 632bdd1243dSDimitry Andric if (std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) 6330b57cec5SDimitry Andric { 634bdd1243dSDimitry Andric __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a); 635bdd1243dSDimitry Andric __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b); 636bdd1243dSDimitry Andric if (std::__constexpr_isnan(__c)) 637bdd1243dSDimitry Andric __c = std::__constexpr_copysign(_Tp(0), __c); 638bdd1243dSDimitry Andric if (std::__constexpr_isnan(__d)) 639bdd1243dSDimitry Andric __d = std::__constexpr_copysign(_Tp(0), __d); 6400b57cec5SDimitry Andric __recalc = true; 6410b57cec5SDimitry Andric } 642bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d)) 6430b57cec5SDimitry Andric { 644bdd1243dSDimitry Andric __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c); 645bdd1243dSDimitry Andric __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d); 646bdd1243dSDimitry Andric if (std::__constexpr_isnan(__a)) 647bdd1243dSDimitry Andric __a = std::__constexpr_copysign(_Tp(0), __a); 648bdd1243dSDimitry Andric if (std::__constexpr_isnan(__b)) 649bdd1243dSDimitry Andric __b = std::__constexpr_copysign(_Tp(0), __b); 6500b57cec5SDimitry Andric __recalc = true; 6510b57cec5SDimitry Andric } 652bdd1243dSDimitry Andric if (!__recalc && (std::__constexpr_isinf(__ac) || std::__constexpr_isinf(__bd) || 653bdd1243dSDimitry Andric std::__constexpr_isinf(__ad) || std::__constexpr_isinf(__bc))) 6540b57cec5SDimitry Andric { 655bdd1243dSDimitry Andric if (std::__constexpr_isnan(__a)) 656bdd1243dSDimitry Andric __a = std::__constexpr_copysign(_Tp(0), __a); 657bdd1243dSDimitry Andric if (std::__constexpr_isnan(__b)) 658bdd1243dSDimitry Andric __b = std::__constexpr_copysign(_Tp(0), __b); 659bdd1243dSDimitry Andric if (std::__constexpr_isnan(__c)) 660bdd1243dSDimitry Andric __c = std::__constexpr_copysign(_Tp(0), __c); 661bdd1243dSDimitry Andric if (std::__constexpr_isnan(__d)) 662bdd1243dSDimitry Andric __d = std::__constexpr_copysign(_Tp(0), __d); 6630b57cec5SDimitry Andric __recalc = true; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric if (__recalc) 6660b57cec5SDimitry Andric { 6670b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c - __b * __d); 6680b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__a * __d + __b * __c); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 6720b57cec5SDimitry Andric} 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andrictemplate<class _Tp> 675*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 6760b57cec5SDimitry Andriccomplex<_Tp> 6770b57cec5SDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) 6780b57cec5SDimitry Andric{ 6790b57cec5SDimitry Andric complex<_Tp> __t(__x); 6800b57cec5SDimitry Andric __t *= __y; 6810b57cec5SDimitry Andric return __t; 6820b57cec5SDimitry Andric} 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andrictemplate<class _Tp> 685*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 6860b57cec5SDimitry Andriccomplex<_Tp> 6870b57cec5SDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) 6880b57cec5SDimitry Andric{ 6890b57cec5SDimitry Andric complex<_Tp> __t(__y); 6900b57cec5SDimitry Andric __t *= __x; 6910b57cec5SDimitry Andric return __t; 6920b57cec5SDimitry Andric} 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andrictemplate<class _Tp> 695bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 6960b57cec5SDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) 6970b57cec5SDimitry Andric{ 6980b57cec5SDimitry Andric int __ilogbw = 0; 6990b57cec5SDimitry Andric _Tp __a = __z.real(); 7000b57cec5SDimitry Andric _Tp __b = __z.imag(); 7010b57cec5SDimitry Andric _Tp __c = __w.real(); 7020b57cec5SDimitry Andric _Tp __d = __w.imag(); 703bdd1243dSDimitry Andric _Tp __logbw = std::__constexpr_logb(std::__constexpr_fmax(std::__constexpr_fabs(__c), std::__constexpr_fabs(__d))); 704bdd1243dSDimitry Andric if (std::__constexpr_isfinite(__logbw)) 7050b57cec5SDimitry Andric { 7060b57cec5SDimitry Andric __ilogbw = static_cast<int>(__logbw); 707bdd1243dSDimitry Andric __c = std::__constexpr_scalbn(__c, -__ilogbw); 708bdd1243dSDimitry Andric __d = std::__constexpr_scalbn(__d, -__ilogbw); 7090b57cec5SDimitry Andric } 710bdd1243dSDimitry Andric 711bdd1243dSDimitry Andric // Avoid floating point operations that are invalid during constant evaluation 712bdd1243dSDimitry Andric if (__libcpp_is_constant_evaluated()) { 713bdd1243dSDimitry Andric bool __z_zero = __a == _Tp(0) && __b == _Tp(0); 714bdd1243dSDimitry Andric bool __w_zero = __c == _Tp(0) && __d == _Tp(0); 715bdd1243dSDimitry Andric bool __z_inf = std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b); 716bdd1243dSDimitry Andric bool __w_inf = std::__constexpr_isinf(__c) || std::__constexpr_isinf(__d); 717bdd1243dSDimitry Andric bool __z_nan = !__z_inf && ( 718bdd1243dSDimitry Andric (std::__constexpr_isnan(__a) && std::__constexpr_isnan(__b)) 719bdd1243dSDimitry Andric || (std::__constexpr_isnan(__a) && __b == _Tp(0)) 720bdd1243dSDimitry Andric || (__a == _Tp(0) && std::__constexpr_isnan(__b)) 721bdd1243dSDimitry Andric ); 722bdd1243dSDimitry Andric bool __w_nan = !__w_inf && ( 723bdd1243dSDimitry Andric (std::__constexpr_isnan(__c) && std::__constexpr_isnan(__d)) 724bdd1243dSDimitry Andric || (std::__constexpr_isnan(__c) && __d == _Tp(0)) 725bdd1243dSDimitry Andric || (__c == _Tp(0) && std::__constexpr_isnan(__d)) 726bdd1243dSDimitry Andric ); 727bdd1243dSDimitry Andric if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) { 728bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 729bdd1243dSDimitry Andric } 730bdd1243dSDimitry Andric bool __z_nonzero_nan = !__z_inf && !__z_nan && (std::__constexpr_isnan(__a) || std::__constexpr_isnan(__b)); 731bdd1243dSDimitry Andric bool __w_nonzero_nan = !__w_inf && !__w_nan && (std::__constexpr_isnan(__c) || std::__constexpr_isnan(__d)); 732bdd1243dSDimitry Andric if (__z_nonzero_nan || __w_nonzero_nan) { 733bdd1243dSDimitry Andric if (__w_zero) { 734bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 735bdd1243dSDimitry Andric } 736bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 737bdd1243dSDimitry Andric } 738bdd1243dSDimitry Andric if (__w_inf) { 739bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), _Tp(0)); 740bdd1243dSDimitry Andric } 741bdd1243dSDimitry Andric if (__z_inf) { 742bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 743bdd1243dSDimitry Andric } 744bdd1243dSDimitry Andric if (__w_zero) { 745bdd1243dSDimitry Andric if (__z_zero) { 746bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0)); 747bdd1243dSDimitry Andric } 748bdd1243dSDimitry Andric return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity())); 749bdd1243dSDimitry Andric } 750bdd1243dSDimitry Andric } 751bdd1243dSDimitry Andric 7520b57cec5SDimitry Andric _Tp __denom = __c * __c + __d * __d; 753bdd1243dSDimitry Andric _Tp __x = std::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); 754bdd1243dSDimitry Andric _Tp __y = std::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); 755bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x) && std::__constexpr_isnan(__y)) 7560b57cec5SDimitry Andric { 757bdd1243dSDimitry Andric if ((__denom == _Tp(0)) && (!std::__constexpr_isnan(__a) || !std::__constexpr_isnan(__b))) 7580b57cec5SDimitry Andric { 759bdd1243dSDimitry Andric __x = std::__constexpr_copysign(_Tp(INFINITY), __c) * __a; 760bdd1243dSDimitry Andric __y = std::__constexpr_copysign(_Tp(INFINITY), __c) * __b; 761bdd1243dSDimitry Andric } else if ((std::__constexpr_isinf(__a) || std::__constexpr_isinf(__b)) && std::__constexpr_isfinite(__c) && 762bdd1243dSDimitry Andric std::__constexpr_isfinite(__d)) { 763bdd1243dSDimitry Andric __a = std::__constexpr_copysign(std::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a); 764bdd1243dSDimitry Andric __b = std::__constexpr_copysign(std::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b); 7650b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c + __b * __d); 7660b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__b * __c - __a * __d); 767bdd1243dSDimitry Andric } else if (std::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && std::__constexpr_isfinite(__a) && 768bdd1243dSDimitry Andric std::__constexpr_isfinite(__b)) { 769bdd1243dSDimitry Andric __c = std::__constexpr_copysign(std::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c); 770bdd1243dSDimitry Andric __d = std::__constexpr_copysign(std::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d); 7710b57cec5SDimitry Andric __x = _Tp(0) * (__a * __c + __b * __d); 7720b57cec5SDimitry Andric __y = _Tp(0) * (__b * __c - __a * __d); 7730b57cec5SDimitry Andric } 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 7760b57cec5SDimitry Andric} 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andrictemplate<class _Tp> 779*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 7800b57cec5SDimitry Andriccomplex<_Tp> 7810b57cec5SDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) 7820b57cec5SDimitry Andric{ 7830b57cec5SDimitry Andric return complex<_Tp>(__x.real() / __y, __x.imag() / __y); 7840b57cec5SDimitry Andric} 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andrictemplate<class _Tp> 787*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 7880b57cec5SDimitry Andriccomplex<_Tp> 7890b57cec5SDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) 7900b57cec5SDimitry Andric{ 7910b57cec5SDimitry Andric complex<_Tp> __t(__x); 7920b57cec5SDimitry Andric __t /= __y; 7930b57cec5SDimitry Andric return __t; 7940b57cec5SDimitry Andric} 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andrictemplate<class _Tp> 797*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 7980b57cec5SDimitry Andriccomplex<_Tp> 7990b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x) 8000b57cec5SDimitry Andric{ 8010b57cec5SDimitry Andric return __x; 8020b57cec5SDimitry Andric} 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andrictemplate<class _Tp> 805*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 8060b57cec5SDimitry Andriccomplex<_Tp> 8070b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x) 8080b57cec5SDimitry Andric{ 8090b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), -__x.imag()); 8100b57cec5SDimitry Andric} 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andrictemplate<class _Tp> 813*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8140b57cec5SDimitry Andricbool 8150b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 8160b57cec5SDimitry Andric{ 8170b57cec5SDimitry Andric return __x.real() == __y.real() && __x.imag() == __y.imag(); 8180b57cec5SDimitry Andric} 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andrictemplate<class _Tp> 821*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8220b57cec5SDimitry Andricbool 8230b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const _Tp& __y) 8240b57cec5SDimitry Andric{ 8250b57cec5SDimitry Andric return __x.real() == __y && __x.imag() == 0; 8260b57cec5SDimitry Andric} 8270b57cec5SDimitry Andric 82806c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 82906c3fb27SDimitry Andric 8300b57cec5SDimitry Andrictemplate<class _Tp> 831*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8320b57cec5SDimitry Andricbool 8330b57cec5SDimitry Andricoperator==(const _Tp& __x, const complex<_Tp>& __y) 8340b57cec5SDimitry Andric{ 8350b57cec5SDimitry Andric return __x == __y.real() && 0 == __y.imag(); 8360b57cec5SDimitry Andric} 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andrictemplate<class _Tp> 839*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8400b57cec5SDimitry Andricbool 8410b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 8420b57cec5SDimitry Andric{ 8430b57cec5SDimitry Andric return !(__x == __y); 8440b57cec5SDimitry Andric} 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andrictemplate<class _Tp> 847*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8480b57cec5SDimitry Andricbool 8490b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const _Tp& __y) 8500b57cec5SDimitry Andric{ 8510b57cec5SDimitry Andric return !(__x == __y); 8520b57cec5SDimitry Andric} 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andrictemplate<class _Tp> 855*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8560b57cec5SDimitry Andricbool 8570b57cec5SDimitry Andricoperator!=(const _Tp& __x, const complex<_Tp>& __y) 8580b57cec5SDimitry Andric{ 8590b57cec5SDimitry Andric return !(__x == __y); 8600b57cec5SDimitry Andric} 8610b57cec5SDimitry Andric 86206c3fb27SDimitry Andric#endif 86306c3fb27SDimitry Andric 8640b57cec5SDimitry Andric// 26.3.7 values: 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, 8670b57cec5SDimitry Andric bool = is_floating_point<_Tp>::value 8680b57cec5SDimitry Andric > 8690b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {}; 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric// Integral Types 8720b57cec5SDimitry Andrictemplate <class _Tp> 8730b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> 8740b57cec5SDimitry Andric{ 8750b57cec5SDimitry Andric typedef double _ValueType; 8760b57cec5SDimitry Andric typedef complex<double> _ComplexType; 8770b57cec5SDimitry Andric}; 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric// Floating point types 8800b57cec5SDimitry Andrictemplate <class _Tp> 8810b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> 8820b57cec5SDimitry Andric{ 8830b57cec5SDimitry Andric typedef _Tp _ValueType; 8840b57cec5SDimitry Andric typedef complex<_Tp> _ComplexType; 8850b57cec5SDimitry Andric}; 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric// real 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andrictemplate<class _Tp> 890*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8910b57cec5SDimitry Andric_Tp 8920b57cec5SDimitry Andricreal(const complex<_Tp>& __c) 8930b57cec5SDimitry Andric{ 8940b57cec5SDimitry Andric return __c.real(); 8950b57cec5SDimitry Andric} 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andrictemplate <class _Tp> 898*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 8990b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 9000b57cec5SDimitry Andricreal(_Tp __re) 9010b57cec5SDimitry Andric{ 9020b57cec5SDimitry Andric return __re; 9030b57cec5SDimitry Andric} 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric// imag 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andrictemplate<class _Tp> 908*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 9090b57cec5SDimitry Andric_Tp 9100b57cec5SDimitry Andricimag(const complex<_Tp>& __c) 9110b57cec5SDimitry Andric{ 9120b57cec5SDimitry Andric return __c.imag(); 9130b57cec5SDimitry Andric} 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andrictemplate <class _Tp> 916*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 9170b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 9180b57cec5SDimitry Andricimag(_Tp) 9190b57cec5SDimitry Andric{ 9200b57cec5SDimitry Andric return 0; 9210b57cec5SDimitry Andric} 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric// abs 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andrictemplate<class _Tp> 926*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 9270b57cec5SDimitry Andric_Tp 9280b57cec5SDimitry Andricabs(const complex<_Tp>& __c) 9290b57cec5SDimitry Andric{ 930bdd1243dSDimitry Andric return std::hypot(__c.real(), __c.imag()); 9310b57cec5SDimitry Andric} 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric// arg 9340b57cec5SDimitry Andric 9350b57cec5SDimitry Andrictemplate<class _Tp> 936*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 9370b57cec5SDimitry Andric_Tp 9380b57cec5SDimitry Andricarg(const complex<_Tp>& __c) 9390b57cec5SDimitry Andric{ 940bdd1243dSDimitry Andric return std::atan2(__c.imag(), __c.real()); 9410b57cec5SDimitry Andric} 9420b57cec5SDimitry Andric 943*5f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0> 944*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 9450b57cec5SDimitry Andriclong double 9460b57cec5SDimitry Andricarg(_Tp __re) 9470b57cec5SDimitry Andric{ 948bdd1243dSDimitry Andric return std::atan2l(0.L, __re); 9490b57cec5SDimitry Andric} 9500b57cec5SDimitry Andric 951*5f757f3fSDimitry Andrictemplate<class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0> 952*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 9530b57cec5SDimitry Andricdouble 9540b57cec5SDimitry Andricarg(_Tp __re) 9550b57cec5SDimitry Andric{ 956bdd1243dSDimitry Andric return std::atan2(0., __re); 9570b57cec5SDimitry Andric} 9580b57cec5SDimitry Andric 959*5f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0> 960*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 9610b57cec5SDimitry Andricfloat 9620b57cec5SDimitry Andricarg(_Tp __re) 9630b57cec5SDimitry Andric{ 964bdd1243dSDimitry Andric return std::atan2f(0.F, __re); 9650b57cec5SDimitry Andric} 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric// norm 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andrictemplate<class _Tp> 970*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 9710b57cec5SDimitry Andric_Tp 9720b57cec5SDimitry Andricnorm(const complex<_Tp>& __c) 9730b57cec5SDimitry Andric{ 974bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real())) 975bdd1243dSDimitry Andric return std::abs(__c.real()); 976bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.imag())) 977bdd1243dSDimitry Andric return std::abs(__c.imag()); 9780b57cec5SDimitry Andric return __c.real() * __c.real() + __c.imag() * __c.imag(); 9790b57cec5SDimitry Andric} 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andrictemplate <class _Tp> 982*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 9830b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 9840b57cec5SDimitry Andricnorm(_Tp __re) 9850b57cec5SDimitry Andric{ 9860b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; 9870b57cec5SDimitry Andric return static_cast<_ValueType>(__re) * __re; 9880b57cec5SDimitry Andric} 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric// conj 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andrictemplate<class _Tp> 993*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 9940b57cec5SDimitry Andriccomplex<_Tp> 9950b57cec5SDimitry Andricconj(const complex<_Tp>& __c) 9960b57cec5SDimitry Andric{ 9970b57cec5SDimitry Andric return complex<_Tp>(__c.real(), -__c.imag()); 9980b57cec5SDimitry Andric} 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andrictemplate <class _Tp> 1001*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 10020b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType 10030b57cec5SDimitry Andricconj(_Tp __re) 10040b57cec5SDimitry Andric{ 10050b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 10060b57cec5SDimitry Andric return _ComplexType(__re); 10070b57cec5SDimitry Andric} 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric// proj 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andrictemplate<class _Tp> 1014*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 10150b57cec5SDimitry Andriccomplex<_Tp> 10160b57cec5SDimitry Andricproj(const complex<_Tp>& __c) 10170b57cec5SDimitry Andric{ 1018e8d8bef9SDimitry Andric complex<_Tp> __r = __c; 1019bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag())) 1020bdd1243dSDimitry Andric __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag())); 10210b57cec5SDimitry Andric return __r; 10220b57cec5SDimitry Andric} 10230b57cec5SDimitry Andric 1024*5f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 1025*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 10260b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType 10270b57cec5SDimitry Andricproj(_Tp __re) 10280b57cec5SDimitry Andric{ 1029bdd1243dSDimitry Andric if (std::__constexpr_isinf(__re)) 1030bdd1243dSDimitry Andric __re = std::abs(__re); 10310b57cec5SDimitry Andric return complex<_Tp>(__re); 10320b57cec5SDimitry Andric} 10330b57cec5SDimitry Andric 1034*5f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 1035*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 10360b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType 10370b57cec5SDimitry Andricproj(_Tp __re) 10380b57cec5SDimitry Andric{ 10390b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 10400b57cec5SDimitry Andric return _ComplexType(__re); 10410b57cec5SDimitry Andric} 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric// polar 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andrictemplate<class _Tp> 1046bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 10470b57cec5SDimitry Andricpolar(const _Tp& __rho, const _Tp& __theta = _Tp()) 10480b57cec5SDimitry Andric{ 1049bdd1243dSDimitry Andric if (std::__constexpr_isnan(__rho) || std::signbit(__rho)) 10500b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 1051bdd1243dSDimitry Andric if (std::__constexpr_isnan(__theta)) 10520b57cec5SDimitry Andric { 1053bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10540b57cec5SDimitry Andric return complex<_Tp>(__rho, __theta); 10550b57cec5SDimitry Andric return complex<_Tp>(__theta, __theta); 10560b57cec5SDimitry Andric } 1057bdd1243dSDimitry Andric if (std::__constexpr_isinf(__theta)) 10580b57cec5SDimitry Andric { 1059bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10600b57cec5SDimitry Andric return complex<_Tp>(__rho, _Tp(NAN)); 10610b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 10620b57cec5SDimitry Andric } 1063bdd1243dSDimitry Andric _Tp __x = __rho * std::cos(__theta); 1064bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x)) 10650b57cec5SDimitry Andric __x = 0; 1066bdd1243dSDimitry Andric _Tp __y = __rho * std::sin(__theta); 1067bdd1243dSDimitry Andric if (std::__constexpr_isnan(__y)) 10680b57cec5SDimitry Andric __y = 0; 10690b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 10700b57cec5SDimitry Andric} 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric// log 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andrictemplate<class _Tp> 1075*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 10760b57cec5SDimitry Andriccomplex<_Tp> 10770b57cec5SDimitry Andriclog(const complex<_Tp>& __x) 10780b57cec5SDimitry Andric{ 1079bdd1243dSDimitry Andric return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x)); 10800b57cec5SDimitry Andric} 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric// log10 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andrictemplate<class _Tp> 1085*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 10860b57cec5SDimitry Andriccomplex<_Tp> 10870b57cec5SDimitry Andriclog10(const complex<_Tp>& __x) 10880b57cec5SDimitry Andric{ 1089bdd1243dSDimitry Andric return std::log(__x) / std::log(_Tp(10)); 10900b57cec5SDimitry Andric} 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric// sqrt 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andrictemplate<class _Tp> 1095bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 10960b57cec5SDimitry Andricsqrt(const complex<_Tp>& __x) 10970b57cec5SDimitry Andric{ 1098bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 10990b57cec5SDimitry Andric return complex<_Tp>(_Tp(INFINITY), __x.imag()); 1100bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 11010b57cec5SDimitry Andric { 11020b57cec5SDimitry Andric if (__x.real() > _Tp(0)) 1103bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag())); 1104bdd1243dSDimitry Andric return complex<_Tp>(std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag())); 11050b57cec5SDimitry Andric } 1106bdd1243dSDimitry Andric return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2)); 11070b57cec5SDimitry Andric} 11080b57cec5SDimitry Andric 11090b57cec5SDimitry Andric// exp 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andrictemplate<class _Tp> 1112bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 11130b57cec5SDimitry Andricexp(const complex<_Tp>& __x) 11140b57cec5SDimitry Andric{ 11150b57cec5SDimitry Andric _Tp __i = __x.imag(); 1116349cc55cSDimitry Andric if (__i == 0) { 1117bdd1243dSDimitry Andric return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag())); 1118349cc55cSDimitry Andric } 1119bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 11200b57cec5SDimitry Andric { 11210b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 11220b57cec5SDimitry Andric { 1123bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__i)) 11240b57cec5SDimitry Andric __i = _Tp(1); 11250b57cec5SDimitry Andric } 1126bdd1243dSDimitry Andric else if (__i == 0 || !std::__constexpr_isfinite(__i)) 11270b57cec5SDimitry Andric { 1128bdd1243dSDimitry Andric if (std::__constexpr_isinf(__i)) 11290b57cec5SDimitry Andric __i = _Tp(NAN); 11300b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __i); 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric } 1133bdd1243dSDimitry Andric _Tp __e = std::exp(__x.real()); 1134bdd1243dSDimitry Andric return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i)); 11350b57cec5SDimitry Andric} 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric// pow 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andrictemplate<class _Tp> 1140*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 11410b57cec5SDimitry Andriccomplex<_Tp> 11420b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Tp>& __y) 11430b57cec5SDimitry Andric{ 1144bdd1243dSDimitry Andric return std::exp(__y * std::log(__x)); 11450b57cec5SDimitry Andric} 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andrictemplate<class _Tp, class _Up> 1148*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 11490b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type> 11500b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) 11510b57cec5SDimitry Andric{ 11520b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 1153*5f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11540b57cec5SDimitry Andric} 11550b57cec5SDimitry Andric 1156*5f757f3fSDimitry Andrictemplate<class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0> 1157*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 11580b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type> 11590b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const _Up& __y) 11600b57cec5SDimitry Andric{ 11610b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 1162*5f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11630b57cec5SDimitry Andric} 11640b57cec5SDimitry Andric 1165*5f757f3fSDimitry Andrictemplate<class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value, int> = 0> 1166*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 11670b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type> 11680b57cec5SDimitry Andricpow(const _Tp& __x, const complex<_Up>& __y) 11690b57cec5SDimitry Andric{ 11700b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 1171*5f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11720b57cec5SDimitry Andric} 11730b57cec5SDimitry Andric 11740b57cec5SDimitry Andric// __sqr, computes pow(x, 2) 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andrictemplate<class _Tp> 1177*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 11780b57cec5SDimitry Andriccomplex<_Tp> 11790b57cec5SDimitry Andric__sqr(const complex<_Tp>& __x) 11800b57cec5SDimitry Andric{ 11810b57cec5SDimitry Andric return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), 11820b57cec5SDimitry Andric _Tp(2) * __x.real() * __x.imag()); 11830b57cec5SDimitry Andric} 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric// asinh 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andrictemplate<class _Tp> 1188bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 11890b57cec5SDimitry Andricasinh(const complex<_Tp>& __x) 11900b57cec5SDimitry Andric{ 11910b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1192bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 11930b57cec5SDimitry Andric { 1194bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 11950b57cec5SDimitry Andric return __x; 1196bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1197bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 1198bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11990b57cec5SDimitry Andric } 1200bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real())) 12010b57cec5SDimitry Andric { 1202bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12030b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 12040b57cec5SDimitry Andric if (__x.imag() == 0) 12050b57cec5SDimitry Andric return __x; 12060b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12070b57cec5SDimitry Andric } 1208bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1209bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi/_Tp(2), __x.imag())); 1210bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1))); 1211bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 12120b57cec5SDimitry Andric} 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric// acosh 12150b57cec5SDimitry Andric 12160b57cec5SDimitry Andrictemplate<class _Tp> 1217bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 12180b57cec5SDimitry Andricacosh(const complex<_Tp>& __x) 12190b57cec5SDimitry Andric{ 12200b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1221bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 12220b57cec5SDimitry Andric { 1223bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 1224bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1225bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12260b57cec5SDimitry Andric { 12270b57cec5SDimitry Andric if (__x.real() > 0) 1228bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 12290b57cec5SDimitry Andric else 1230bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag())); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric if (__x.real() < 0) 1233bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag())); 1234bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 12350b57cec5SDimitry Andric } 1236bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real())) 12370b57cec5SDimitry Andric { 1238bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1239bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), __x.real()); 12400b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12410b57cec5SDimitry Andric } 1242bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1243bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi/_Tp(2), __x.imag())); 1244bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1245bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag())); 12460b57cec5SDimitry Andric} 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric// atanh 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andrictemplate<class _Tp> 1251bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 12520b57cec5SDimitry Andricatanh(const complex<_Tp>& __x) 12530b57cec5SDimitry Andric{ 12540b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1255bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12560b57cec5SDimitry Andric { 1257bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag())); 12580b57cec5SDimitry Andric } 1259bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 12600b57cec5SDimitry Andric { 1261bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) || __x.real() == 0) 1262bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag()); 12630b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.imag()); 12640b57cec5SDimitry Andric } 1265bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real())) 12660b57cec5SDimitry Andric { 12670b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12680b57cec5SDimitry Andric } 1269bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 12700b57cec5SDimitry Andric { 1271bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi/_Tp(2), __x.imag())); 12720b57cec5SDimitry Andric } 1273bdd1243dSDimitry Andric if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) 12740b57cec5SDimitry Andric { 1275bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag())); 12760b57cec5SDimitry Andric } 1277bdd1243dSDimitry Andric complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); 1278bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 12790b57cec5SDimitry Andric} 12800b57cec5SDimitry Andric 12810b57cec5SDimitry Andric// sinh 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andrictemplate<class _Tp> 1284bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 12850b57cec5SDimitry Andricsinh(const complex<_Tp>& __x) 12860b57cec5SDimitry Andric{ 1287bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 12880b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1289bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 12900b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1291bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 12920b57cec5SDimitry Andric return __x; 1293bdd1243dSDimitry Andric return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag())); 12940b57cec5SDimitry Andric} 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric// cosh 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andrictemplate<class _Tp> 1299bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13000b57cec5SDimitry Andriccosh(const complex<_Tp>& __x) 13010b57cec5SDimitry Andric{ 1302bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 1303bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), _Tp(NAN)); 1304bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 13050b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), __x.real()); 13060b57cec5SDimitry Andric if (__x.real() == 0 && __x.imag() == 0) 13070b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), __x.imag()); 1308bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 1309bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1310bdd1243dSDimitry Andric return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag())); 13110b57cec5SDimitry Andric} 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric// tanh 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andrictemplate<class _Tp> 1316bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13170b57cec5SDimitry Andrictanh(const complex<_Tp>& __x) 13180b57cec5SDimitry Andric{ 1319bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 13200b57cec5SDimitry Andric { 1321bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__x.imag())) 1322bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0)); 1323bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag()))); 13240b57cec5SDimitry Andric } 1325bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0) 13260b57cec5SDimitry Andric return __x; 13270b57cec5SDimitry Andric _Tp __2r(_Tp(2) * __x.real()); 13280b57cec5SDimitry Andric _Tp __2i(_Tp(2) * __x.imag()); 1329bdd1243dSDimitry Andric _Tp __d(std::cosh(__2r) + std::cos(__2i)); 1330bdd1243dSDimitry Andric _Tp __2rsh(std::sinh(__2r)); 1331bdd1243dSDimitry Andric if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d)) 13320b57cec5SDimitry Andric return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), 13330b57cec5SDimitry Andric __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); 1334bdd1243dSDimitry Andric return complex<_Tp>(__2rsh/__d, std::sin(__2i)/__d); 13350b57cec5SDimitry Andric} 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric// asin 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andrictemplate<class _Tp> 1340bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13410b57cec5SDimitry Andricasin(const complex<_Tp>& __x) 13420b57cec5SDimitry Andric{ 1343bdd1243dSDimitry Andric complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real())); 13440b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13450b57cec5SDimitry Andric} 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric// acos 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andrictemplate<class _Tp> 1350bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13510b57cec5SDimitry Andricacos(const complex<_Tp>& __x) 13520b57cec5SDimitry Andric{ 13530b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1354bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real())) 13550b57cec5SDimitry Andric { 1356bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 13570b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 1358bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 13590b57cec5SDimitry Andric { 13600b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 13610b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); 13620b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 1365bdd1243dSDimitry Andric return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real()); 1366bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real()); 13670b57cec5SDimitry Andric } 1368bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real())) 13690b57cec5SDimitry Andric { 1370bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 13710b57cec5SDimitry Andric return complex<_Tp>(__x.real(), -__x.imag()); 13720b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 13730b57cec5SDimitry Andric } 1374bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 13750b57cec5SDimitry Andric return complex<_Tp>(__pi/_Tp(2), -__x.imag()); 1376bdd1243dSDimitry Andric if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag()))) 13770b57cec5SDimitry Andric return complex<_Tp>(__pi/_Tp(2), -__x.imag()); 1378bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1379bdd1243dSDimitry Andric if (std::signbit(__x.imag())) 1380bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real())); 1381bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real())); 13820b57cec5SDimitry Andric} 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric// atan 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andrictemplate<class _Tp> 1387bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13880b57cec5SDimitry Andricatan(const complex<_Tp>& __x) 13890b57cec5SDimitry Andric{ 1390bdd1243dSDimitry Andric complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real())); 13910b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13920b57cec5SDimitry Andric} 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric// sin 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andrictemplate<class _Tp> 1397bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 13980b57cec5SDimitry Andricsin(const complex<_Tp>& __x) 13990b57cec5SDimitry Andric{ 1400bdd1243dSDimitry Andric complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real())); 14010b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 14020b57cec5SDimitry Andric} 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric// cos 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andrictemplate<class _Tp> 1407*5f757f3fSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI 14080b57cec5SDimitry Andriccomplex<_Tp> 14090b57cec5SDimitry Andriccos(const complex<_Tp>& __x) 14100b57cec5SDimitry Andric{ 1411bdd1243dSDimitry Andric return std::cosh(complex<_Tp>(-__x.imag(), __x.real())); 14120b57cec5SDimitry Andric} 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric// tan 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andrictemplate<class _Tp> 1417bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> 14180b57cec5SDimitry Andrictan(const complex<_Tp>& __x) 14190b57cec5SDimitry Andric{ 1420bdd1243dSDimitry Andric complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real())); 14210b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 14220b57cec5SDimitry Andric} 14230b57cec5SDimitry Andric 1424bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 14250b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits> 1426bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 14270b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 14280b57cec5SDimitry Andric{ 14290b57cec5SDimitry Andric if (__is.good()) 14300b57cec5SDimitry Andric { 1431bdd1243dSDimitry Andric std::ws(__is); 14320b57cec5SDimitry Andric if (__is.peek() == _CharT('(')) 14330b57cec5SDimitry Andric { 14340b57cec5SDimitry Andric __is.get(); 14350b57cec5SDimitry Andric _Tp __r; 14360b57cec5SDimitry Andric __is >> __r; 14370b57cec5SDimitry Andric if (!__is.fail()) 14380b57cec5SDimitry Andric { 1439bdd1243dSDimitry Andric std::ws(__is); 14400b57cec5SDimitry Andric _CharT __c = __is.peek(); 14410b57cec5SDimitry Andric if (__c == _CharT(',')) 14420b57cec5SDimitry Andric { 14430b57cec5SDimitry Andric __is.get(); 14440b57cec5SDimitry Andric _Tp __i; 14450b57cec5SDimitry Andric __is >> __i; 14460b57cec5SDimitry Andric if (!__is.fail()) 14470b57cec5SDimitry Andric { 1448bdd1243dSDimitry Andric std::ws(__is); 14490b57cec5SDimitry Andric __c = __is.peek(); 14500b57cec5SDimitry Andric if (__c == _CharT(')')) 14510b57cec5SDimitry Andric { 14520b57cec5SDimitry Andric __is.get(); 14530b57cec5SDimitry Andric __x = complex<_Tp>(__r, __i); 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric else 14565ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14570b57cec5SDimitry Andric } 14580b57cec5SDimitry Andric else 14595ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14600b57cec5SDimitry Andric } 14610b57cec5SDimitry Andric else if (__c == _CharT(')')) 14620b57cec5SDimitry Andric { 14630b57cec5SDimitry Andric __is.get(); 14640b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 14650b57cec5SDimitry Andric } 14660b57cec5SDimitry Andric else 14675ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14680b57cec5SDimitry Andric } 14690b57cec5SDimitry Andric else 14705ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric else 14730b57cec5SDimitry Andric { 14740b57cec5SDimitry Andric _Tp __r; 14750b57cec5SDimitry Andric __is >> __r; 14760b57cec5SDimitry Andric if (!__is.fail()) 14770b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 14780b57cec5SDimitry Andric else 14795ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14800b57cec5SDimitry Andric } 14810b57cec5SDimitry Andric } 14820b57cec5SDimitry Andric else 14835ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14840b57cec5SDimitry Andric return __is; 14850b57cec5SDimitry Andric} 14860b57cec5SDimitry Andric 14870b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits> 1488bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 14890b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 14900b57cec5SDimitry Andric{ 14910b57cec5SDimitry Andric basic_ostringstream<_CharT, _Traits> __s; 14920b57cec5SDimitry Andric __s.flags(__os.flags()); 14930b57cec5SDimitry Andric __s.imbue(__os.getloc()); 14940b57cec5SDimitry Andric __s.precision(__os.precision()); 14950b57cec5SDimitry Andric __s << '(' << __x.real() << ',' << __x.imag() << ')'; 14960b57cec5SDimitry Andric return __os << __s.str(); 14970b57cec5SDimitry Andric} 1498e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION 14990b57cec5SDimitry Andric 150006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 15010b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals] 15020b57cec5SDimitry Andricinline namespace literals 15030b57cec5SDimitry Andric{ 15040b57cec5SDimitry Andric inline namespace complex_literals 15050b57cec5SDimitry Andric { 1506*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(long double __im) 15070b57cec5SDimitry Andric { 15080b57cec5SDimitry Andric return { 0.0l, __im }; 15090b57cec5SDimitry Andric } 15100b57cec5SDimitry Andric 1511*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(unsigned long long __im) 15120b57cec5SDimitry Andric { 15130b57cec5SDimitry Andric return { 0.0l, static_cast<long double>(__im) }; 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric 1517*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(long double __im) 15180b57cec5SDimitry Andric { 15190b57cec5SDimitry Andric return { 0.0, static_cast<double>(__im) }; 15200b57cec5SDimitry Andric } 15210b57cec5SDimitry Andric 1522*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(unsigned long long __im) 15230b57cec5SDimitry Andric { 15240b57cec5SDimitry Andric return { 0.0, static_cast<double>(__im) }; 15250b57cec5SDimitry Andric } 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric 1528*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(long double __im) 15290b57cec5SDimitry Andric { 15300b57cec5SDimitry Andric return { 0.0f, static_cast<float>(__im) }; 15310b57cec5SDimitry Andric } 15320b57cec5SDimitry Andric 1533*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long long __im) 15340b57cec5SDimitry Andric { 15350b57cec5SDimitry Andric return { 0.0f, static_cast<float>(__im) }; 15360b57cec5SDimitry Andric } 15370eae32dcSDimitry Andric } // namespace complex_literals 15380eae32dcSDimitry Andric} // namespace literals 15390b57cec5SDimitry Andric#endif 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 15420b57cec5SDimitry Andric 154306c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1544*5f757f3fSDimitry Andric# include <iosfwd> 1545*5f757f3fSDimitry Andric# include <stdexcept> 154606c3fb27SDimitry Andric# include <type_traits> 154706c3fb27SDimitry Andric#endif 154806c3fb27SDimitry Andric 15490b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX 1550