10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===--------------------------- complex ----------------------------------===// 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 320b57cec5SDimitry Andric void real(T); 330b57cec5SDimitry Andric void imag(T); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric complex<T>& operator= (const T&); 360b57cec5SDimitry Andric complex<T>& operator+=(const T&); 370b57cec5SDimitry Andric complex<T>& operator-=(const T&); 380b57cec5SDimitry Andric complex<T>& operator*=(const T&); 390b57cec5SDimitry Andric complex<T>& operator/=(const T&); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric complex& operator=(const complex&); 420b57cec5SDimitry Andric template<class X> complex<T>& operator= (const complex<X>&); 430b57cec5SDimitry Andric template<class X> complex<T>& operator+=(const complex<X>&); 440b57cec5SDimitry Andric template<class X> complex<T>& operator-=(const complex<X>&); 450b57cec5SDimitry Andric template<class X> complex<T>& operator*=(const complex<X>&); 460b57cec5SDimitry Andric template<class X> complex<T>& operator/=(const complex<X>&); 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; 600b57cec5SDimitry Andric void real(float); 610b57cec5SDimitry Andric constexpr float imag() const; 620b57cec5SDimitry Andric void imag(float); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric complex<float>& operator= (float); 650b57cec5SDimitry Andric complex<float>& operator+=(float); 660b57cec5SDimitry Andric complex<float>& operator-=(float); 670b57cec5SDimitry Andric complex<float>& operator*=(float); 680b57cec5SDimitry Andric complex<float>& operator/=(float); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric complex<float>& operator=(const complex<float>&); 710b57cec5SDimitry Andric template<class X> complex<float>& operator= (const complex<X>&); 720b57cec5SDimitry Andric template<class X> complex<float>& operator+=(const complex<X>&); 730b57cec5SDimitry Andric template<class X> complex<float>& operator-=(const complex<X>&); 740b57cec5SDimitry Andric template<class X> complex<float>& operator*=(const complex<X>&); 750b57cec5SDimitry Andric template<class X> complex<float>& operator/=(const complex<X>&); 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; 890b57cec5SDimitry Andric void real(double); 900b57cec5SDimitry Andric constexpr double imag() const; 910b57cec5SDimitry Andric void imag(double); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric complex<double>& operator= (double); 940b57cec5SDimitry Andric complex<double>& operator+=(double); 950b57cec5SDimitry Andric complex<double>& operator-=(double); 960b57cec5SDimitry Andric complex<double>& operator*=(double); 970b57cec5SDimitry Andric complex<double>& operator/=(double); 980b57cec5SDimitry Andric complex<double>& operator=(const complex<double>&); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric template<class X> complex<double>& operator= (const complex<X>&); 1010b57cec5SDimitry Andric template<class X> complex<double>& operator+=(const complex<X>&); 1020b57cec5SDimitry Andric template<class X> complex<double>& operator-=(const complex<X>&); 1030b57cec5SDimitry Andric template<class X> complex<double>& operator*=(const complex<X>&); 1040b57cec5SDimitry Andric template<class X> complex<double>& operator/=(const complex<X>&); 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; 1180b57cec5SDimitry Andric void real(long double); 1190b57cec5SDimitry Andric constexpr long double imag() const; 1200b57cec5SDimitry Andric void imag(long double); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric complex<long double>& operator=(const complex<long double>&); 1230b57cec5SDimitry Andric complex<long double>& operator= (long double); 1240b57cec5SDimitry Andric complex<long double>& operator+=(long double); 1250b57cec5SDimitry Andric complex<long double>& operator-=(long double); 1260b57cec5SDimitry Andric complex<long double>& operator*=(long double); 1270b57cec5SDimitry Andric complex<long double>& operator/=(long double); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric template<class X> complex<long double>& operator= (const complex<X>&); 1300b57cec5SDimitry Andric template<class X> complex<long double>& operator+=(const complex<X>&); 1310b57cec5SDimitry Andric template<class X> complex<long double>& operator-=(const complex<X>&); 1320b57cec5SDimitry Andric template<class X> complex<long double>& operator*=(const complex<X>&); 1330b57cec5SDimitry Andric template<class X> complex<long double>& operator/=(const complex<X>&); 1340b57cec5SDimitry Andric}; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric// 26.3.6 operators: 1370b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&); 1380b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const T&); 1390b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const T&, const complex<T>&); 1400b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&); 1410b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const T&); 1420b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const T&, const complex<T>&); 1430b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&); 1440b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const T&); 1450b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const T&, const complex<T>&); 1460b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&); 1470b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const T&); 1480b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const T&, const complex<T>&); 1490b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&); 1500b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&); 1510b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14 1520b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14 1530b57cec5SDimitry Andrictemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14 1540b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14 1550b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14 1560b57cec5SDimitry Andrictemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andrictemplate<class T, class charT, class traits> 1590b57cec5SDimitry Andric basic_istream<charT, traits>& 1600b57cec5SDimitry Andric operator>>(basic_istream<charT, traits>&, complex<T>&); 1610b57cec5SDimitry Andrictemplate<class T, class charT, class traits> 1620b57cec5SDimitry Andric basic_ostream<charT, traits>& 1630b57cec5SDimitry Andric operator<<(basic_ostream<charT, traits>&, const complex<T>&); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric// 26.3.7 values: 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andrictemplate<class T> T real(const complex<T>&); // constexpr in C++14 1680b57cec5SDimitry Andric long double real(long double); // constexpr in C++14 1690b57cec5SDimitry Andric double real(double); // constexpr in C++14 1700b57cec5SDimitry Andrictemplate<Integral T> double real(T); // constexpr in C++14 1710b57cec5SDimitry Andric float real(float); // constexpr in C++14 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andrictemplate<class T> T imag(const complex<T>&); // constexpr in C++14 1740b57cec5SDimitry Andric long double imag(long double); // constexpr in C++14 1750b57cec5SDimitry Andric double imag(double); // constexpr in C++14 1760b57cec5SDimitry Andrictemplate<Integral T> double imag(T); // constexpr in C++14 1770b57cec5SDimitry Andric float imag(float); // constexpr in C++14 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andrictemplate<class T> T abs(const complex<T>&); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andrictemplate<class T> T arg(const complex<T>&); 1820b57cec5SDimitry Andric long double arg(long double); 1830b57cec5SDimitry Andric double arg(double); 1840b57cec5SDimitry Andrictemplate<Integral T> double arg(T); 1850b57cec5SDimitry Andric float arg(float); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andrictemplate<class T> T norm(const complex<T>&); 1880b57cec5SDimitry Andric long double norm(long double); 1890b57cec5SDimitry Andric double norm(double); 1900b57cec5SDimitry Andrictemplate<Integral T> double norm(T); 1910b57cec5SDimitry Andric float norm(float); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andrictemplate<class T> complex<T> conj(const complex<T>&); 1940b57cec5SDimitry Andric complex<long double> conj(long double); 1950b57cec5SDimitry Andric complex<double> conj(double); 1960b57cec5SDimitry Andrictemplate<Integral T> complex<double> conj(T); 1970b57cec5SDimitry Andric complex<float> conj(float); 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 Andrictemplate<class T, class charT, class traits> 2310b57cec5SDimitry Andric basic_istream<charT, traits>& 2320b57cec5SDimitry Andric operator>>(basic_istream<charT, traits>& is, complex<T>& x); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andrictemplate<class T, class charT, class traits> 2350b57cec5SDimitry Andric basic_ostream<charT, traits>& 2360b57cec5SDimitry Andric operator<<(basic_ostream<charT, traits>& o, const complex<T>& x); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric} // std 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric*/ 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric#include <__config> 2430b57cec5SDimitry Andric#include <type_traits> 2440b57cec5SDimitry Andric#include <stdexcept> 2450b57cec5SDimitry Andric#include <cmath> 246*5ffd83dbSDimitry Andric#include <iosfwd> 2470b57cec5SDimitry Andric#include <sstream> 2480b57cec5SDimitry Andric#include <version> 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2510b57cec5SDimitry Andric#pragma GCC system_header 2520b57cec5SDimitry Andric#endif 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andrictemplate<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 2590b57cec5SDimitry Andrictemplate<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andrictemplate<class _Tp> 2620b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex 2630b57cec5SDimitry Andric{ 2640b57cec5SDimitry Andricpublic: 2650b57cec5SDimitry Andric typedef _Tp value_type; 2660b57cec5SDimitry Andricprivate: 2670b57cec5SDimitry Andric value_type __re_; 2680b57cec5SDimitry Andric value_type __im_; 2690b57cec5SDimitry Andricpublic: 2700b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2710b57cec5SDimitry Andric complex(const value_type& __re = value_type(), const value_type& __im = value_type()) 2720b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 2730b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 2740b57cec5SDimitry Andric complex(const complex<_Xp>& __c) 2750b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} 2780b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} 2810b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) 2840b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 2850b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} 2860b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} 2870b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} 2880b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) 2910b57cec5SDimitry Andric { 2920b57cec5SDimitry Andric __re_ = __c.real(); 2930b57cec5SDimitry Andric __im_ = __c.imag(); 2940b57cec5SDimitry Andric return *this; 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) 2970b57cec5SDimitry Andric { 2980b57cec5SDimitry Andric __re_ += __c.real(); 2990b57cec5SDimitry Andric __im_ += __c.imag(); 3000b57cec5SDimitry Andric return *this; 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) 3030b57cec5SDimitry Andric { 3040b57cec5SDimitry Andric __re_ -= __c.real(); 3050b57cec5SDimitry Andric __im_ -= __c.imag(); 3060b57cec5SDimitry Andric return *this; 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) 3090b57cec5SDimitry Andric { 3100b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3110b57cec5SDimitry Andric return *this; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) 3140b57cec5SDimitry Andric { 3150b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3160b57cec5SDimitry Andric return *this; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric}; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>; 3210b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andrictemplate<> 3240b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float> 3250b57cec5SDimitry Andric{ 3260b57cec5SDimitry Andric float __re_; 3270b57cec5SDimitry Andric float __im_; 3280b57cec5SDimitry Andricpublic: 3290b57cec5SDimitry Andric typedef float value_type; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) 3320b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 3330b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3340b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 3350b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3360b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} 3390b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} 3420b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) 3450b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 3460b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} 3470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} 3480b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} 3490b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) 3520b57cec5SDimitry Andric { 3530b57cec5SDimitry Andric __re_ = __c.real(); 3540b57cec5SDimitry Andric __im_ = __c.imag(); 3550b57cec5SDimitry Andric return *this; 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) 3580b57cec5SDimitry Andric { 3590b57cec5SDimitry Andric __re_ += __c.real(); 3600b57cec5SDimitry Andric __im_ += __c.imag(); 3610b57cec5SDimitry Andric return *this; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) 3640b57cec5SDimitry Andric { 3650b57cec5SDimitry Andric __re_ -= __c.real(); 3660b57cec5SDimitry Andric __im_ -= __c.imag(); 3670b57cec5SDimitry Andric return *this; 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) 3700b57cec5SDimitry Andric { 3710b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3720b57cec5SDimitry Andric return *this; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) 3750b57cec5SDimitry Andric { 3760b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3770b57cec5SDimitry Andric return *this; 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric}; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andrictemplate<> 3820b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> 3830b57cec5SDimitry Andric{ 3840b57cec5SDimitry Andric double __re_; 3850b57cec5SDimitry Andric double __im_; 3860b57cec5SDimitry Andricpublic: 3870b57cec5SDimitry Andric typedef double value_type; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) 3900b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 3910b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3920b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 3930b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3940b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} 3970b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} 4000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) 4030b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 4040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} 4050b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} 4060b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} 4070b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) 4100b57cec5SDimitry Andric { 4110b57cec5SDimitry Andric __re_ = __c.real(); 4120b57cec5SDimitry Andric __im_ = __c.imag(); 4130b57cec5SDimitry Andric return *this; 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) 4160b57cec5SDimitry Andric { 4170b57cec5SDimitry Andric __re_ += __c.real(); 4180b57cec5SDimitry Andric __im_ += __c.imag(); 4190b57cec5SDimitry Andric return *this; 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) 4220b57cec5SDimitry Andric { 4230b57cec5SDimitry Andric __re_ -= __c.real(); 4240b57cec5SDimitry Andric __im_ -= __c.imag(); 4250b57cec5SDimitry Andric return *this; 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) 4280b57cec5SDimitry Andric { 4290b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4300b57cec5SDimitry Andric return *this; 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) 4330b57cec5SDimitry Andric { 4340b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4350b57cec5SDimitry Andric return *this; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric}; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andrictemplate<> 4400b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> 4410b57cec5SDimitry Andric{ 4420b57cec5SDimitry Andric long double __re_; 4430b57cec5SDimitry Andric long double __im_; 4440b57cec5SDimitry Andricpublic: 4450b57cec5SDimitry Andric typedef long double value_type; 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) 4480b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 4490b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4500b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 4510b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4520b57cec5SDimitry Andric _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} 4550b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} 4580b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) 4610b57cec5SDimitry Andric {__re_ = __re; __im_ = value_type(); return *this;} 4620b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} 4630b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} 4640b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} 4650b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) 4680b57cec5SDimitry Andric { 4690b57cec5SDimitry Andric __re_ = __c.real(); 4700b57cec5SDimitry Andric __im_ = __c.imag(); 4710b57cec5SDimitry Andric return *this; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) 4740b57cec5SDimitry Andric { 4750b57cec5SDimitry Andric __re_ += __c.real(); 4760b57cec5SDimitry Andric __im_ += __c.imag(); 4770b57cec5SDimitry Andric return *this; 4780b57cec5SDimitry Andric } 4790b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) 4800b57cec5SDimitry Andric { 4810b57cec5SDimitry Andric __re_ -= __c.real(); 4820b57cec5SDimitry Andric __im_ -= __c.imag(); 4830b57cec5SDimitry Andric return *this; 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) 4860b57cec5SDimitry Andric { 4870b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4880b57cec5SDimitry Andric return *this; 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) 4910b57cec5SDimitry Andric { 4920b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4930b57cec5SDimitry Andric return *this; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric}; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andricinline 4980b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 4990b57cec5SDimitry Andriccomplex<float>::complex(const complex<double>& __c) 5000b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andricinline 5030b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5040b57cec5SDimitry Andriccomplex<float>::complex(const complex<long double>& __c) 5050b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andricinline 5080b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5090b57cec5SDimitry Andriccomplex<double>::complex(const complex<float>& __c) 5100b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andricinline 5130b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5140b57cec5SDimitry Andriccomplex<double>::complex(const complex<long double>& __c) 5150b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andricinline 5180b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5190b57cec5SDimitry Andriccomplex<long double>::complex(const complex<float>& __c) 5200b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andricinline 5230b57cec5SDimitry Andric_LIBCPP_CONSTEXPR 5240b57cec5SDimitry Andriccomplex<long double>::complex(const complex<double>& __c) 5250b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric// 26.3.6 operators: 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andrictemplate<class _Tp> 5300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5310b57cec5SDimitry Andriccomplex<_Tp> 5320b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 5330b57cec5SDimitry Andric{ 5340b57cec5SDimitry Andric complex<_Tp> __t(__x); 5350b57cec5SDimitry Andric __t += __y; 5360b57cec5SDimitry Andric return __t; 5370b57cec5SDimitry Andric} 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andrictemplate<class _Tp> 5400b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5410b57cec5SDimitry Andriccomplex<_Tp> 5420b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) 5430b57cec5SDimitry Andric{ 5440b57cec5SDimitry Andric complex<_Tp> __t(__x); 5450b57cec5SDimitry Andric __t += __y; 5460b57cec5SDimitry Andric return __t; 5470b57cec5SDimitry Andric} 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andrictemplate<class _Tp> 5500b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5510b57cec5SDimitry Andriccomplex<_Tp> 5520b57cec5SDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) 5530b57cec5SDimitry Andric{ 5540b57cec5SDimitry Andric complex<_Tp> __t(__y); 5550b57cec5SDimitry Andric __t += __x; 5560b57cec5SDimitry Andric return __t; 5570b57cec5SDimitry Andric} 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andrictemplate<class _Tp> 5600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5610b57cec5SDimitry Andriccomplex<_Tp> 5620b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 5630b57cec5SDimitry Andric{ 5640b57cec5SDimitry Andric complex<_Tp> __t(__x); 5650b57cec5SDimitry Andric __t -= __y; 5660b57cec5SDimitry Andric return __t; 5670b57cec5SDimitry Andric} 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andrictemplate<class _Tp> 5700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5710b57cec5SDimitry Andriccomplex<_Tp> 5720b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) 5730b57cec5SDimitry Andric{ 5740b57cec5SDimitry Andric complex<_Tp> __t(__x); 5750b57cec5SDimitry Andric __t -= __y; 5760b57cec5SDimitry Andric return __t; 5770b57cec5SDimitry Andric} 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andrictemplate<class _Tp> 5800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5810b57cec5SDimitry Andriccomplex<_Tp> 5820b57cec5SDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) 5830b57cec5SDimitry Andric{ 5840b57cec5SDimitry Andric complex<_Tp> __t(-__y); 5850b57cec5SDimitry Andric __t += __x; 5860b57cec5SDimitry Andric return __t; 5870b57cec5SDimitry Andric} 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andrictemplate<class _Tp> 5900b57cec5SDimitry Andriccomplex<_Tp> 5910b57cec5SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) 5920b57cec5SDimitry Andric{ 5930b57cec5SDimitry Andric _Tp __a = __z.real(); 5940b57cec5SDimitry Andric _Tp __b = __z.imag(); 5950b57cec5SDimitry Andric _Tp __c = __w.real(); 5960b57cec5SDimitry Andric _Tp __d = __w.imag(); 5970b57cec5SDimitry Andric _Tp __ac = __a * __c; 5980b57cec5SDimitry Andric _Tp __bd = __b * __d; 5990b57cec5SDimitry Andric _Tp __ad = __a * __d; 6000b57cec5SDimitry Andric _Tp __bc = __b * __c; 6010b57cec5SDimitry Andric _Tp __x = __ac - __bd; 6020b57cec5SDimitry Andric _Tp __y = __ad + __bc; 6030b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) 6040b57cec5SDimitry Andric { 6050b57cec5SDimitry Andric bool __recalc = false; 6060b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) 6070b57cec5SDimitry Andric { 6080b57cec5SDimitry Andric __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); 6090b57cec5SDimitry Andric __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); 6100b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__c)) 6110b57cec5SDimitry Andric __c = copysign(_Tp(0), __c); 6120b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__d)) 6130b57cec5SDimitry Andric __d = copysign(_Tp(0), __d); 6140b57cec5SDimitry Andric __recalc = true; 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) 6170b57cec5SDimitry Andric { 6180b57cec5SDimitry Andric __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); 6190b57cec5SDimitry Andric __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); 6200b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__a)) 6210b57cec5SDimitry Andric __a = copysign(_Tp(0), __a); 6220b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__b)) 6230b57cec5SDimitry Andric __b = copysign(_Tp(0), __b); 6240b57cec5SDimitry Andric __recalc = true; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) || 6270b57cec5SDimitry Andric __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc))) 6280b57cec5SDimitry Andric { 6290b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__a)) 6300b57cec5SDimitry Andric __a = copysign(_Tp(0), __a); 6310b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__b)) 6320b57cec5SDimitry Andric __b = copysign(_Tp(0), __b); 6330b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__c)) 6340b57cec5SDimitry Andric __c = copysign(_Tp(0), __c); 6350b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__d)) 6360b57cec5SDimitry Andric __d = copysign(_Tp(0), __d); 6370b57cec5SDimitry Andric __recalc = true; 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric if (__recalc) 6400b57cec5SDimitry Andric { 6410b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c - __b * __d); 6420b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__a * __d + __b * __c); 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 6460b57cec5SDimitry Andric} 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andrictemplate<class _Tp> 6490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 6500b57cec5SDimitry Andriccomplex<_Tp> 6510b57cec5SDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) 6520b57cec5SDimitry Andric{ 6530b57cec5SDimitry Andric complex<_Tp> __t(__x); 6540b57cec5SDimitry Andric __t *= __y; 6550b57cec5SDimitry Andric return __t; 6560b57cec5SDimitry Andric} 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andrictemplate<class _Tp> 6590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 6600b57cec5SDimitry Andriccomplex<_Tp> 6610b57cec5SDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) 6620b57cec5SDimitry Andric{ 6630b57cec5SDimitry Andric complex<_Tp> __t(__y); 6640b57cec5SDimitry Andric __t *= __x; 6650b57cec5SDimitry Andric return __t; 6660b57cec5SDimitry Andric} 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andrictemplate<class _Tp> 6690b57cec5SDimitry Andriccomplex<_Tp> 6700b57cec5SDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) 6710b57cec5SDimitry Andric{ 6720b57cec5SDimitry Andric int __ilogbw = 0; 6730b57cec5SDimitry Andric _Tp __a = __z.real(); 6740b57cec5SDimitry Andric _Tp __b = __z.imag(); 6750b57cec5SDimitry Andric _Tp __c = __w.real(); 6760b57cec5SDimitry Andric _Tp __d = __w.imag(); 6770b57cec5SDimitry Andric _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); 6780b57cec5SDimitry Andric if (__libcpp_isfinite_or_builtin(__logbw)) 6790b57cec5SDimitry Andric { 6800b57cec5SDimitry Andric __ilogbw = static_cast<int>(__logbw); 6810b57cec5SDimitry Andric __c = scalbn(__c, -__ilogbw); 6820b57cec5SDimitry Andric __d = scalbn(__d, -__ilogbw); 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric _Tp __denom = __c * __c + __d * __d; 6850b57cec5SDimitry Andric _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); 6860b57cec5SDimitry Andric _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); 6870b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) 6880b57cec5SDimitry Andric { 6890b57cec5SDimitry Andric if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b))) 6900b57cec5SDimitry Andric { 6910b57cec5SDimitry Andric __x = copysign(_Tp(INFINITY), __c) * __a; 6920b57cec5SDimitry Andric __y = copysign(_Tp(INFINITY), __c) * __b; 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d)) 6950b57cec5SDimitry Andric { 6960b57cec5SDimitry Andric __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); 6970b57cec5SDimitry Andric __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); 6980b57cec5SDimitry Andric __x = _Tp(INFINITY) * (__a * __c + __b * __d); 6990b57cec5SDimitry Andric __y = _Tp(INFINITY) * (__b * __c - __a * __d); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b)) 7020b57cec5SDimitry Andric { 7030b57cec5SDimitry Andric __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); 7040b57cec5SDimitry Andric __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); 7050b57cec5SDimitry Andric __x = _Tp(0) * (__a * __c + __b * __d); 7060b57cec5SDimitry Andric __y = _Tp(0) * (__b * __c - __a * __d); 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric } 7090b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 7100b57cec5SDimitry Andric} 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andrictemplate<class _Tp> 7130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 7140b57cec5SDimitry Andriccomplex<_Tp> 7150b57cec5SDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) 7160b57cec5SDimitry Andric{ 7170b57cec5SDimitry Andric return complex<_Tp>(__x.real() / __y, __x.imag() / __y); 7180b57cec5SDimitry Andric} 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andrictemplate<class _Tp> 7210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 7220b57cec5SDimitry Andriccomplex<_Tp> 7230b57cec5SDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) 7240b57cec5SDimitry Andric{ 7250b57cec5SDimitry Andric complex<_Tp> __t(__x); 7260b57cec5SDimitry Andric __t /= __y; 7270b57cec5SDimitry Andric return __t; 7280b57cec5SDimitry Andric} 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andrictemplate<class _Tp> 7310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 7320b57cec5SDimitry Andriccomplex<_Tp> 7330b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x) 7340b57cec5SDimitry Andric{ 7350b57cec5SDimitry Andric return __x; 7360b57cec5SDimitry Andric} 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andrictemplate<class _Tp> 7390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 7400b57cec5SDimitry Andriccomplex<_Tp> 7410b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x) 7420b57cec5SDimitry Andric{ 7430b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), -__x.imag()); 7440b57cec5SDimitry Andric} 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andrictemplate<class _Tp> 7470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7480b57cec5SDimitry Andricbool 7490b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 7500b57cec5SDimitry Andric{ 7510b57cec5SDimitry Andric return __x.real() == __y.real() && __x.imag() == __y.imag(); 7520b57cec5SDimitry Andric} 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andrictemplate<class _Tp> 7550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7560b57cec5SDimitry Andricbool 7570b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const _Tp& __y) 7580b57cec5SDimitry Andric{ 7590b57cec5SDimitry Andric return __x.real() == __y && __x.imag() == 0; 7600b57cec5SDimitry Andric} 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andrictemplate<class _Tp> 7630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7640b57cec5SDimitry Andricbool 7650b57cec5SDimitry Andricoperator==(const _Tp& __x, const complex<_Tp>& __y) 7660b57cec5SDimitry Andric{ 7670b57cec5SDimitry Andric return __x == __y.real() && 0 == __y.imag(); 7680b57cec5SDimitry Andric} 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andrictemplate<class _Tp> 7710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7720b57cec5SDimitry Andricbool 7730b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 7740b57cec5SDimitry Andric{ 7750b57cec5SDimitry Andric return !(__x == __y); 7760b57cec5SDimitry Andric} 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andrictemplate<class _Tp> 7790b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7800b57cec5SDimitry Andricbool 7810b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const _Tp& __y) 7820b57cec5SDimitry Andric{ 7830b57cec5SDimitry Andric return !(__x == __y); 7840b57cec5SDimitry Andric} 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andrictemplate<class _Tp> 7870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 7880b57cec5SDimitry Andricbool 7890b57cec5SDimitry Andricoperator!=(const _Tp& __x, const complex<_Tp>& __y) 7900b57cec5SDimitry Andric{ 7910b57cec5SDimitry Andric return !(__x == __y); 7920b57cec5SDimitry Andric} 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric// 26.3.7 values: 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, 7970b57cec5SDimitry Andric bool = is_floating_point<_Tp>::value 7980b57cec5SDimitry Andric > 7990b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {}; 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric// Integral Types 8020b57cec5SDimitry Andrictemplate <class _Tp> 8030b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> 8040b57cec5SDimitry Andric{ 8050b57cec5SDimitry Andric typedef double _ValueType; 8060b57cec5SDimitry Andric typedef complex<double> _ComplexType; 8070b57cec5SDimitry Andric}; 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric// Floating point types 8100b57cec5SDimitry Andrictemplate <class _Tp> 8110b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> 8120b57cec5SDimitry Andric{ 8130b57cec5SDimitry Andric typedef _Tp _ValueType; 8140b57cec5SDimitry Andric typedef complex<_Tp> _ComplexType; 8150b57cec5SDimitry Andric}; 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric// real 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andrictemplate<class _Tp> 8200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 8210b57cec5SDimitry Andric_Tp 8220b57cec5SDimitry Andricreal(const complex<_Tp>& __c) 8230b57cec5SDimitry Andric{ 8240b57cec5SDimitry Andric return __c.real(); 8250b57cec5SDimitry Andric} 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andrictemplate <class _Tp> 8280b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 8290b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 8300b57cec5SDimitry Andricreal(_Tp __re) 8310b57cec5SDimitry Andric{ 8320b57cec5SDimitry Andric return __re; 8330b57cec5SDimitry Andric} 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric// imag 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andrictemplate<class _Tp> 8380b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 8390b57cec5SDimitry Andric_Tp 8400b57cec5SDimitry Andricimag(const complex<_Tp>& __c) 8410b57cec5SDimitry Andric{ 8420b57cec5SDimitry Andric return __c.imag(); 8430b57cec5SDimitry Andric} 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andrictemplate <class _Tp> 8460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 8470b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 8480b57cec5SDimitry Andricimag(_Tp) 8490b57cec5SDimitry Andric{ 8500b57cec5SDimitry Andric return 0; 8510b57cec5SDimitry Andric} 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric// abs 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andrictemplate<class _Tp> 8560b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8570b57cec5SDimitry Andric_Tp 8580b57cec5SDimitry Andricabs(const complex<_Tp>& __c) 8590b57cec5SDimitry Andric{ 8600b57cec5SDimitry Andric return hypot(__c.real(), __c.imag()); 8610b57cec5SDimitry Andric} 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric// arg 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andrictemplate<class _Tp> 8660b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8670b57cec5SDimitry Andric_Tp 8680b57cec5SDimitry Andricarg(const complex<_Tp>& __c) 8690b57cec5SDimitry Andric{ 8700b57cec5SDimitry Andric return atan2(__c.imag(), __c.real()); 8710b57cec5SDimitry Andric} 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andrictemplate <class _Tp> 8740b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8750b57cec5SDimitry Andrictypename enable_if< 8760b57cec5SDimitry Andric is_same<_Tp, long double>::value, 8770b57cec5SDimitry Andric long double 8780b57cec5SDimitry Andric>::type 8790b57cec5SDimitry Andricarg(_Tp __re) 8800b57cec5SDimitry Andric{ 8810b57cec5SDimitry Andric return atan2l(0.L, __re); 8820b57cec5SDimitry Andric} 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andrictemplate<class _Tp> 8850b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8860b57cec5SDimitry Andrictypename enable_if 8870b57cec5SDimitry Andric< 8880b57cec5SDimitry Andric is_integral<_Tp>::value || is_same<_Tp, double>::value, 8890b57cec5SDimitry Andric double 8900b57cec5SDimitry Andric>::type 8910b57cec5SDimitry Andricarg(_Tp __re) 8920b57cec5SDimitry Andric{ 8930b57cec5SDimitry Andric return atan2(0., __re); 8940b57cec5SDimitry Andric} 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andrictemplate <class _Tp> 8970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 8980b57cec5SDimitry Andrictypename enable_if< 8990b57cec5SDimitry Andric is_same<_Tp, float>::value, 9000b57cec5SDimitry Andric float 9010b57cec5SDimitry Andric>::type 9020b57cec5SDimitry Andricarg(_Tp __re) 9030b57cec5SDimitry Andric{ 9040b57cec5SDimitry Andric return atan2f(0.F, __re); 9050b57cec5SDimitry Andric} 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric// norm 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andrictemplate<class _Tp> 9100b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9110b57cec5SDimitry Andric_Tp 9120b57cec5SDimitry Andricnorm(const complex<_Tp>& __c) 9130b57cec5SDimitry Andric{ 9140b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__c.real())) 9150b57cec5SDimitry Andric return abs(__c.real()); 9160b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__c.imag())) 9170b57cec5SDimitry Andric return abs(__c.imag()); 9180b57cec5SDimitry Andric return __c.real() * __c.real() + __c.imag() * __c.imag(); 9190b57cec5SDimitry Andric} 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andrictemplate <class _Tp> 9220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9230b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType 9240b57cec5SDimitry Andricnorm(_Tp __re) 9250b57cec5SDimitry Andric{ 9260b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; 9270b57cec5SDimitry Andric return static_cast<_ValueType>(__re) * __re; 9280b57cec5SDimitry Andric} 9290b57cec5SDimitry Andric 9300b57cec5SDimitry Andric// conj 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andrictemplate<class _Tp> 9330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9340b57cec5SDimitry Andriccomplex<_Tp> 9350b57cec5SDimitry Andricconj(const complex<_Tp>& __c) 9360b57cec5SDimitry Andric{ 9370b57cec5SDimitry Andric return complex<_Tp>(__c.real(), -__c.imag()); 9380b57cec5SDimitry Andric} 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andrictemplate <class _Tp> 9410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9420b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType 9430b57cec5SDimitry Andricconj(_Tp __re) 9440b57cec5SDimitry Andric{ 9450b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9460b57cec5SDimitry Andric return _ComplexType(__re); 9470b57cec5SDimitry Andric} 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric// proj 9520b57cec5SDimitry Andric 9530b57cec5SDimitry Andrictemplate<class _Tp> 9540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9550b57cec5SDimitry Andriccomplex<_Tp> 9560b57cec5SDimitry Andricproj(const complex<_Tp>& __c) 9570b57cec5SDimitry Andric{ 9580b57cec5SDimitry Andric std::complex<_Tp> __r = __c; 9590b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag())) 9600b57cec5SDimitry Andric __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); 9610b57cec5SDimitry Andric return __r; 9620b57cec5SDimitry Andric} 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andrictemplate <class _Tp> 9650b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9660b57cec5SDimitry Andrictypename enable_if 9670b57cec5SDimitry Andric< 9680b57cec5SDimitry Andric is_floating_point<_Tp>::value, 9690b57cec5SDimitry Andric typename __libcpp_complex_overload_traits<_Tp>::_ComplexType 9700b57cec5SDimitry Andric>::type 9710b57cec5SDimitry Andricproj(_Tp __re) 9720b57cec5SDimitry Andric{ 9730b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__re)) 9740b57cec5SDimitry Andric __re = abs(__re); 9750b57cec5SDimitry Andric return complex<_Tp>(__re); 9760b57cec5SDimitry Andric} 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andrictemplate <class _Tp> 9790b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 9800b57cec5SDimitry Andrictypename enable_if 9810b57cec5SDimitry Andric< 9820b57cec5SDimitry Andric is_integral<_Tp>::value, 9830b57cec5SDimitry Andric typename __libcpp_complex_overload_traits<_Tp>::_ComplexType 9840b57cec5SDimitry Andric>::type 9850b57cec5SDimitry Andricproj(_Tp __re) 9860b57cec5SDimitry Andric{ 9870b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9880b57cec5SDimitry Andric return _ComplexType(__re); 9890b57cec5SDimitry Andric} 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric// polar 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andrictemplate<class _Tp> 9940b57cec5SDimitry Andriccomplex<_Tp> 9950b57cec5SDimitry Andricpolar(const _Tp& __rho, const _Tp& __theta = _Tp()) 9960b57cec5SDimitry Andric{ 9970b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho)) 9980b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 9990b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__theta)) 10000b57cec5SDimitry Andric { 10010b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__rho)) 10020b57cec5SDimitry Andric return complex<_Tp>(__rho, __theta); 10030b57cec5SDimitry Andric return complex<_Tp>(__theta, __theta); 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__theta)) 10060b57cec5SDimitry Andric { 10070b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__rho)) 10080b57cec5SDimitry Andric return complex<_Tp>(__rho, _Tp(NAN)); 10090b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric _Tp __x = __rho * cos(__theta); 10120b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x)) 10130b57cec5SDimitry Andric __x = 0; 10140b57cec5SDimitry Andric _Tp __y = __rho * sin(__theta); 10150b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__y)) 10160b57cec5SDimitry Andric __y = 0; 10170b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 10180b57cec5SDimitry Andric} 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric// log 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andrictemplate<class _Tp> 10230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 10240b57cec5SDimitry Andriccomplex<_Tp> 10250b57cec5SDimitry Andriclog(const complex<_Tp>& __x) 10260b57cec5SDimitry Andric{ 10270b57cec5SDimitry Andric return complex<_Tp>(log(abs(__x)), arg(__x)); 10280b57cec5SDimitry Andric} 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric// log10 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andrictemplate<class _Tp> 10330b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 10340b57cec5SDimitry Andriccomplex<_Tp> 10350b57cec5SDimitry Andriclog10(const complex<_Tp>& __x) 10360b57cec5SDimitry Andric{ 10370b57cec5SDimitry Andric return log(__x) / log(_Tp(10)); 10380b57cec5SDimitry Andric} 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric// sqrt 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andrictemplate<class _Tp> 10430b57cec5SDimitry Andriccomplex<_Tp> 10440b57cec5SDimitry Andricsqrt(const complex<_Tp>& __x) 10450b57cec5SDimitry Andric{ 10460b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 10470b57cec5SDimitry Andric return complex<_Tp>(_Tp(INFINITY), __x.imag()); 10480b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 10490b57cec5SDimitry Andric { 10500b57cec5SDimitry Andric if (__x.real() > _Tp(0)) 10510b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); 10520b57cec5SDimitry Andric return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); 10530b57cec5SDimitry Andric } 10540b57cec5SDimitry Andric return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); 10550b57cec5SDimitry Andric} 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric// exp 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andrictemplate<class _Tp> 10600b57cec5SDimitry Andriccomplex<_Tp> 10610b57cec5SDimitry Andricexp(const complex<_Tp>& __x) 10620b57cec5SDimitry Andric{ 10630b57cec5SDimitry Andric _Tp __i = __x.imag(); 10640b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 10650b57cec5SDimitry Andric { 10660b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 10670b57cec5SDimitry Andric { 10680b57cec5SDimitry Andric if (!__libcpp_isfinite_or_builtin(__i)) 10690b57cec5SDimitry Andric __i = _Tp(1); 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i)) 10720b57cec5SDimitry Andric { 10730b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__i)) 10740b57cec5SDimitry Andric __i = _Tp(NAN); 10750b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __i); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric } 10780b57cec5SDimitry Andric else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) 10790b57cec5SDimitry Andric return __x; 10800b57cec5SDimitry Andric _Tp __e = exp(__x.real()); 10810b57cec5SDimitry Andric return complex<_Tp>(__e * cos(__i), __e * sin(__i)); 10820b57cec5SDimitry Andric} 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric// pow 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andrictemplate<class _Tp> 10870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 10880b57cec5SDimitry Andriccomplex<_Tp> 10890b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Tp>& __y) 10900b57cec5SDimitry Andric{ 10910b57cec5SDimitry Andric return exp(__y * log(__x)); 10920b57cec5SDimitry Andric} 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andrictemplate<class _Tp, class _Up> 10950b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 10960b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type> 10970b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) 10980b57cec5SDimitry Andric{ 10990b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11000b57cec5SDimitry Andric return _VSTD::pow(result_type(__x), result_type(__y)); 11010b57cec5SDimitry Andric} 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andrictemplate<class _Tp, class _Up> 11040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 11050b57cec5SDimitry Andrictypename enable_if 11060b57cec5SDimitry Andric< 11070b57cec5SDimitry Andric is_arithmetic<_Up>::value, 11080b57cec5SDimitry Andric complex<typename __promote<_Tp, _Up>::type> 11090b57cec5SDimitry Andric>::type 11100b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const _Up& __y) 11110b57cec5SDimitry Andric{ 11120b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11130b57cec5SDimitry Andric return _VSTD::pow(result_type(__x), result_type(__y)); 11140b57cec5SDimitry Andric} 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andrictemplate<class _Tp, class _Up> 11170b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 11180b57cec5SDimitry Andrictypename enable_if 11190b57cec5SDimitry Andric< 11200b57cec5SDimitry Andric is_arithmetic<_Tp>::value, 11210b57cec5SDimitry Andric complex<typename __promote<_Tp, _Up>::type> 11220b57cec5SDimitry Andric>::type 11230b57cec5SDimitry Andricpow(const _Tp& __x, const complex<_Up>& __y) 11240b57cec5SDimitry Andric{ 11250b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11260b57cec5SDimitry Andric return _VSTD::pow(result_type(__x), result_type(__y)); 11270b57cec5SDimitry Andric} 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric// __sqr, computes pow(x, 2) 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andrictemplate<class _Tp> 11320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 11330b57cec5SDimitry Andriccomplex<_Tp> 11340b57cec5SDimitry Andric__sqr(const complex<_Tp>& __x) 11350b57cec5SDimitry Andric{ 11360b57cec5SDimitry Andric return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), 11370b57cec5SDimitry Andric _Tp(2) * __x.real() * __x.imag()); 11380b57cec5SDimitry Andric} 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric// asinh 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andrictemplate<class _Tp> 11430b57cec5SDimitry Andriccomplex<_Tp> 11440b57cec5SDimitry Andricasinh(const complex<_Tp>& __x) 11450b57cec5SDimitry Andric{ 11460b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 11470b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 11480b57cec5SDimitry Andric { 11490b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.imag())) 11500b57cec5SDimitry Andric return __x; 11510b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11520b57cec5SDimitry Andric return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); 11530b57cec5SDimitry Andric return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.real())) 11560b57cec5SDimitry Andric { 11570b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11580b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 11590b57cec5SDimitry Andric if (__x.imag() == 0) 11600b57cec5SDimitry Andric return __x; 11610b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11620b57cec5SDimitry Andric } 11630b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11640b57cec5SDimitry Andric return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); 11650b57cec5SDimitry Andric complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1))); 11660b57cec5SDimitry Andric return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); 11670b57cec5SDimitry Andric} 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric// acosh 11700b57cec5SDimitry Andric 11710b57cec5SDimitry Andrictemplate<class _Tp> 11720b57cec5SDimitry Andriccomplex<_Tp> 11730b57cec5SDimitry Andricacosh(const complex<_Tp>& __x) 11740b57cec5SDimitry Andric{ 11750b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 11760b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 11770b57cec5SDimitry Andric { 11780b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.imag())) 11790b57cec5SDimitry Andric return complex<_Tp>(abs(__x.real()), __x.imag()); 11800b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11810b57cec5SDimitry Andric { 11820b57cec5SDimitry Andric if (__x.real() > 0) 11830b57cec5SDimitry Andric return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); 11840b57cec5SDimitry Andric else 11850b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag())); 11860b57cec5SDimitry Andric } 11870b57cec5SDimitry Andric if (__x.real() < 0) 11880b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); 11890b57cec5SDimitry Andric return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); 11900b57cec5SDimitry Andric } 11910b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.real())) 11920b57cec5SDimitry Andric { 11930b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11940b57cec5SDimitry Andric return complex<_Tp>(abs(__x.imag()), __x.real()); 11950b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 11980b57cec5SDimitry Andric return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); 11990b57cec5SDimitry Andric complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); 12000b57cec5SDimitry Andric return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); 12010b57cec5SDimitry Andric} 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric// atanh 12040b57cec5SDimitry Andric 12050b57cec5SDimitry Andrictemplate<class _Tp> 12060b57cec5SDimitry Andriccomplex<_Tp> 12070b57cec5SDimitry Andricatanh(const complex<_Tp>& __x) 12080b57cec5SDimitry Andric{ 12090b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 12100b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 12110b57cec5SDimitry Andric { 12120b57cec5SDimitry Andric return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); 12130b57cec5SDimitry Andric } 12140b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.imag())) 12150b57cec5SDimitry Andric { 12160b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0) 12170b57cec5SDimitry Andric return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); 12180b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.imag()); 12190b57cec5SDimitry Andric } 12200b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.real())) 12210b57cec5SDimitry Andric { 12220b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12230b57cec5SDimitry Andric } 12240b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 12250b57cec5SDimitry Andric { 12260b57cec5SDimitry Andric return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); 12270b57cec5SDimitry Andric } 12280b57cec5SDimitry Andric if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) 12290b57cec5SDimitry Andric { 12300b57cec5SDimitry Andric return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag())); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); 12330b57cec5SDimitry Andric return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); 12340b57cec5SDimitry Andric} 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric// sinh 12370b57cec5SDimitry Andric 12380b57cec5SDimitry Andrictemplate<class _Tp> 12390b57cec5SDimitry Andriccomplex<_Tp> 12400b57cec5SDimitry Andricsinh(const complex<_Tp>& __x) 12410b57cec5SDimitry Andric{ 12420b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) 12430b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 12440b57cec5SDimitry Andric if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) 12450b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 12460b57cec5SDimitry Andric if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) 12470b57cec5SDimitry Andric return __x; 12480b57cec5SDimitry Andric return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); 12490b57cec5SDimitry Andric} 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric// cosh 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andrictemplate<class _Tp> 12540b57cec5SDimitry Andriccomplex<_Tp> 12550b57cec5SDimitry Andriccosh(const complex<_Tp>& __x) 12560b57cec5SDimitry Andric{ 12570b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag())) 12580b57cec5SDimitry Andric return complex<_Tp>(abs(__x.real()), _Tp(NAN)); 12590b57cec5SDimitry Andric if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag())) 12600b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), __x.real()); 12610b57cec5SDimitry Andric if (__x.real() == 0 && __x.imag() == 0) 12620b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), __x.imag()); 12630b57cec5SDimitry Andric if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real())) 12640b57cec5SDimitry Andric return complex<_Tp>(abs(__x.real()), __x.imag()); 12650b57cec5SDimitry Andric return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); 12660b57cec5SDimitry Andric} 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric// tanh 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andrictemplate<class _Tp> 12710b57cec5SDimitry Andriccomplex<_Tp> 12720b57cec5SDimitry Andrictanh(const complex<_Tp>& __x) 12730b57cec5SDimitry Andric{ 12740b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 12750b57cec5SDimitry Andric { 12760b57cec5SDimitry Andric if (!__libcpp_isfinite_or_builtin(__x.imag())) 12770b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), _Tp(0)); 12780b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); 12790b57cec5SDimitry Andric } 12800b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0) 12810b57cec5SDimitry Andric return __x; 12820b57cec5SDimitry Andric _Tp __2r(_Tp(2) * __x.real()); 12830b57cec5SDimitry Andric _Tp __2i(_Tp(2) * __x.imag()); 12840b57cec5SDimitry Andric _Tp __d(cosh(__2r) + cos(__2i)); 12850b57cec5SDimitry Andric _Tp __2rsh(sinh(__2r)); 12860b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d)) 12870b57cec5SDimitry Andric return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), 12880b57cec5SDimitry Andric __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); 12890b57cec5SDimitry Andric return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); 12900b57cec5SDimitry Andric} 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric// asin 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andrictemplate<class _Tp> 12950b57cec5SDimitry Andriccomplex<_Tp> 12960b57cec5SDimitry Andricasin(const complex<_Tp>& __x) 12970b57cec5SDimitry Andric{ 12980b57cec5SDimitry Andric complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real())); 12990b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13000b57cec5SDimitry Andric} 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric// acos 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andrictemplate<class _Tp> 13050b57cec5SDimitry Andriccomplex<_Tp> 13060b57cec5SDimitry Andricacos(const complex<_Tp>& __x) 13070b57cec5SDimitry Andric{ 13080b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 13090b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.real())) 13100b57cec5SDimitry Andric { 13110b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.imag())) 13120b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 13130b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 13140b57cec5SDimitry Andric { 13150b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 13160b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); 13170b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); 13180b57cec5SDimitry Andric } 13190b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 13200b57cec5SDimitry Andric return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); 13210b57cec5SDimitry Andric return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric if (__libcpp_isnan_or_builtin(__x.real())) 13240b57cec5SDimitry Andric { 13250b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 13260b57cec5SDimitry Andric return complex<_Tp>(__x.real(), -__x.imag()); 13270b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric if (__libcpp_isinf_or_builtin(__x.imag())) 13300b57cec5SDimitry Andric return complex<_Tp>(__pi/_Tp(2), -__x.imag()); 13310b57cec5SDimitry Andric if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) 13320b57cec5SDimitry Andric return complex<_Tp>(__pi/_Tp(2), -__x.imag()); 13330b57cec5SDimitry Andric complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1))); 13340b57cec5SDimitry Andric if (signbit(__x.imag())) 13350b57cec5SDimitry Andric return complex<_Tp>(abs(__z.imag()), abs(__z.real())); 13360b57cec5SDimitry Andric return complex<_Tp>(abs(__z.imag()), -abs(__z.real())); 13370b57cec5SDimitry Andric} 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric// atan 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andrictemplate<class _Tp> 13420b57cec5SDimitry Andriccomplex<_Tp> 13430b57cec5SDimitry Andricatan(const complex<_Tp>& __x) 13440b57cec5SDimitry Andric{ 13450b57cec5SDimitry Andric complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real())); 13460b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13470b57cec5SDimitry Andric} 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andric// sin 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andrictemplate<class _Tp> 13520b57cec5SDimitry Andriccomplex<_Tp> 13530b57cec5SDimitry Andricsin(const complex<_Tp>& __x) 13540b57cec5SDimitry Andric{ 13550b57cec5SDimitry Andric complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real())); 13560b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13570b57cec5SDimitry Andric} 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric// cos 13600b57cec5SDimitry Andric 13610b57cec5SDimitry Andrictemplate<class _Tp> 13620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 13630b57cec5SDimitry Andriccomplex<_Tp> 13640b57cec5SDimitry Andriccos(const complex<_Tp>& __x) 13650b57cec5SDimitry Andric{ 13660b57cec5SDimitry Andric return cosh(complex<_Tp>(-__x.imag(), __x.real())); 13670b57cec5SDimitry Andric} 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric// tan 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andrictemplate<class _Tp> 13720b57cec5SDimitry Andriccomplex<_Tp> 13730b57cec5SDimitry Andrictan(const complex<_Tp>& __x) 13740b57cec5SDimitry Andric{ 13750b57cec5SDimitry Andric complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real())); 13760b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13770b57cec5SDimitry Andric} 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits> 13800b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>& 13810b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 13820b57cec5SDimitry Andric{ 13830b57cec5SDimitry Andric if (__is.good()) 13840b57cec5SDimitry Andric { 13850b57cec5SDimitry Andric ws(__is); 13860b57cec5SDimitry Andric if (__is.peek() == _CharT('(')) 13870b57cec5SDimitry Andric { 13880b57cec5SDimitry Andric __is.get(); 13890b57cec5SDimitry Andric _Tp __r; 13900b57cec5SDimitry Andric __is >> __r; 13910b57cec5SDimitry Andric if (!__is.fail()) 13920b57cec5SDimitry Andric { 13930b57cec5SDimitry Andric ws(__is); 13940b57cec5SDimitry Andric _CharT __c = __is.peek(); 13950b57cec5SDimitry Andric if (__c == _CharT(',')) 13960b57cec5SDimitry Andric { 13970b57cec5SDimitry Andric __is.get(); 13980b57cec5SDimitry Andric _Tp __i; 13990b57cec5SDimitry Andric __is >> __i; 14000b57cec5SDimitry Andric if (!__is.fail()) 14010b57cec5SDimitry Andric { 14020b57cec5SDimitry Andric ws(__is); 14030b57cec5SDimitry Andric __c = __is.peek(); 14040b57cec5SDimitry Andric if (__c == _CharT(')')) 14050b57cec5SDimitry Andric { 14060b57cec5SDimitry Andric __is.get(); 14070b57cec5SDimitry Andric __x = complex<_Tp>(__r, __i); 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric else 1410*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric else 1413*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric else if (__c == _CharT(')')) 14160b57cec5SDimitry Andric { 14170b57cec5SDimitry Andric __is.get(); 14180b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 14190b57cec5SDimitry Andric } 14200b57cec5SDimitry Andric else 1421*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14220b57cec5SDimitry Andric } 14230b57cec5SDimitry Andric else 1424*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric else 14270b57cec5SDimitry Andric { 14280b57cec5SDimitry Andric _Tp __r; 14290b57cec5SDimitry Andric __is >> __r; 14300b57cec5SDimitry Andric if (!__is.fail()) 14310b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 14320b57cec5SDimitry Andric else 1433*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14340b57cec5SDimitry Andric } 14350b57cec5SDimitry Andric } 14360b57cec5SDimitry Andric else 1437*5ffd83dbSDimitry Andric __is.setstate(__is.failbit); 14380b57cec5SDimitry Andric return __is; 14390b57cec5SDimitry Andric} 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits> 14420b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>& 14430b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 14440b57cec5SDimitry Andric{ 14450b57cec5SDimitry Andric basic_ostringstream<_CharT, _Traits> __s; 14460b57cec5SDimitry Andric __s.flags(__os.flags()); 14470b57cec5SDimitry Andric __s.imbue(__os.getloc()); 14480b57cec5SDimitry Andric __s.precision(__os.precision()); 14490b57cec5SDimitry Andric __s << '(' << __x.real() << ',' << __x.imag() << ')'; 14500b57cec5SDimitry Andric return __os << __s.str(); 14510b57cec5SDimitry Andric} 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 14540b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals] 14550b57cec5SDimitry Andricinline namespace literals 14560b57cec5SDimitry Andric{ 14570b57cec5SDimitry Andric inline namespace complex_literals 14580b57cec5SDimitry Andric { 14590b57cec5SDimitry Andric constexpr complex<long double> operator""il(long double __im) 14600b57cec5SDimitry Andric { 14610b57cec5SDimitry Andric return { 0.0l, __im }; 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric constexpr complex<long double> operator""il(unsigned long long __im) 14650b57cec5SDimitry Andric { 14660b57cec5SDimitry Andric return { 0.0l, static_cast<long double>(__im) }; 14670b57cec5SDimitry Andric } 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric 14700b57cec5SDimitry Andric constexpr complex<double> operator""i(long double __im) 14710b57cec5SDimitry Andric { 14720b57cec5SDimitry Andric return { 0.0, static_cast<double>(__im) }; 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric constexpr complex<double> operator""i(unsigned long long __im) 14760b57cec5SDimitry Andric { 14770b57cec5SDimitry Andric return { 0.0, static_cast<double>(__im) }; 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric constexpr complex<float> operator""if(long double __im) 14820b57cec5SDimitry Andric { 14830b57cec5SDimitry Andric return { 0.0f, static_cast<float>(__im) }; 14840b57cec5SDimitry Andric } 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric constexpr complex<float> operator""if(unsigned long long __im) 14870b57cec5SDimitry Andric { 14880b57cec5SDimitry Andric return { 0.0f, static_cast<float>(__im) }; 14890b57cec5SDimitry Andric } 14900b57cec5SDimitry Andric } 14910b57cec5SDimitry Andric} 14920b57cec5SDimitry Andric#endif 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX 1497