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 2300fca6ea1SDimitry Andric // [complex.tuple], tuple interface 2310fca6ea1SDimitry Andric template<class T> struct tuple_size; // Since C++26 2320fca6ea1SDimitry Andric template<size_t I, class T> struct tuple_element; // Since C++26 2330fca6ea1SDimitry Andric template<class T> struct tuple_size<complex<T>>; // Since C++26 2340fca6ea1SDimitry Andric template<size_t I, class T> struct tuple_element<I, complex<T>>; // Since C++26 2350fca6ea1SDimitry Andric template<size_t I, class T> 2360fca6ea1SDimitry Andric constexpr T& get(complex<T>&) noexcept; // Since C++26 2370fca6ea1SDimitry Andric template<size_t I, class T> 2380fca6ea1SDimitry Andric constexpr T&& get(complex<T>&&) noexcept; // Since C++26 2390fca6ea1SDimitry Andric template<size_t I, class T> 2400fca6ea1SDimitry Andric constexpr const T& get(const complex<T>&) noexcept; // Since C++26 2410fca6ea1SDimitry Andric template<size_t I, class T> 2420fca6ea1SDimitry Andric constexpr const T&& get(const complex<T>&&) noexcept; // Since C++26 2430fca6ea1SDimitry Andric 2440fca6ea1SDimitry Andric // [complex.literals], complex literals 2450fca6ea1SDimitry Andric inline namespace literals { 2460fca6ea1SDimitry Andric inline namespace complex_literals { 2470fca6ea1SDimitry Andric constexpr complex<long double> operator""il(long double); // Since C++14 2480fca6ea1SDimitry Andric constexpr complex<long double> operator""il(unsigned long long); // Since C++14 2490fca6ea1SDimitry Andric constexpr complex<double> operator""i(long double); // Since C++14 2500fca6ea1SDimitry Andric constexpr complex<double> operator""i(unsigned long long); // Since C++14 2510fca6ea1SDimitry Andric constexpr complex<float> operator""if(long double); // Since C++14 2520fca6ea1SDimitry Andric constexpr complex<float> operator""if(unsigned long long); // Since C++14 2530fca6ea1SDimitry Andric } 2540fca6ea1SDimitry Andric } 2550b57cec5SDimitry Andric} // std 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric*/ 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric#include <__config> 2600fca6ea1SDimitry Andric#include <__fwd/complex.h> 2610fca6ea1SDimitry Andric#include <__fwd/tuple.h> 2620fca6ea1SDimitry Andric#include <__tuple/tuple_element.h> 2630fca6ea1SDimitry Andric#include <__tuple/tuple_size.h> 2640fca6ea1SDimitry Andric#include <__type_traits/conditional.h> 2650fca6ea1SDimitry Andric#include <__utility/move.h> 2660b57cec5SDimitry Andric#include <cmath> 2670b57cec5SDimitry Andric#include <version> 2680b57cec5SDimitry Andric 269e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 270e8d8bef9SDimitry Andric# include <sstream> // for std::basic_ostringstream 271e8d8bef9SDimitry Andric#endif 272e8d8bef9SDimitry Andric 2730b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2740b57cec5SDimitry Andric# pragma GCC system_header 2750b57cec5SDimitry Andric#endif 2760b57cec5SDimitry Andric 2770fca6ea1SDimitry Andric_LIBCPP_PUSH_MACROS 2780fca6ea1SDimitry Andric#include <__undef_macros> 2790fca6ea1SDimitry Andric 2800b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2810b57cec5SDimitry Andric 282cb14a3feSDimitry Andrictemplate <class _Tp> 283cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex; 2840b57cec5SDimitry Andric 2850fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 286cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 287cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 2880fca6ea1SDimitry Andric 2890fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0> 2900fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 2910fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 2920fca6ea1SDimitry Andric 2930fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 2940fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 2950fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 2960fca6ea1SDimitry Andric 2970fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0> 298cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 299cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 300cb14a3feSDimitry Andric 301cb14a3feSDimitry Andrictemplate <class _Tp> 302cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex { 3030b57cec5SDimitry Andricpublic: 3040b57cec5SDimitry Andric typedef _Tp value_type; 305cb14a3feSDimitry Andric 3060b57cec5SDimitry Andricprivate: 3070b57cec5SDimitry Andric value_type __re_; 3080b57cec5SDimitry Andric value_type __im_; 309cb14a3feSDimitry Andric 3100b57cec5SDimitry Andricpublic: 3115f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 3120b57cec5SDimitry Andric complex(const value_type& __re = value_type(), const value_type& __im = value_type()) 3130b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 314cb14a3feSDimitry Andric template <class _Xp> 315cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 complex(const complex<_Xp>& __c) 3160b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 3170b57cec5SDimitry Andric 3185f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const { return __re_; } 3195f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const { return __im_; } 3200b57cec5SDimitry Andric 3215f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 3225f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 3230b57cec5SDimitry Andric 324cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const value_type& __re) { 325cb14a3feSDimitry Andric __re_ = __re; 326cb14a3feSDimitry Andric __im_ = value_type(); 327cb14a3feSDimitry Andric return *this; 328cb14a3feSDimitry Andric } 329cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) { 330cb14a3feSDimitry Andric __re_ += __re; 331cb14a3feSDimitry Andric return *this; 332cb14a3feSDimitry Andric } 333cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) { 334cb14a3feSDimitry Andric __re_ -= __re; 335cb14a3feSDimitry Andric return *this; 336cb14a3feSDimitry Andric } 337cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) { 338cb14a3feSDimitry Andric __re_ *= __re; 339cb14a3feSDimitry Andric __im_ *= __re; 340cb14a3feSDimitry Andric return *this; 341cb14a3feSDimitry Andric } 342cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) { 343cb14a3feSDimitry Andric __re_ /= __re; 344cb14a3feSDimitry Andric __im_ /= __re; 345cb14a3feSDimitry Andric return *this; 346cb14a3feSDimitry Andric } 3470b57cec5SDimitry Andric 348cb14a3feSDimitry Andric template <class _Xp> 349cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 3500b57cec5SDimitry Andric __re_ = __c.real(); 3510b57cec5SDimitry Andric __im_ = __c.imag(); 3520b57cec5SDimitry Andric return *this; 3530b57cec5SDimitry Andric } 354cb14a3feSDimitry Andric template <class _Xp> 355cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 3560b57cec5SDimitry Andric __re_ += __c.real(); 3570b57cec5SDimitry Andric __im_ += __c.imag(); 3580b57cec5SDimitry Andric return *this; 3590b57cec5SDimitry Andric } 360cb14a3feSDimitry Andric template <class _Xp> 361cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 3620b57cec5SDimitry Andric __re_ -= __c.real(); 3630b57cec5SDimitry Andric __im_ -= __c.imag(); 3640b57cec5SDimitry Andric return *this; 3650b57cec5SDimitry Andric } 366cb14a3feSDimitry Andric template <class _Xp> 367cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 3680b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 3690b57cec5SDimitry Andric return *this; 3700b57cec5SDimitry Andric } 371cb14a3feSDimitry Andric template <class _Xp> 372cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 3730b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 3740b57cec5SDimitry Andric return *this; 3750b57cec5SDimitry Andric } 3760fca6ea1SDimitry Andric 3770fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 3780fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 3790fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 3800fca6ea1SDimitry Andric 3810fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 3820fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 3830fca6ea1SDimitry Andric 3840fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 3850fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 3860fca6ea1SDimitry Andric 3870fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 3880fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 3890fca6ea1SDimitry Andric#endif 3900b57cec5SDimitry Andric}; 3910b57cec5SDimitry Andric 392cb14a3feSDimitry Andrictemplate <> 393cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double>; 394cb14a3feSDimitry Andrictemplate <> 395cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double>; 3960b57cec5SDimitry Andric 3970fca6ea1SDimitry Andricstruct __from_builtin_tag {}; 3980fca6ea1SDimitry Andric 3990fca6ea1SDimitry Andrictemplate <class _Tp> 4000fca6ea1SDimitry Andricusing __complex_t = 4010fca6ea1SDimitry Andric __conditional_t<is_same<_Tp, float>::value, 4020fca6ea1SDimitry Andric _Complex float, 4030fca6ea1SDimitry Andric __conditional_t<is_same<_Tp, double>::value, _Complex double, _Complex long double> >; 4040fca6ea1SDimitry Andric 4050fca6ea1SDimitry Andrictemplate <class _Tp> 4060fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __complex_t<_Tp> __make_complex(_Tp __re, _Tp __im) { 4070fca6ea1SDimitry Andric#if __has_builtin(__builtin_complex) 4080fca6ea1SDimitry Andric return __builtin_complex(__re, __im); 4090fca6ea1SDimitry Andric#else 4100fca6ea1SDimitry Andric return __complex_t<_Tp>{__re, __im}; 4110fca6ea1SDimitry Andric#endif 4120fca6ea1SDimitry Andric} 4130fca6ea1SDimitry Andric 4140b57cec5SDimitry Andrictemplate <> 415cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float> { 4160b57cec5SDimitry Andric float __re_; 4170b57cec5SDimitry Andric float __im_; 418cb14a3feSDimitry Andric 4190b57cec5SDimitry Andricpublic: 4200b57cec5SDimitry Andric typedef float value_type; 4210b57cec5SDimitry Andric 422cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {} 4230fca6ea1SDimitry Andric 424*62987288SDimitry Andric template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0> 425*62987288SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex float __v) 4260fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 4270fca6ea1SDimitry Andric 428cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 429cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 4300b57cec5SDimitry Andric 4315f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; } 4325f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; } 4330b57cec5SDimitry Andric 4345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 4355f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 4360b57cec5SDimitry Andric 4370fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex float __builtin() const { return std::__make_complex(__re_, __im_); } 4380fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex float __f) { 4390fca6ea1SDimitry Andric __re_ = __real__ __f; 4400fca6ea1SDimitry Andric __im_ = __imag__ __f; 4410fca6ea1SDimitry Andric } 4420fca6ea1SDimitry Andric 443cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(float __re) { 444cb14a3feSDimitry Andric __re_ = __re; 445cb14a3feSDimitry Andric __im_ = value_type(); 446cb14a3feSDimitry Andric return *this; 447cb14a3feSDimitry Andric } 448cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) { 449cb14a3feSDimitry Andric __re_ += __re; 450cb14a3feSDimitry Andric return *this; 451cb14a3feSDimitry Andric } 452cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) { 453cb14a3feSDimitry Andric __re_ -= __re; 454cb14a3feSDimitry Andric return *this; 455cb14a3feSDimitry Andric } 456cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) { 457cb14a3feSDimitry Andric __re_ *= __re; 458cb14a3feSDimitry Andric __im_ *= __re; 459cb14a3feSDimitry Andric return *this; 460cb14a3feSDimitry Andric } 461cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) { 462cb14a3feSDimitry Andric __re_ /= __re; 463cb14a3feSDimitry Andric __im_ /= __re; 464cb14a3feSDimitry Andric return *this; 465cb14a3feSDimitry Andric } 4660b57cec5SDimitry Andric 467cb14a3feSDimitry Andric template <class _Xp> 468cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 4690b57cec5SDimitry Andric __re_ = __c.real(); 4700b57cec5SDimitry Andric __im_ = __c.imag(); 4710b57cec5SDimitry Andric return *this; 4720b57cec5SDimitry Andric } 473cb14a3feSDimitry Andric template <class _Xp> 474cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 4750b57cec5SDimitry Andric __re_ += __c.real(); 4760b57cec5SDimitry Andric __im_ += __c.imag(); 4770b57cec5SDimitry Andric return *this; 4780b57cec5SDimitry Andric } 479cb14a3feSDimitry Andric template <class _Xp> 480cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 4810b57cec5SDimitry Andric __re_ -= __c.real(); 4820b57cec5SDimitry Andric __im_ -= __c.imag(); 4830b57cec5SDimitry Andric return *this; 4840b57cec5SDimitry Andric } 485cb14a3feSDimitry Andric template <class _Xp> 486cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 4870b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4880b57cec5SDimitry Andric return *this; 4890b57cec5SDimitry Andric } 490cb14a3feSDimitry Andric template <class _Xp> 491cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 4920b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4930b57cec5SDimitry Andric return *this; 4940b57cec5SDimitry Andric } 4950fca6ea1SDimitry Andric 4960fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 4970fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 4980fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 4990fca6ea1SDimitry Andric 5000fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 5010fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 5020fca6ea1SDimitry Andric 5030fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 5040fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 5050fca6ea1SDimitry Andric 5060fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 5070fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 5080fca6ea1SDimitry Andric#endif 5090b57cec5SDimitry Andric}; 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andrictemplate <> 512cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> { 5130b57cec5SDimitry Andric double __re_; 5140b57cec5SDimitry Andric double __im_; 515cb14a3feSDimitry Andric 5160b57cec5SDimitry Andricpublic: 5170b57cec5SDimitry Andric typedef double value_type; 5180b57cec5SDimitry Andric 519cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {} 5200fca6ea1SDimitry Andric 521*62987288SDimitry Andric template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0> 522*62987288SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex double __v) 5230fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 5240fca6ea1SDimitry Andric 525cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 526cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 5270b57cec5SDimitry Andric 5285f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; } 5295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; } 5300b57cec5SDimitry Andric 5315f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 5325f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 5330b57cec5SDimitry Andric 5340fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex double __builtin() const { 5350fca6ea1SDimitry Andric return std::__make_complex(__re_, __im_); 5360fca6ea1SDimitry Andric } 5370fca6ea1SDimitry Andric 5380fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex double __f) { 5390fca6ea1SDimitry Andric __re_ = __real__ __f; 5400fca6ea1SDimitry Andric __im_ = __imag__ __f; 5410fca6ea1SDimitry Andric } 5420fca6ea1SDimitry Andric 543cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(double __re) { 544cb14a3feSDimitry Andric __re_ = __re; 545cb14a3feSDimitry Andric __im_ = value_type(); 546cb14a3feSDimitry Andric return *this; 547cb14a3feSDimitry Andric } 548cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) { 549cb14a3feSDimitry Andric __re_ += __re; 550cb14a3feSDimitry Andric return *this; 551cb14a3feSDimitry Andric } 552cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) { 553cb14a3feSDimitry Andric __re_ -= __re; 554cb14a3feSDimitry Andric return *this; 555cb14a3feSDimitry Andric } 556cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) { 557cb14a3feSDimitry Andric __re_ *= __re; 558cb14a3feSDimitry Andric __im_ *= __re; 559cb14a3feSDimitry Andric return *this; 560cb14a3feSDimitry Andric } 561cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) { 562cb14a3feSDimitry Andric __re_ /= __re; 563cb14a3feSDimitry Andric __im_ /= __re; 564cb14a3feSDimitry Andric return *this; 565cb14a3feSDimitry Andric } 5660b57cec5SDimitry Andric 567cb14a3feSDimitry Andric template <class _Xp> 568cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 5690b57cec5SDimitry Andric __re_ = __c.real(); 5700b57cec5SDimitry Andric __im_ = __c.imag(); 5710b57cec5SDimitry Andric return *this; 5720b57cec5SDimitry Andric } 573cb14a3feSDimitry Andric template <class _Xp> 574cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 5750b57cec5SDimitry Andric __re_ += __c.real(); 5760b57cec5SDimitry Andric __im_ += __c.imag(); 5770b57cec5SDimitry Andric return *this; 5780b57cec5SDimitry Andric } 579cb14a3feSDimitry Andric template <class _Xp> 580cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 5810b57cec5SDimitry Andric __re_ -= __c.real(); 5820b57cec5SDimitry Andric __im_ -= __c.imag(); 5830b57cec5SDimitry Andric return *this; 5840b57cec5SDimitry Andric } 585cb14a3feSDimitry Andric template <class _Xp> 586cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 5870b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 5880b57cec5SDimitry Andric return *this; 5890b57cec5SDimitry Andric } 590cb14a3feSDimitry Andric template <class _Xp> 591cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 5920b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 5930b57cec5SDimitry Andric return *this; 5940b57cec5SDimitry Andric } 5950fca6ea1SDimitry Andric 5960fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 5970fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 5980fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 5990fca6ea1SDimitry Andric 6000fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 6010fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 6020fca6ea1SDimitry Andric 6030fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 6040fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 6050fca6ea1SDimitry Andric 6060fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 6070fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 6080fca6ea1SDimitry Andric#endif 6090b57cec5SDimitry Andric}; 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andrictemplate <> 612cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> { 6130b57cec5SDimitry Andric long double __re_; 6140b57cec5SDimitry Andric long double __im_; 615cb14a3feSDimitry Andric 6160b57cec5SDimitry Andricpublic: 6170b57cec5SDimitry Andric typedef long double value_type; 6180b57cec5SDimitry Andric 6195f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) 6200b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 6210fca6ea1SDimitry Andric 622*62987288SDimitry Andric template <class _Tag, __enable_if_t<_IsSame<_Tag, __from_builtin_tag>::value, int> = 0> 623*62987288SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit complex(_Tag, _Complex long double __v) 6240fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 6250fca6ea1SDimitry Andric 626cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 627cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 6280b57cec5SDimitry Andric 6295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; } 6305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; } 6310b57cec5SDimitry Andric 6325f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 6335f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 6340b57cec5SDimitry Andric 6350fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex long double __builtin() const { 6360fca6ea1SDimitry Andric return std::__make_complex(__re_, __im_); 6370fca6ea1SDimitry Andric } 6380fca6ea1SDimitry Andric 6390fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex long double __f) { 6400fca6ea1SDimitry Andric __re_ = __real__ __f; 6410fca6ea1SDimitry Andric __im_ = __imag__ __f; 6420fca6ea1SDimitry Andric } 6430fca6ea1SDimitry Andric 644cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(long double __re) { 645cb14a3feSDimitry Andric __re_ = __re; 646cb14a3feSDimitry Andric __im_ = value_type(); 647cb14a3feSDimitry Andric return *this; 648cb14a3feSDimitry Andric } 649cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) { 650cb14a3feSDimitry Andric __re_ += __re; 651cb14a3feSDimitry Andric return *this; 652cb14a3feSDimitry Andric } 653cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) { 654cb14a3feSDimitry Andric __re_ -= __re; 655cb14a3feSDimitry Andric return *this; 656cb14a3feSDimitry Andric } 657cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) { 658cb14a3feSDimitry Andric __re_ *= __re; 659cb14a3feSDimitry Andric __im_ *= __re; 660cb14a3feSDimitry Andric return *this; 661cb14a3feSDimitry Andric } 662cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) { 663cb14a3feSDimitry Andric __re_ /= __re; 664cb14a3feSDimitry Andric __im_ /= __re; 665cb14a3feSDimitry Andric return *this; 666cb14a3feSDimitry Andric } 6670b57cec5SDimitry Andric 668cb14a3feSDimitry Andric template <class _Xp> 669cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 6700b57cec5SDimitry Andric __re_ = __c.real(); 6710b57cec5SDimitry Andric __im_ = __c.imag(); 6720b57cec5SDimitry Andric return *this; 6730b57cec5SDimitry Andric } 674cb14a3feSDimitry Andric template <class _Xp> 675cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 6760b57cec5SDimitry Andric __re_ += __c.real(); 6770b57cec5SDimitry Andric __im_ += __c.imag(); 6780b57cec5SDimitry Andric return *this; 6790b57cec5SDimitry Andric } 680cb14a3feSDimitry Andric template <class _Xp> 681cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 6820b57cec5SDimitry Andric __re_ -= __c.real(); 6830b57cec5SDimitry Andric __im_ -= __c.imag(); 6840b57cec5SDimitry Andric return *this; 6850b57cec5SDimitry Andric } 686cb14a3feSDimitry Andric template <class _Xp> 687cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 6880b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 6890b57cec5SDimitry Andric return *this; 6900b57cec5SDimitry Andric } 691cb14a3feSDimitry Andric template <class _Xp> 692cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 6930b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 6940b57cec5SDimitry Andric return *this; 6950b57cec5SDimitry Andric } 6960fca6ea1SDimitry Andric 6970fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 6980fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 6990fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 7000fca6ea1SDimitry Andric 7010fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 7020fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 7030fca6ea1SDimitry Andric 7040fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 7050fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 7060fca6ea1SDimitry Andric 7070fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 7080fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 7090fca6ea1SDimitry Andric#endif 7100b57cec5SDimitry Andric}; 7110b57cec5SDimitry Andric 712cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 713cb14a3feSDimitry Andric 714cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c) 7150b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7160b57cec5SDimitry Andric 717cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 718cb14a3feSDimitry Andric 719cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c) 7200b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7210b57cec5SDimitry Andric 722cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c) 7230b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7240b57cec5SDimitry Andric 725cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c) 7260b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric// 26.3.6 operators: 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andrictemplate <class _Tp> 731cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 732cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) { 7330b57cec5SDimitry Andric complex<_Tp> __t(__x); 7340b57cec5SDimitry Andric __t += __y; 7350b57cec5SDimitry Andric return __t; 7360b57cec5SDimitry Andric} 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andrictemplate <class _Tp> 739cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 740cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) { 7410b57cec5SDimitry Andric complex<_Tp> __t(__x); 7420b57cec5SDimitry Andric __t += __y; 7430b57cec5SDimitry Andric return __t; 7440b57cec5SDimitry Andric} 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andrictemplate <class _Tp> 747cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 748cb14a3feSDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) { 7490b57cec5SDimitry Andric complex<_Tp> __t(__y); 7500b57cec5SDimitry Andric __t += __x; 7510b57cec5SDimitry Andric return __t; 7520b57cec5SDimitry Andric} 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andrictemplate <class _Tp> 755cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 756cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) { 7570b57cec5SDimitry Andric complex<_Tp> __t(__x); 7580b57cec5SDimitry Andric __t -= __y; 7590b57cec5SDimitry Andric return __t; 7600b57cec5SDimitry Andric} 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andrictemplate <class _Tp> 763cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 764cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) { 7650b57cec5SDimitry Andric complex<_Tp> __t(__x); 7660b57cec5SDimitry Andric __t -= __y; 7670b57cec5SDimitry Andric return __t; 7680b57cec5SDimitry Andric} 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andrictemplate <class _Tp> 771cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 772cb14a3feSDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) { 7730b57cec5SDimitry Andric complex<_Tp> __t(-__y); 7740b57cec5SDimitry Andric __t += __x; 7750b57cec5SDimitry Andric return __t; 7760b57cec5SDimitry Andric} 7770b57cec5SDimitry Andric 7780fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> > 7790fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 7800fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) { 7810fca6ea1SDimitry Andric return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() * __rhs.__builtin()); 7820fca6ea1SDimitry Andric} 7830fca6ea1SDimitry Andric 7840fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> > 785bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 786cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) { 7870b57cec5SDimitry Andric _Tp __a = __z.real(); 7880b57cec5SDimitry Andric _Tp __b = __z.imag(); 7890b57cec5SDimitry Andric _Tp __c = __w.real(); 7900b57cec5SDimitry Andric _Tp __d = __w.imag(); 791bdd1243dSDimitry Andric 7920fca6ea1SDimitry Andric return complex<_Tp>((__a * __c) - (__b * __d), (__a * __d) + (__b * __c)); 7930b57cec5SDimitry Andric} 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andrictemplate <class _Tp> 796cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 797cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) { 7980b57cec5SDimitry Andric complex<_Tp> __t(__x); 7990b57cec5SDimitry Andric __t *= __y; 8000b57cec5SDimitry Andric return __t; 8010b57cec5SDimitry Andric} 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andrictemplate <class _Tp> 804cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 805cb14a3feSDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) { 8060b57cec5SDimitry Andric complex<_Tp> __t(__y); 8070b57cec5SDimitry Andric __t *= __x; 8080b57cec5SDimitry Andric return __t; 8090b57cec5SDimitry Andric} 8100b57cec5SDimitry Andric 8110fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> > 8120fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 8130fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) { 8140fca6ea1SDimitry Andric return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() / __rhs.__builtin()); 8150fca6ea1SDimitry Andric} 8160fca6ea1SDimitry Andric 8170fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> > 818bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 819cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) { 8200b57cec5SDimitry Andric _Tp __a = __z.real(); 8210b57cec5SDimitry Andric _Tp __b = __z.imag(); 8220b57cec5SDimitry Andric _Tp __c = __w.real(); 8230b57cec5SDimitry Andric _Tp __d = __w.imag(); 824bdd1243dSDimitry Andric 8250b57cec5SDimitry Andric _Tp __denom = __c * __c + __d * __d; 8260fca6ea1SDimitry Andric return complex<_Tp>((__a * __c + __b * __d) / __denom, (__b * __c - __a * __d) / __denom); 8270b57cec5SDimitry Andric} 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andrictemplate <class _Tp> 830cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 831cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) { 8320b57cec5SDimitry Andric return complex<_Tp>(__x.real() / __y, __x.imag() / __y); 8330b57cec5SDimitry Andric} 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andrictemplate <class _Tp> 836cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 837cb14a3feSDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) { 8380b57cec5SDimitry Andric complex<_Tp> __t(__x); 8390b57cec5SDimitry Andric __t /= __y; 8400b57cec5SDimitry Andric return __t; 8410b57cec5SDimitry Andric} 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andrictemplate <class _Tp> 844cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator+(const complex<_Tp>& __x) { 8450b57cec5SDimitry Andric return __x; 8460b57cec5SDimitry Andric} 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andrictemplate <class _Tp> 849cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator-(const complex<_Tp>& __x) { 8500b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), -__x.imag()); 8510b57cec5SDimitry Andric} 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andrictemplate <class _Tp> 854cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 855cb14a3feSDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8560b57cec5SDimitry Andric return __x.real() == __y.real() && __x.imag() == __y.imag(); 8570b57cec5SDimitry Andric} 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andrictemplate <class _Tp> 860cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const complex<_Tp>& __x, const _Tp& __y) { 8610b57cec5SDimitry Andric return __x.real() == __y && __x.imag() == 0; 8620b57cec5SDimitry Andric} 8630b57cec5SDimitry Andric 86406c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 86506c3fb27SDimitry Andric 8660b57cec5SDimitry Andrictemplate <class _Tp> 867cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const _Tp& __x, const complex<_Tp>& __y) { 8680b57cec5SDimitry Andric return __x == __y.real() && 0 == __y.imag(); 8690b57cec5SDimitry Andric} 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andrictemplate <class _Tp> 872cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 873cb14a3feSDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8740b57cec5SDimitry Andric return !(__x == __y); 8750b57cec5SDimitry Andric} 8760b57cec5SDimitry Andric 8770b57cec5SDimitry Andrictemplate <class _Tp> 878cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const complex<_Tp>& __x, const _Tp& __y) { 8790b57cec5SDimitry Andric return !(__x == __y); 8800b57cec5SDimitry Andric} 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andrictemplate <class _Tp> 883cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const _Tp& __x, const complex<_Tp>& __y) { 8840b57cec5SDimitry Andric return !(__x == __y); 8850b57cec5SDimitry Andric} 8860b57cec5SDimitry Andric 88706c3fb27SDimitry Andric#endif 88806c3fb27SDimitry Andric 8890b57cec5SDimitry Andric// 26.3.7 values: 8900b57cec5SDimitry Andric 891cb14a3feSDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, bool = is_floating_point<_Tp>::value > 8920b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {}; 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric// Integral Types 8950b57cec5SDimitry Andrictemplate <class _Tp> 896cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> { 8970b57cec5SDimitry Andric typedef double _ValueType; 8980b57cec5SDimitry Andric typedef complex<double> _ComplexType; 8990b57cec5SDimitry Andric}; 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andric// Floating point types 9020b57cec5SDimitry Andrictemplate <class _Tp> 903cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> { 9040b57cec5SDimitry Andric typedef _Tp _ValueType; 9050b57cec5SDimitry Andric typedef complex<_Tp> _ComplexType; 9060b57cec5SDimitry Andric}; 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric// real 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andrictemplate <class _Tp> 911cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) { 9120b57cec5SDimitry Andric return __c.real(); 9130b57cec5SDimitry Andric} 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andrictemplate <class _Tp> 916cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 917cb14a3feSDimitry Andricreal(_Tp __re) { 9180b57cec5SDimitry Andric return __re; 9190b57cec5SDimitry Andric} 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric// imag 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andrictemplate <class _Tp> 924cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) { 9250b57cec5SDimitry Andric return __c.imag(); 9260b57cec5SDimitry Andric} 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andrictemplate <class _Tp> 929cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 930cb14a3feSDimitry Andricimag(_Tp) { 9310b57cec5SDimitry Andric return 0; 9320b57cec5SDimitry Andric} 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric// abs 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andrictemplate <class _Tp> 937cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) { 938bdd1243dSDimitry Andric return std::hypot(__c.real(), __c.imag()); 9390b57cec5SDimitry Andric} 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric// arg 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andrictemplate <class _Tp> 944cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) { 945bdd1243dSDimitry Andric return std::atan2(__c.imag(), __c.real()); 9460b57cec5SDimitry Andric} 9470b57cec5SDimitry Andric 9485f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0> 949cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) { 950bdd1243dSDimitry Andric return std::atan2l(0.L, __re); 9510b57cec5SDimitry Andric} 9520b57cec5SDimitry Andric 9535f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0> 954cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) { 955bdd1243dSDimitry Andric return std::atan2(0., __re); 9560b57cec5SDimitry Andric} 9570b57cec5SDimitry Andric 9585f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0> 959cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) { 960bdd1243dSDimitry Andric return std::atan2f(0.F, __re); 9610b57cec5SDimitry Andric} 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric// norm 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andrictemplate <class _Tp> 966cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) { 967bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real())) 968bdd1243dSDimitry Andric return std::abs(__c.real()); 969bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.imag())) 970bdd1243dSDimitry Andric return std::abs(__c.imag()); 9710b57cec5SDimitry Andric return __c.real() * __c.real() + __c.imag() * __c.imag(); 9720b57cec5SDimitry Andric} 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andrictemplate <class _Tp> 975cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 976cb14a3feSDimitry Andricnorm(_Tp __re) { 9770b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; 9780b57cec5SDimitry Andric return static_cast<_ValueType>(__re) * __re; 9790b57cec5SDimitry Andric} 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric// conj 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andrictemplate <class _Tp> 984cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> conj(const complex<_Tp>& __c) { 9850b57cec5SDimitry Andric return complex<_Tp>(__c.real(), -__c.imag()); 9860b57cec5SDimitry Andric} 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andrictemplate <class _Tp> 989cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType 990cb14a3feSDimitry Andricconj(_Tp __re) { 9910b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9920b57cec5SDimitry Andric return _ComplexType(__re); 9930b57cec5SDimitry Andric} 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric// proj 9960b57cec5SDimitry Andric 9970b57cec5SDimitry Andrictemplate <class _Tp> 998cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) { 999e8d8bef9SDimitry Andric complex<_Tp> __r = __c; 1000bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag())) 1001bdd1243dSDimitry Andric __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag())); 10020b57cec5SDimitry Andric return __r; 10030b57cec5SDimitry Andric} 10040b57cec5SDimitry Andric 10055f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 1006cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 1007bdd1243dSDimitry Andric if (std::__constexpr_isinf(__re)) 1008bdd1243dSDimitry Andric __re = std::abs(__re); 10090b57cec5SDimitry Andric return complex<_Tp>(__re); 10100b57cec5SDimitry Andric} 10110b57cec5SDimitry Andric 10125f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 1013cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 10140b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 10150b57cec5SDimitry Andric return _ComplexType(__re); 10160b57cec5SDimitry Andric} 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric// polar 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andrictemplate <class _Tp> 1021cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) { 1022bdd1243dSDimitry Andric if (std::__constexpr_isnan(__rho) || std::signbit(__rho)) 10230b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 1024cb14a3feSDimitry Andric if (std::__constexpr_isnan(__theta)) { 1025bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10260b57cec5SDimitry Andric return complex<_Tp>(__rho, __theta); 10270b57cec5SDimitry Andric return complex<_Tp>(__theta, __theta); 10280b57cec5SDimitry Andric } 1029cb14a3feSDimitry Andric if (std::__constexpr_isinf(__theta)) { 1030bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10310b57cec5SDimitry Andric return complex<_Tp>(__rho, _Tp(NAN)); 10320b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 10330b57cec5SDimitry Andric } 1034bdd1243dSDimitry Andric _Tp __x = __rho * std::cos(__theta); 1035bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x)) 10360b57cec5SDimitry Andric __x = 0; 1037bdd1243dSDimitry Andric _Tp __y = __rho * std::sin(__theta); 1038bdd1243dSDimitry Andric if (std::__constexpr_isnan(__y)) 10390b57cec5SDimitry Andric __y = 0; 10400b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 10410b57cec5SDimitry Andric} 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric// log 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andrictemplate <class _Tp> 1046cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) { 1047bdd1243dSDimitry Andric return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x)); 10480b57cec5SDimitry Andric} 10490b57cec5SDimitry Andric 10500b57cec5SDimitry Andric// log10 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andrictemplate <class _Tp> 1053cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) { 1054bdd1243dSDimitry Andric return std::log(__x) / std::log(_Tp(10)); 10550b57cec5SDimitry Andric} 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric// sqrt 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andrictemplate <class _Tp> 1060cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) { 1061bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 10620b57cec5SDimitry Andric return complex<_Tp>(_Tp(INFINITY), __x.imag()); 1063cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 10640b57cec5SDimitry Andric if (__x.real() > _Tp(0)) 1065cb14a3feSDimitry Andric return complex<_Tp>( 1066cb14a3feSDimitry Andric __x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag())); 1067cb14a3feSDimitry Andric return complex<_Tp>( 1068cb14a3feSDimitry Andric std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag())); 10690b57cec5SDimitry Andric } 1070bdd1243dSDimitry Andric return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2)); 10710b57cec5SDimitry Andric} 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric// exp 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andrictemplate <class _Tp> 1076cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) { 10770b57cec5SDimitry Andric _Tp __i = __x.imag(); 1078349cc55cSDimitry Andric if (__i == 0) { 1079bdd1243dSDimitry Andric return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag())); 1080349cc55cSDimitry Andric } 1081cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1082cb14a3feSDimitry Andric if (__x.real() < _Tp(0)) { 1083bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__i)) 10840b57cec5SDimitry Andric __i = _Tp(1); 1085cb14a3feSDimitry Andric } else if (__i == 0 || !std::__constexpr_isfinite(__i)) { 1086bdd1243dSDimitry Andric if (std::__constexpr_isinf(__i)) 10870b57cec5SDimitry Andric __i = _Tp(NAN); 10880b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __i); 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric } 1091bdd1243dSDimitry Andric _Tp __e = std::exp(__x.real()); 1092bdd1243dSDimitry Andric return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i)); 10930b57cec5SDimitry Andric} 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric// pow 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andrictemplate <class _Tp> 1098cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { 1099bdd1243dSDimitry Andric return std::exp(__y * std::log(__x)); 11000b57cec5SDimitry Andric} 11010b57cec5SDimitry Andric 11020b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1103cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> 1104cb14a3feSDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) { 11050b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11065f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11070b57cec5SDimitry Andric} 11080b57cec5SDimitry Andric 11095f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0> 1110cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) { 11110b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11125f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11130b57cec5SDimitry Andric} 11140b57cec5SDimitry Andric 11155f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value, int> = 0> 1116cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const _Tp& __x, const complex<_Up>& __y) { 11170b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11185f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11190b57cec5SDimitry Andric} 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric// __sqr, computes pow(x, 2) 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andrictemplate <class _Tp> 1124cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) { 1125cb14a3feSDimitry Andric return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), _Tp(2) * __x.real() * __x.imag()); 11260b57cec5SDimitry Andric} 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric// asinh 11290b57cec5SDimitry Andric 11300b57cec5SDimitry Andrictemplate <class _Tp> 1131cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) { 11320b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1133cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1134bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 11350b57cec5SDimitry Andric return __x; 1136bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1137bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 1138bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11390b57cec5SDimitry Andric } 1140cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1141bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 11420b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 11430b57cec5SDimitry Andric if (__x.imag() == 0) 11440b57cec5SDimitry Andric return __x; 11450b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11460b57cec5SDimitry Andric } 1147bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1148bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 1149bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1))); 1150bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 11510b57cec5SDimitry Andric} 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric// acosh 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andrictemplate <class _Tp> 1156cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) { 11570b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1158cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1159bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 1160bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1161cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 11620b57cec5SDimitry Andric if (__x.real() > 0) 1163bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 11640b57cec5SDimitry Andric else 1165bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag())); 11660b57cec5SDimitry Andric } 11670b57cec5SDimitry Andric if (__x.real() < 0) 1168bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag())); 1169bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11700b57cec5SDimitry Andric } 1171cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1172bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1173bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), __x.real()); 11740b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11750b57cec5SDimitry Andric } 1176bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1177bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag())); 1178bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1179bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag())); 11800b57cec5SDimitry Andric} 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric// atanh 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andrictemplate <class _Tp> 1185cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) { 11860b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1187cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 1188bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 11890b57cec5SDimitry Andric } 1190cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.imag())) { 1191bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) || __x.real() == 0) 1192bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag()); 11930b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.imag()); 11940b57cec5SDimitry Andric } 1195cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 11960b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11970b57cec5SDimitry Andric } 1198cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1199bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 12000b57cec5SDimitry Andric } 1201cb14a3feSDimitry Andric if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) { 1202bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag())); 12030b57cec5SDimitry Andric } 1204bdd1243dSDimitry Andric complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); 1205bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 12060b57cec5SDimitry Andric} 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric// sinh 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andrictemplate <class _Tp> 1211cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) { 1212bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 12130b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1214bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 12150b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1216bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 12170b57cec5SDimitry Andric return __x; 1218bdd1243dSDimitry Andric return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag())); 12190b57cec5SDimitry Andric} 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric// cosh 12220b57cec5SDimitry Andric 12230b57cec5SDimitry Andrictemplate <class _Tp> 1224cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) { 1225bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 1226bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), _Tp(NAN)); 1227bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 12280b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), __x.real()); 12290b57cec5SDimitry Andric if (__x.real() == 0 && __x.imag() == 0) 12300b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), __x.imag()); 1231bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 1232bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1233bdd1243dSDimitry Andric return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag())); 12340b57cec5SDimitry Andric} 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric// tanh 12370b57cec5SDimitry Andric 12380b57cec5SDimitry Andrictemplate <class _Tp> 1239cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) { 1240cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1241bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__x.imag())) 1242bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0)); 1243bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag()))); 12440b57cec5SDimitry Andric } 1245bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0) 12460b57cec5SDimitry Andric return __x; 12470b57cec5SDimitry Andric _Tp __2r(_Tp(2) * __x.real()); 12480b57cec5SDimitry Andric _Tp __2i(_Tp(2) * __x.imag()); 1249bdd1243dSDimitry Andric _Tp __d(std::cosh(__2r) + std::cos(__2i)); 1250bdd1243dSDimitry Andric _Tp __2rsh(std::sinh(__2r)); 1251bdd1243dSDimitry Andric if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d)) 1252cb14a3feSDimitry Andric return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); 1253bdd1243dSDimitry Andric return complex<_Tp>(__2rsh / __d, std::sin(__2i) / __d); 12540b57cec5SDimitry Andric} 12550b57cec5SDimitry Andric 12560b57cec5SDimitry Andric// asin 12570b57cec5SDimitry Andric 12580b57cec5SDimitry Andrictemplate <class _Tp> 1259cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) { 1260bdd1243dSDimitry Andric complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real())); 12610b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12620b57cec5SDimitry Andric} 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric// acos 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andrictemplate <class _Tp> 1267cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) { 12680b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1269cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1270bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 12710b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 1272cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 12730b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 12740b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); 12750b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 1278bdd1243dSDimitry Andric return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real()); 1279bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real()); 12800b57cec5SDimitry Andric } 1281cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1282bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12830b57cec5SDimitry Andric return complex<_Tp>(__x.real(), -__x.imag()); 12840b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12850b57cec5SDimitry Andric } 1286bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12870b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1288bdd1243dSDimitry Andric if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag()))) 12890b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1290bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1291bdd1243dSDimitry Andric if (std::signbit(__x.imag())) 1292bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real())); 1293bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real())); 12940b57cec5SDimitry Andric} 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric// atan 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andrictemplate <class _Tp> 1299cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) { 1300bdd1243dSDimitry Andric complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real())); 13010b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13020b57cec5SDimitry Andric} 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andric// sin 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andrictemplate <class _Tp> 1307cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) { 1308bdd1243dSDimitry Andric complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real())); 13090b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13100b57cec5SDimitry Andric} 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric// cos 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andrictemplate <class _Tp> 1315cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) { 1316bdd1243dSDimitry Andric return std::cosh(complex<_Tp>(-__x.imag(), __x.real())); 13170b57cec5SDimitry Andric} 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric// tan 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andrictemplate <class _Tp> 1322cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) { 1323bdd1243dSDimitry Andric complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real())); 13240b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13250b57cec5SDimitry Andric} 13260b57cec5SDimitry Andric 1327bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 13280b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1329bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 1330cb14a3feSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) { 1331cb14a3feSDimitry Andric if (__is.good()) { 1332bdd1243dSDimitry Andric std::ws(__is); 1333cb14a3feSDimitry Andric if (__is.peek() == _CharT('(')) { 13340b57cec5SDimitry Andric __is.get(); 13350b57cec5SDimitry Andric _Tp __r; 13360b57cec5SDimitry Andric __is >> __r; 1337cb14a3feSDimitry Andric if (!__is.fail()) { 1338bdd1243dSDimitry Andric std::ws(__is); 13390b57cec5SDimitry Andric _CharT __c = __is.peek(); 1340cb14a3feSDimitry Andric if (__c == _CharT(',')) { 13410b57cec5SDimitry Andric __is.get(); 13420b57cec5SDimitry Andric _Tp __i; 13430b57cec5SDimitry Andric __is >> __i; 1344cb14a3feSDimitry Andric if (!__is.fail()) { 1345bdd1243dSDimitry Andric std::ws(__is); 13460b57cec5SDimitry Andric __c = __is.peek(); 1347cb14a3feSDimitry Andric if (__c == _CharT(')')) { 13480b57cec5SDimitry Andric __is.get(); 13490b57cec5SDimitry Andric __x = complex<_Tp>(__r, __i); 1350cb14a3feSDimitry Andric } else 13515ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1352cb14a3feSDimitry Andric } else 13535ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1354cb14a3feSDimitry Andric } else if (__c == _CharT(')')) { 13550b57cec5SDimitry Andric __is.get(); 13560b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 1357cb14a3feSDimitry Andric } else 13585ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1359cb14a3feSDimitry Andric } else 13605ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1361cb14a3feSDimitry Andric } else { 13620b57cec5SDimitry Andric _Tp __r; 13630b57cec5SDimitry Andric __is >> __r; 13640b57cec5SDimitry Andric if (!__is.fail()) 13650b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 13660b57cec5SDimitry Andric else 13675ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13680b57cec5SDimitry Andric } 1369cb14a3feSDimitry Andric } else 13705ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13710b57cec5SDimitry Andric return __is; 13720b57cec5SDimitry Andric} 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1375bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 1376cb14a3feSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) { 13770b57cec5SDimitry Andric basic_ostringstream<_CharT, _Traits> __s; 13780b57cec5SDimitry Andric __s.flags(__os.flags()); 13790b57cec5SDimitry Andric __s.imbue(__os.getloc()); 13800b57cec5SDimitry Andric __s.precision(__os.precision()); 13810b57cec5SDimitry Andric __s << '(' << __x.real() << ',' << __x.imag() << ')'; 13820b57cec5SDimitry Andric return __os << __s.str(); 13830b57cec5SDimitry Andric} 1384e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION 13850b57cec5SDimitry Andric 13860fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 13870fca6ea1SDimitry Andric 13880fca6ea1SDimitry Andric// [complex.tuple], tuple interface 13890fca6ea1SDimitry Andric 13900fca6ea1SDimitry Andrictemplate <class _Tp> 13910fca6ea1SDimitry Andricstruct tuple_size<complex<_Tp>> : integral_constant<size_t, 2> {}; 13920fca6ea1SDimitry Andric 13930fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Tp> 13940fca6ea1SDimitry Andricstruct tuple_element<_Ip, complex<_Tp>> { 13950fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 13960fca6ea1SDimitry Andric using type = _Tp; 13970fca6ea1SDimitry Andric}; 13980fca6ea1SDimitry Andric 13990fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 14000fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept { 14010fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 14020fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 14030fca6ea1SDimitry Andric return __z.__re_; 14040fca6ea1SDimitry Andric } else { 14050fca6ea1SDimitry Andric return __z.__im_; 14060fca6ea1SDimitry Andric } 14070fca6ea1SDimitry Andric} 14080fca6ea1SDimitry Andric 14090fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 14100fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept { 14110fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 14120fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 14130fca6ea1SDimitry Andric return std::move(__z.__re_); 14140fca6ea1SDimitry Andric } else { 14150fca6ea1SDimitry Andric return std::move(__z.__im_); 14160fca6ea1SDimitry Andric } 14170fca6ea1SDimitry Andric} 14180fca6ea1SDimitry Andric 14190fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 14200fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept { 14210fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 14220fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 14230fca6ea1SDimitry Andric return __z.__re_; 14240fca6ea1SDimitry Andric } else { 14250fca6ea1SDimitry Andric return __z.__im_; 14260fca6ea1SDimitry Andric } 14270fca6ea1SDimitry Andric} 14280fca6ea1SDimitry Andric 14290fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 14300fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept { 14310fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 14320fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 14330fca6ea1SDimitry Andric return std::move(__z.__re_); 14340fca6ea1SDimitry Andric } else { 14350fca6ea1SDimitry Andric return std::move(__z.__im_); 14360fca6ea1SDimitry Andric } 14370fca6ea1SDimitry Andric} 14380fca6ea1SDimitry Andric 14390fca6ea1SDimitry Andric#endif // _LIBCPP_STD_VER >= 26 14400fca6ea1SDimitry Andric 144106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 14420b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals] 1443cb14a3feSDimitry Andricinline namespace literals { 1444cb14a3feSDimitry Andricinline namespace complex_literals { 1445cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(long double __im) { return {0.0l, __im}; } 14460b57cec5SDimitry Andric 1447cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(unsigned long long __im) { 14480b57cec5SDimitry Andric return {0.0l, static_cast<long double>(__im)}; 14490b57cec5SDimitry Andric} 14500b57cec5SDimitry Andric 1451cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(long double __im) { 14520b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 14530b57cec5SDimitry Andric} 14540b57cec5SDimitry Andric 1455cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(unsigned long long __im) { 14560b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 14570b57cec5SDimitry Andric} 14580b57cec5SDimitry Andric 1459cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(long double __im) { 14600b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 14610b57cec5SDimitry Andric} 14620b57cec5SDimitry Andric 1463cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long long __im) { 14640b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 14650b57cec5SDimitry Andric} 14660eae32dcSDimitry Andric} // namespace complex_literals 14670eae32dcSDimitry Andric} // namespace literals 14680b57cec5SDimitry Andric#endif 14690b57cec5SDimitry Andric 14700b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 14710b57cec5SDimitry Andric 14720fca6ea1SDimitry Andric_LIBCPP_POP_MACROS 14730fca6ea1SDimitry Andric 147406c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 14755f757f3fSDimitry Andric# include <iosfwd> 14765f757f3fSDimitry Andric# include <stdexcept> 147706c3fb27SDimitry Andric# include <type_traits> 147806c3fb27SDimitry Andric#endif 147906c3fb27SDimitry Andric 14800b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX 1481