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 230*0fca6ea1SDimitry Andric // [complex.tuple], tuple interface 231*0fca6ea1SDimitry Andric template<class T> struct tuple_size; // Since C++26 232*0fca6ea1SDimitry Andric template<size_t I, class T> struct tuple_element; // Since C++26 233*0fca6ea1SDimitry Andric template<class T> struct tuple_size<complex<T>>; // Since C++26 234*0fca6ea1SDimitry Andric template<size_t I, class T> struct tuple_element<I, complex<T>>; // Since C++26 235*0fca6ea1SDimitry Andric template<size_t I, class T> 236*0fca6ea1SDimitry Andric constexpr T& get(complex<T>&) noexcept; // Since C++26 237*0fca6ea1SDimitry Andric template<size_t I, class T> 238*0fca6ea1SDimitry Andric constexpr T&& get(complex<T>&&) noexcept; // Since C++26 239*0fca6ea1SDimitry Andric template<size_t I, class T> 240*0fca6ea1SDimitry Andric constexpr const T& get(const complex<T>&) noexcept; // Since C++26 241*0fca6ea1SDimitry Andric template<size_t I, class T> 242*0fca6ea1SDimitry Andric constexpr const T&& get(const complex<T>&&) noexcept; // Since C++26 243*0fca6ea1SDimitry Andric 244*0fca6ea1SDimitry Andric // [complex.literals], complex literals 245*0fca6ea1SDimitry Andric inline namespace literals { 246*0fca6ea1SDimitry Andric inline namespace complex_literals { 247*0fca6ea1SDimitry Andric constexpr complex<long double> operator""il(long double); // Since C++14 248*0fca6ea1SDimitry Andric constexpr complex<long double> operator""il(unsigned long long); // Since C++14 249*0fca6ea1SDimitry Andric constexpr complex<double> operator""i(long double); // Since C++14 250*0fca6ea1SDimitry Andric constexpr complex<double> operator""i(unsigned long long); // Since C++14 251*0fca6ea1SDimitry Andric constexpr complex<float> operator""if(long double); // Since C++14 252*0fca6ea1SDimitry Andric constexpr complex<float> operator""if(unsigned long long); // Since C++14 253*0fca6ea1SDimitry Andric } 254*0fca6ea1SDimitry Andric } 2550b57cec5SDimitry Andric} // std 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric*/ 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric#include <__config> 260*0fca6ea1SDimitry Andric#include <__fwd/complex.h> 261*0fca6ea1SDimitry Andric#include <__fwd/tuple.h> 262*0fca6ea1SDimitry Andric#include <__tuple/tuple_element.h> 263*0fca6ea1SDimitry Andric#include <__tuple/tuple_size.h> 264*0fca6ea1SDimitry Andric#include <__type_traits/conditional.h> 265*0fca6ea1SDimitry 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 277*0fca6ea1SDimitry Andric_LIBCPP_PUSH_MACROS 278*0fca6ea1SDimitry Andric#include <__undef_macros> 279*0fca6ea1SDimitry Andric 2800b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 2810b57cec5SDimitry Andric 282cb14a3feSDimitry Andrictemplate <class _Tp> 283cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex; 2840b57cec5SDimitry Andric 285*0fca6ea1SDimitry 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); 288*0fca6ea1SDimitry Andric 289*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0> 290*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 291*0fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w); 292*0fca6ea1SDimitry Andric 293*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 294*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 295*0fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y); 296*0fca6ea1SDimitry Andric 297*0fca6ea1SDimitry 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 } 376*0fca6ea1SDimitry Andric 377*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 378*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 379*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 380*0fca6ea1SDimitry Andric 381*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 382*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 383*0fca6ea1SDimitry Andric 384*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 385*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 386*0fca6ea1SDimitry Andric 387*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 388*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 389*0fca6ea1SDimitry 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 397*0fca6ea1SDimitry Andricstruct __from_builtin_tag {}; 398*0fca6ea1SDimitry Andric 399*0fca6ea1SDimitry Andrictemplate <class _Tp> 400*0fca6ea1SDimitry Andricusing __complex_t = 401*0fca6ea1SDimitry Andric __conditional_t<is_same<_Tp, float>::value, 402*0fca6ea1SDimitry Andric _Complex float, 403*0fca6ea1SDimitry Andric __conditional_t<is_same<_Tp, double>::value, _Complex double, _Complex long double> >; 404*0fca6ea1SDimitry Andric 405*0fca6ea1SDimitry Andrictemplate <class _Tp> 406*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __complex_t<_Tp> __make_complex(_Tp __re, _Tp __im) { 407*0fca6ea1SDimitry Andric#if __has_builtin(__builtin_complex) 408*0fca6ea1SDimitry Andric return __builtin_complex(__re, __im); 409*0fca6ea1SDimitry Andric#else 410*0fca6ea1SDimitry Andric return __complex_t<_Tp>{__re, __im}; 411*0fca6ea1SDimitry Andric#endif 412*0fca6ea1SDimitry Andric} 413*0fca6ea1SDimitry 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) {} 423*0fca6ea1SDimitry Andric 424*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex float __v) 425*0fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 426*0fca6ea1SDimitry Andric 427cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 428cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 4290b57cec5SDimitry Andric 4305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; } 4315f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; } 4320b57cec5SDimitry Andric 4335f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 4345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 4350b57cec5SDimitry Andric 436*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex float __builtin() const { return std::__make_complex(__re_, __im_); } 437*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex float __f) { 438*0fca6ea1SDimitry Andric __re_ = __real__ __f; 439*0fca6ea1SDimitry Andric __im_ = __imag__ __f; 440*0fca6ea1SDimitry Andric } 441*0fca6ea1SDimitry Andric 442cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(float __re) { 443cb14a3feSDimitry Andric __re_ = __re; 444cb14a3feSDimitry Andric __im_ = value_type(); 445cb14a3feSDimitry Andric return *this; 446cb14a3feSDimitry Andric } 447cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) { 448cb14a3feSDimitry Andric __re_ += __re; 449cb14a3feSDimitry Andric return *this; 450cb14a3feSDimitry Andric } 451cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) { 452cb14a3feSDimitry Andric __re_ -= __re; 453cb14a3feSDimitry Andric return *this; 454cb14a3feSDimitry Andric } 455cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) { 456cb14a3feSDimitry Andric __re_ *= __re; 457cb14a3feSDimitry Andric __im_ *= __re; 458cb14a3feSDimitry Andric return *this; 459cb14a3feSDimitry Andric } 460cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) { 461cb14a3feSDimitry Andric __re_ /= __re; 462cb14a3feSDimitry Andric __im_ /= __re; 463cb14a3feSDimitry Andric return *this; 464cb14a3feSDimitry Andric } 4650b57cec5SDimitry Andric 466cb14a3feSDimitry Andric template <class _Xp> 467cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 4680b57cec5SDimitry Andric __re_ = __c.real(); 4690b57cec5SDimitry Andric __im_ = __c.imag(); 4700b57cec5SDimitry Andric return *this; 4710b57cec5SDimitry Andric } 472cb14a3feSDimitry Andric template <class _Xp> 473cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 4740b57cec5SDimitry Andric __re_ += __c.real(); 4750b57cec5SDimitry Andric __im_ += __c.imag(); 4760b57cec5SDimitry Andric return *this; 4770b57cec5SDimitry Andric } 478cb14a3feSDimitry Andric template <class _Xp> 479cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 4800b57cec5SDimitry Andric __re_ -= __c.real(); 4810b57cec5SDimitry Andric __im_ -= __c.imag(); 4820b57cec5SDimitry Andric return *this; 4830b57cec5SDimitry Andric } 484cb14a3feSDimitry Andric template <class _Xp> 485cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 4860b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 4870b57cec5SDimitry Andric return *this; 4880b57cec5SDimitry Andric } 489cb14a3feSDimitry Andric template <class _Xp> 490cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 4910b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 4920b57cec5SDimitry Andric return *this; 4930b57cec5SDimitry Andric } 494*0fca6ea1SDimitry Andric 495*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 496*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 497*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 498*0fca6ea1SDimitry Andric 499*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 500*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 501*0fca6ea1SDimitry Andric 502*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 503*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 504*0fca6ea1SDimitry Andric 505*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 506*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 507*0fca6ea1SDimitry Andric#endif 5080b57cec5SDimitry Andric}; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andrictemplate <> 511cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> { 5120b57cec5SDimitry Andric double __re_; 5130b57cec5SDimitry Andric double __im_; 514cb14a3feSDimitry Andric 5150b57cec5SDimitry Andricpublic: 5160b57cec5SDimitry Andric typedef double value_type; 5170b57cec5SDimitry Andric 518cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {} 519*0fca6ea1SDimitry Andric 520*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex double __v) 521*0fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 522*0fca6ea1SDimitry Andric 523cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 524cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); 5250b57cec5SDimitry Andric 5265f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; } 5275f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; } 5280b57cec5SDimitry Andric 5295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 5305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 5310b57cec5SDimitry Andric 532*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex double __builtin() const { 533*0fca6ea1SDimitry Andric return std::__make_complex(__re_, __im_); 534*0fca6ea1SDimitry Andric } 535*0fca6ea1SDimitry Andric 536*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex double __f) { 537*0fca6ea1SDimitry Andric __re_ = __real__ __f; 538*0fca6ea1SDimitry Andric __im_ = __imag__ __f; 539*0fca6ea1SDimitry Andric } 540*0fca6ea1SDimitry Andric 541cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(double __re) { 542cb14a3feSDimitry Andric __re_ = __re; 543cb14a3feSDimitry Andric __im_ = value_type(); 544cb14a3feSDimitry Andric return *this; 545cb14a3feSDimitry Andric } 546cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) { 547cb14a3feSDimitry Andric __re_ += __re; 548cb14a3feSDimitry Andric return *this; 549cb14a3feSDimitry Andric } 550cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) { 551cb14a3feSDimitry Andric __re_ -= __re; 552cb14a3feSDimitry Andric return *this; 553cb14a3feSDimitry Andric } 554cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) { 555cb14a3feSDimitry Andric __re_ *= __re; 556cb14a3feSDimitry Andric __im_ *= __re; 557cb14a3feSDimitry Andric return *this; 558cb14a3feSDimitry Andric } 559cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) { 560cb14a3feSDimitry Andric __re_ /= __re; 561cb14a3feSDimitry Andric __im_ /= __re; 562cb14a3feSDimitry Andric return *this; 563cb14a3feSDimitry Andric } 5640b57cec5SDimitry Andric 565cb14a3feSDimitry Andric template <class _Xp> 566cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 5670b57cec5SDimitry Andric __re_ = __c.real(); 5680b57cec5SDimitry Andric __im_ = __c.imag(); 5690b57cec5SDimitry Andric return *this; 5700b57cec5SDimitry Andric } 571cb14a3feSDimitry Andric template <class _Xp> 572cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 5730b57cec5SDimitry Andric __re_ += __c.real(); 5740b57cec5SDimitry Andric __im_ += __c.imag(); 5750b57cec5SDimitry Andric return *this; 5760b57cec5SDimitry Andric } 577cb14a3feSDimitry Andric template <class _Xp> 578cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 5790b57cec5SDimitry Andric __re_ -= __c.real(); 5800b57cec5SDimitry Andric __im_ -= __c.imag(); 5810b57cec5SDimitry Andric return *this; 5820b57cec5SDimitry Andric } 583cb14a3feSDimitry Andric template <class _Xp> 584cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 5850b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 5860b57cec5SDimitry Andric return *this; 5870b57cec5SDimitry Andric } 588cb14a3feSDimitry Andric template <class _Xp> 589cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 5900b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 5910b57cec5SDimitry Andric return *this; 5920b57cec5SDimitry Andric } 593*0fca6ea1SDimitry Andric 594*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 595*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 596*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 597*0fca6ea1SDimitry Andric 598*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 599*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 600*0fca6ea1SDimitry Andric 601*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 602*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 603*0fca6ea1SDimitry Andric 604*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 605*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 606*0fca6ea1SDimitry Andric#endif 6070b57cec5SDimitry Andric}; 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andrictemplate <> 610cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> { 6110b57cec5SDimitry Andric long double __re_; 6120b57cec5SDimitry Andric long double __im_; 613cb14a3feSDimitry Andric 6140b57cec5SDimitry Andricpublic: 6150b57cec5SDimitry Andric typedef long double value_type; 6160b57cec5SDimitry Andric 6175f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) 6180b57cec5SDimitry Andric : __re_(__re), __im_(__im) {} 619*0fca6ea1SDimitry Andric 620*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex long double __v) 621*0fca6ea1SDimitry Andric : __re_(__real__ __v), __im_(__imag__ __v) {} 622*0fca6ea1SDimitry Andric 623cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c); 624cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<double>& __c); 6250b57cec5SDimitry Andric 6265f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; } 6275f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; } 6280b57cec5SDimitry Andric 6295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; } 6305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; } 6310b57cec5SDimitry Andric 632*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex long double __builtin() const { 633*0fca6ea1SDimitry Andric return std::__make_complex(__re_, __im_); 634*0fca6ea1SDimitry Andric } 635*0fca6ea1SDimitry Andric 636*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex long double __f) { 637*0fca6ea1SDimitry Andric __re_ = __real__ __f; 638*0fca6ea1SDimitry Andric __im_ = __imag__ __f; 639*0fca6ea1SDimitry Andric } 640*0fca6ea1SDimitry Andric 641cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(long double __re) { 642cb14a3feSDimitry Andric __re_ = __re; 643cb14a3feSDimitry Andric __im_ = value_type(); 644cb14a3feSDimitry Andric return *this; 645cb14a3feSDimitry Andric } 646cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) { 647cb14a3feSDimitry Andric __re_ += __re; 648cb14a3feSDimitry Andric return *this; 649cb14a3feSDimitry Andric } 650cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) { 651cb14a3feSDimitry Andric __re_ -= __re; 652cb14a3feSDimitry Andric return *this; 653cb14a3feSDimitry Andric } 654cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) { 655cb14a3feSDimitry Andric __re_ *= __re; 656cb14a3feSDimitry Andric __im_ *= __re; 657cb14a3feSDimitry Andric return *this; 658cb14a3feSDimitry Andric } 659cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) { 660cb14a3feSDimitry Andric __re_ /= __re; 661cb14a3feSDimitry Andric __im_ /= __re; 662cb14a3feSDimitry Andric return *this; 663cb14a3feSDimitry Andric } 6640b57cec5SDimitry Andric 665cb14a3feSDimitry Andric template <class _Xp> 666cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) { 6670b57cec5SDimitry Andric __re_ = __c.real(); 6680b57cec5SDimitry Andric __im_ = __c.imag(); 6690b57cec5SDimitry Andric return *this; 6700b57cec5SDimitry Andric } 671cb14a3feSDimitry Andric template <class _Xp> 672cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) { 6730b57cec5SDimitry Andric __re_ += __c.real(); 6740b57cec5SDimitry Andric __im_ += __c.imag(); 6750b57cec5SDimitry Andric return *this; 6760b57cec5SDimitry Andric } 677cb14a3feSDimitry Andric template <class _Xp> 678cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) { 6790b57cec5SDimitry Andric __re_ -= __c.real(); 6800b57cec5SDimitry Andric __im_ -= __c.imag(); 6810b57cec5SDimitry Andric return *this; 6820b57cec5SDimitry Andric } 683cb14a3feSDimitry Andric template <class _Xp> 684cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) { 6850b57cec5SDimitry Andric *this = *this * complex(__c.real(), __c.imag()); 6860b57cec5SDimitry Andric return *this; 6870b57cec5SDimitry Andric } 688cb14a3feSDimitry Andric template <class _Xp> 689cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) { 6900b57cec5SDimitry Andric *this = *this / complex(__c.real(), __c.imag()); 6910b57cec5SDimitry Andric return *this; 6920b57cec5SDimitry Andric } 693*0fca6ea1SDimitry Andric 694*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 695*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 696*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; 697*0fca6ea1SDimitry Andric 698*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 699*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; 700*0fca6ea1SDimitry Andric 701*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 702*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; 703*0fca6ea1SDimitry Andric 704*0fca6ea1SDimitry Andric template <size_t _Ip, class _Xp> 705*0fca6ea1SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; 706*0fca6ea1SDimitry Andric#endif 7070b57cec5SDimitry Andric}; 7080b57cec5SDimitry Andric 709cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 710cb14a3feSDimitry Andric 711cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c) 7120b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7130b57cec5SDimitry Andric 714cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} 715cb14a3feSDimitry Andric 716cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c) 7170b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7180b57cec5SDimitry Andric 719cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c) 7200b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7210b57cec5SDimitry Andric 722cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c) 7230b57cec5SDimitry Andric : __re_(__c.real()), __im_(__c.imag()) {} 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric// 26.3.6 operators: 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andrictemplate <class _Tp> 728cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 729cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) { 7300b57cec5SDimitry Andric complex<_Tp> __t(__x); 7310b57cec5SDimitry Andric __t += __y; 7320b57cec5SDimitry Andric return __t; 7330b57cec5SDimitry Andric} 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andrictemplate <class _Tp> 736cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 737cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) { 7380b57cec5SDimitry Andric complex<_Tp> __t(__x); 7390b57cec5SDimitry Andric __t += __y; 7400b57cec5SDimitry Andric return __t; 7410b57cec5SDimitry Andric} 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andrictemplate <class _Tp> 744cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 745cb14a3feSDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) { 7460b57cec5SDimitry Andric complex<_Tp> __t(__y); 7470b57cec5SDimitry Andric __t += __x; 7480b57cec5SDimitry Andric return __t; 7490b57cec5SDimitry Andric} 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andrictemplate <class _Tp> 752cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 753cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) { 7540b57cec5SDimitry Andric complex<_Tp> __t(__x); 7550b57cec5SDimitry Andric __t -= __y; 7560b57cec5SDimitry Andric return __t; 7570b57cec5SDimitry Andric} 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andrictemplate <class _Tp> 760cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 761cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) { 7620b57cec5SDimitry Andric complex<_Tp> __t(__x); 7630b57cec5SDimitry Andric __t -= __y; 7640b57cec5SDimitry Andric return __t; 7650b57cec5SDimitry Andric} 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andrictemplate <class _Tp> 768cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 769cb14a3feSDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) { 7700b57cec5SDimitry Andric complex<_Tp> __t(-__y); 7710b57cec5SDimitry Andric __t += __x; 7720b57cec5SDimitry Andric return __t; 7730b57cec5SDimitry Andric} 7740b57cec5SDimitry Andric 775*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> > 776*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 777*0fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) { 778*0fca6ea1SDimitry Andric return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() * __rhs.__builtin()); 779*0fca6ea1SDimitry Andric} 780*0fca6ea1SDimitry Andric 781*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> > 782bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 783cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) { 7840b57cec5SDimitry Andric _Tp __a = __z.real(); 7850b57cec5SDimitry Andric _Tp __b = __z.imag(); 7860b57cec5SDimitry Andric _Tp __c = __w.real(); 7870b57cec5SDimitry Andric _Tp __d = __w.imag(); 788bdd1243dSDimitry Andric 789*0fca6ea1SDimitry Andric return complex<_Tp>((__a * __c) - (__b * __d), (__a * __d) + (__b * __c)); 7900b57cec5SDimitry Andric} 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andrictemplate <class _Tp> 793cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 794cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) { 7950b57cec5SDimitry Andric complex<_Tp> __t(__x); 7960b57cec5SDimitry Andric __t *= __y; 7970b57cec5SDimitry Andric return __t; 7980b57cec5SDimitry Andric} 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andrictemplate <class _Tp> 801cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 802cb14a3feSDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) { 8030b57cec5SDimitry Andric complex<_Tp> __t(__y); 8040b57cec5SDimitry Andric __t *= __x; 8050b57cec5SDimitry Andric return __t; 8060b57cec5SDimitry Andric} 8070b57cec5SDimitry Andric 808*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> > 809*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 810*0fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) { 811*0fca6ea1SDimitry Andric return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() / __rhs.__builtin()); 812*0fca6ea1SDimitry Andric} 813*0fca6ea1SDimitry Andric 814*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> > 815bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 816cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) { 8170b57cec5SDimitry Andric _Tp __a = __z.real(); 8180b57cec5SDimitry Andric _Tp __b = __z.imag(); 8190b57cec5SDimitry Andric _Tp __c = __w.real(); 8200b57cec5SDimitry Andric _Tp __d = __w.imag(); 821bdd1243dSDimitry Andric 8220b57cec5SDimitry Andric _Tp __denom = __c * __c + __d * __d; 823*0fca6ea1SDimitry Andric return complex<_Tp>((__a * __c + __b * __d) / __denom, (__b * __c - __a * __d) / __denom); 8240b57cec5SDimitry Andric} 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andrictemplate <class _Tp> 827cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 828cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) { 8290b57cec5SDimitry Andric return complex<_Tp>(__x.real() / __y, __x.imag() / __y); 8300b57cec5SDimitry Andric} 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andrictemplate <class _Tp> 833cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> 834cb14a3feSDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) { 8350b57cec5SDimitry Andric complex<_Tp> __t(__x); 8360b57cec5SDimitry Andric __t /= __y; 8370b57cec5SDimitry Andric return __t; 8380b57cec5SDimitry Andric} 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andrictemplate <class _Tp> 841cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator+(const complex<_Tp>& __x) { 8420b57cec5SDimitry Andric return __x; 8430b57cec5SDimitry Andric} 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andrictemplate <class _Tp> 846cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator-(const complex<_Tp>& __x) { 8470b57cec5SDimitry Andric return complex<_Tp>(-__x.real(), -__x.imag()); 8480b57cec5SDimitry Andric} 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andrictemplate <class _Tp> 851cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 852cb14a3feSDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8530b57cec5SDimitry Andric return __x.real() == __y.real() && __x.imag() == __y.imag(); 8540b57cec5SDimitry Andric} 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andrictemplate <class _Tp> 857cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const complex<_Tp>& __x, const _Tp& __y) { 8580b57cec5SDimitry Andric return __x.real() == __y && __x.imag() == 0; 8590b57cec5SDimitry Andric} 8600b57cec5SDimitry Andric 86106c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17 86206c3fb27SDimitry Andric 8630b57cec5SDimitry Andrictemplate <class _Tp> 864cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const _Tp& __x, const complex<_Tp>& __y) { 8650b57cec5SDimitry Andric return __x == __y.real() && 0 == __y.imag(); 8660b57cec5SDimitry Andric} 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andrictemplate <class _Tp> 869cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 870cb14a3feSDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) { 8710b57cec5SDimitry Andric return !(__x == __y); 8720b57cec5SDimitry Andric} 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andrictemplate <class _Tp> 875cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const complex<_Tp>& __x, const _Tp& __y) { 8760b57cec5SDimitry Andric return !(__x == __y); 8770b57cec5SDimitry Andric} 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andrictemplate <class _Tp> 880cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const _Tp& __x, const complex<_Tp>& __y) { 8810b57cec5SDimitry Andric return !(__x == __y); 8820b57cec5SDimitry Andric} 8830b57cec5SDimitry Andric 88406c3fb27SDimitry Andric#endif 88506c3fb27SDimitry Andric 8860b57cec5SDimitry Andric// 26.3.7 values: 8870b57cec5SDimitry Andric 888cb14a3feSDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, bool = is_floating_point<_Tp>::value > 8890b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {}; 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric// Integral Types 8920b57cec5SDimitry Andrictemplate <class _Tp> 893cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> { 8940b57cec5SDimitry Andric typedef double _ValueType; 8950b57cec5SDimitry Andric typedef complex<double> _ComplexType; 8960b57cec5SDimitry Andric}; 8970b57cec5SDimitry Andric 8980b57cec5SDimitry Andric// Floating point types 8990b57cec5SDimitry Andrictemplate <class _Tp> 900cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> { 9010b57cec5SDimitry Andric typedef _Tp _ValueType; 9020b57cec5SDimitry Andric typedef complex<_Tp> _ComplexType; 9030b57cec5SDimitry Andric}; 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric// real 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andrictemplate <class _Tp> 908cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) { 9090b57cec5SDimitry Andric return __c.real(); 9100b57cec5SDimitry Andric} 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andrictemplate <class _Tp> 913cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 914cb14a3feSDimitry Andricreal(_Tp __re) { 9150b57cec5SDimitry Andric return __re; 9160b57cec5SDimitry Andric} 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric// imag 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andrictemplate <class _Tp> 921cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) { 9220b57cec5SDimitry Andric return __c.imag(); 9230b57cec5SDimitry Andric} 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andrictemplate <class _Tp> 926cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 927cb14a3feSDimitry Andricimag(_Tp) { 9280b57cec5SDimitry Andric return 0; 9290b57cec5SDimitry Andric} 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric// abs 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andrictemplate <class _Tp> 934cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) { 935bdd1243dSDimitry Andric return std::hypot(__c.real(), __c.imag()); 9360b57cec5SDimitry Andric} 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric// arg 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andrictemplate <class _Tp> 941cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) { 942bdd1243dSDimitry Andric return std::atan2(__c.imag(), __c.real()); 9430b57cec5SDimitry Andric} 9440b57cec5SDimitry Andric 9455f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0> 946cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) { 947bdd1243dSDimitry Andric return std::atan2l(0.L, __re); 9480b57cec5SDimitry Andric} 9490b57cec5SDimitry Andric 9505f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0> 951cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) { 952bdd1243dSDimitry Andric return std::atan2(0., __re); 9530b57cec5SDimitry Andric} 9540b57cec5SDimitry Andric 9555f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0> 956cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) { 957bdd1243dSDimitry Andric return std::atan2f(0.F, __re); 9580b57cec5SDimitry Andric} 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric// norm 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andrictemplate <class _Tp> 963cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) { 964bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real())) 965bdd1243dSDimitry Andric return std::abs(__c.real()); 966bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.imag())) 967bdd1243dSDimitry Andric return std::abs(__c.imag()); 9680b57cec5SDimitry Andric return __c.real() * __c.real() + __c.imag() * __c.imag(); 9690b57cec5SDimitry Andric} 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andrictemplate <class _Tp> 972cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ValueType 973cb14a3feSDimitry Andricnorm(_Tp __re) { 9740b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; 9750b57cec5SDimitry Andric return static_cast<_ValueType>(__re) * __re; 9760b57cec5SDimitry Andric} 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric// conj 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andrictemplate <class _Tp> 981cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> conj(const complex<_Tp>& __c) { 9820b57cec5SDimitry Andric return complex<_Tp>(__c.real(), -__c.imag()); 9830b57cec5SDimitry Andric} 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andrictemplate <class _Tp> 986cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType 987cb14a3feSDimitry Andricconj(_Tp __re) { 9880b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 9890b57cec5SDimitry Andric return _ComplexType(__re); 9900b57cec5SDimitry Andric} 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric// proj 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andrictemplate <class _Tp> 995cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) { 996e8d8bef9SDimitry Andric complex<_Tp> __r = __c; 997bdd1243dSDimitry Andric if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag())) 998bdd1243dSDimitry Andric __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag())); 9990b57cec5SDimitry Andric return __r; 10000b57cec5SDimitry Andric} 10010b57cec5SDimitry Andric 10025f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0> 1003cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 1004bdd1243dSDimitry Andric if (std::__constexpr_isinf(__re)) 1005bdd1243dSDimitry Andric __re = std::abs(__re); 10060b57cec5SDimitry Andric return complex<_Tp>(__re); 10070b57cec5SDimitry Andric} 10080b57cec5SDimitry Andric 10095f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0> 1010cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) { 10110b57cec5SDimitry Andric typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; 10120b57cec5SDimitry Andric return _ComplexType(__re); 10130b57cec5SDimitry Andric} 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric// polar 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andrictemplate <class _Tp> 1018cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) { 1019bdd1243dSDimitry Andric if (std::__constexpr_isnan(__rho) || std::signbit(__rho)) 10200b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 1021cb14a3feSDimitry Andric if (std::__constexpr_isnan(__theta)) { 1022bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10230b57cec5SDimitry Andric return complex<_Tp>(__rho, __theta); 10240b57cec5SDimitry Andric return complex<_Tp>(__theta, __theta); 10250b57cec5SDimitry Andric } 1026cb14a3feSDimitry Andric if (std::__constexpr_isinf(__theta)) { 1027bdd1243dSDimitry Andric if (std::__constexpr_isinf(__rho)) 10280b57cec5SDimitry Andric return complex<_Tp>(__rho, _Tp(NAN)); 10290b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), _Tp(NAN)); 10300b57cec5SDimitry Andric } 1031bdd1243dSDimitry Andric _Tp __x = __rho * std::cos(__theta); 1032bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x)) 10330b57cec5SDimitry Andric __x = 0; 1034bdd1243dSDimitry Andric _Tp __y = __rho * std::sin(__theta); 1035bdd1243dSDimitry Andric if (std::__constexpr_isnan(__y)) 10360b57cec5SDimitry Andric __y = 0; 10370b57cec5SDimitry Andric return complex<_Tp>(__x, __y); 10380b57cec5SDimitry Andric} 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric// log 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andrictemplate <class _Tp> 1043cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) { 1044bdd1243dSDimitry Andric return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x)); 10450b57cec5SDimitry Andric} 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric// log10 10480b57cec5SDimitry Andric 10490b57cec5SDimitry Andrictemplate <class _Tp> 1050cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) { 1051bdd1243dSDimitry Andric return std::log(__x) / std::log(_Tp(10)); 10520b57cec5SDimitry Andric} 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric// sqrt 10550b57cec5SDimitry Andric 10560b57cec5SDimitry Andrictemplate <class _Tp> 1057cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) { 1058bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 10590b57cec5SDimitry Andric return complex<_Tp>(_Tp(INFINITY), __x.imag()); 1060cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 10610b57cec5SDimitry Andric if (__x.real() > _Tp(0)) 1062cb14a3feSDimitry Andric return complex<_Tp>( 1063cb14a3feSDimitry Andric __x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag())); 1064cb14a3feSDimitry Andric return complex<_Tp>( 1065cb14a3feSDimitry Andric std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag())); 10660b57cec5SDimitry Andric } 1067bdd1243dSDimitry Andric return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2)); 10680b57cec5SDimitry Andric} 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric// exp 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andrictemplate <class _Tp> 1073cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) { 10740b57cec5SDimitry Andric _Tp __i = __x.imag(); 1075349cc55cSDimitry Andric if (__i == 0) { 1076bdd1243dSDimitry Andric return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag())); 1077349cc55cSDimitry Andric } 1078cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1079cb14a3feSDimitry Andric if (__x.real() < _Tp(0)) { 1080bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__i)) 10810b57cec5SDimitry Andric __i = _Tp(1); 1082cb14a3feSDimitry Andric } else if (__i == 0 || !std::__constexpr_isfinite(__i)) { 1083bdd1243dSDimitry Andric if (std::__constexpr_isinf(__i)) 10840b57cec5SDimitry Andric __i = _Tp(NAN); 10850b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __i); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric } 1088bdd1243dSDimitry Andric _Tp __e = std::exp(__x.real()); 1089bdd1243dSDimitry Andric return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i)); 10900b57cec5SDimitry Andric} 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric// pow 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andrictemplate <class _Tp> 1095cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { 1096bdd1243dSDimitry Andric return std::exp(__y * std::log(__x)); 10970b57cec5SDimitry Andric} 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 1100cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> 1101cb14a3feSDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) { 11020b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11035f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11040b57cec5SDimitry Andric} 11050b57cec5SDimitry Andric 11065f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0> 1107cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) { 11080b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11095f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11100b57cec5SDimitry Andric} 11110b57cec5SDimitry Andric 11125f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value, int> = 0> 1113cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const _Tp& __x, const complex<_Up>& __y) { 11140b57cec5SDimitry Andric typedef complex<typename __promote<_Tp, _Up>::type> result_type; 11155f757f3fSDimitry Andric return std::pow(result_type(__x), result_type(__y)); 11160b57cec5SDimitry Andric} 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric// __sqr, computes pow(x, 2) 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andrictemplate <class _Tp> 1121cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) { 1122cb14a3feSDimitry Andric return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), _Tp(2) * __x.real() * __x.imag()); 11230b57cec5SDimitry Andric} 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric// asinh 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andrictemplate <class _Tp> 1128cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) { 11290b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1130cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1131bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 11320b57cec5SDimitry Andric return __x; 1133bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1134bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 1135bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11360b57cec5SDimitry Andric } 1137cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1138bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 11390b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 11400b57cec5SDimitry Andric if (__x.imag() == 0) 11410b57cec5SDimitry Andric return __x; 11420b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11430b57cec5SDimitry Andric } 1144bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1145bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 1146bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1))); 1147bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 11480b57cec5SDimitry Andric} 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric// acosh 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andrictemplate <class _Tp> 1153cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) { 11540b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1155cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1156bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 1157bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1158cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 11590b57cec5SDimitry Andric if (__x.real() > 0) 1160bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag())); 11610b57cec5SDimitry Andric else 1162bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag())); 11630b57cec5SDimitry Andric } 11640b57cec5SDimitry Andric if (__x.real() < 0) 1165bdd1243dSDimitry Andric return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag())); 1166bdd1243dSDimitry Andric return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag())); 11670b57cec5SDimitry Andric } 1168cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1169bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1170bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), __x.real()); 11710b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11720b57cec5SDimitry Andric } 1173bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 1174bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag())); 1175bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1176bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag())); 11770b57cec5SDimitry Andric} 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andric// atanh 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andrictemplate <class _Tp> 1182cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) { 11830b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1184cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 1185bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 11860b57cec5SDimitry Andric } 1187cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.imag())) { 1188bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) || __x.real() == 0) 1189bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag()); 11900b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.imag()); 11910b57cec5SDimitry Andric } 1192cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 11930b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 11940b57cec5SDimitry Andric } 1195cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1196bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag())); 11970b57cec5SDimitry Andric } 1198cb14a3feSDimitry Andric if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) { 1199bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag())); 12000b57cec5SDimitry Andric } 1201bdd1243dSDimitry Andric complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2); 1202bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag())); 12030b57cec5SDimitry Andric} 12040b57cec5SDimitry Andric 12050b57cec5SDimitry Andric// sinh 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andrictemplate <class _Tp> 1208cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) { 1209bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 12100b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1211bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 12120b57cec5SDimitry Andric return complex<_Tp>(__x.real(), _Tp(NAN)); 1213bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 12140b57cec5SDimitry Andric return __x; 1215bdd1243dSDimitry Andric return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag())); 12160b57cec5SDimitry Andric} 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric// cosh 12190b57cec5SDimitry Andric 12200b57cec5SDimitry Andrictemplate <class _Tp> 1221cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) { 1222bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag())) 1223bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), _Tp(NAN)); 1224bdd1243dSDimitry Andric if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag())) 12250b57cec5SDimitry Andric return complex<_Tp>(_Tp(NAN), __x.real()); 12260b57cec5SDimitry Andric if (__x.real() == 0 && __x.imag() == 0) 12270b57cec5SDimitry Andric return complex<_Tp>(_Tp(1), __x.imag()); 1228bdd1243dSDimitry Andric if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real())) 1229bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__x.real()), __x.imag()); 1230bdd1243dSDimitry Andric return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag())); 12310b57cec5SDimitry Andric} 12320b57cec5SDimitry Andric 12330b57cec5SDimitry Andric// tanh 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andrictemplate <class _Tp> 1236cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) { 1237cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1238bdd1243dSDimitry Andric if (!std::__constexpr_isfinite(__x.imag())) 1239bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0)); 1240bdd1243dSDimitry Andric return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag()))); 12410b57cec5SDimitry Andric } 1242bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0) 12430b57cec5SDimitry Andric return __x; 12440b57cec5SDimitry Andric _Tp __2r(_Tp(2) * __x.real()); 12450b57cec5SDimitry Andric _Tp __2i(_Tp(2) * __x.imag()); 1246bdd1243dSDimitry Andric _Tp __d(std::cosh(__2r) + std::cos(__2i)); 1247bdd1243dSDimitry Andric _Tp __2rsh(std::sinh(__2r)); 1248bdd1243dSDimitry Andric if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d)) 1249cb14a3feSDimitry Andric return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); 1250bdd1243dSDimitry Andric return complex<_Tp>(__2rsh / __d, std::sin(__2i) / __d); 12510b57cec5SDimitry Andric} 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric// asin 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andrictemplate <class _Tp> 1256cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) { 1257bdd1243dSDimitry Andric complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real())); 12580b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12590b57cec5SDimitry Andric} 12600b57cec5SDimitry Andric 12610b57cec5SDimitry Andric// acos 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andrictemplate <class _Tp> 1264cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) { 12650b57cec5SDimitry Andric const _Tp __pi(atan2(+0., -0.)); 1266cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.real())) { 1267bdd1243dSDimitry Andric if (std::__constexpr_isnan(__x.imag())) 12680b57cec5SDimitry Andric return complex<_Tp>(__x.imag(), __x.real()); 1269cb14a3feSDimitry Andric if (std::__constexpr_isinf(__x.imag())) { 12700b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 12710b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); 12720b57cec5SDimitry Andric return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag()); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric if (__x.real() < _Tp(0)) 1275bdd1243dSDimitry Andric return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real()); 1276bdd1243dSDimitry Andric return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real()); 12770b57cec5SDimitry Andric } 1278cb14a3feSDimitry Andric if (std::__constexpr_isnan(__x.real())) { 1279bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12800b57cec5SDimitry Andric return complex<_Tp>(__x.real(), -__x.imag()); 12810b57cec5SDimitry Andric return complex<_Tp>(__x.real(), __x.real()); 12820b57cec5SDimitry Andric } 1283bdd1243dSDimitry Andric if (std::__constexpr_isinf(__x.imag())) 12840b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1285bdd1243dSDimitry Andric if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag()))) 12860b57cec5SDimitry Andric return complex<_Tp>(__pi / _Tp(2), -__x.imag()); 1287bdd1243dSDimitry Andric complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1))); 1288bdd1243dSDimitry Andric if (std::signbit(__x.imag())) 1289bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real())); 1290bdd1243dSDimitry Andric return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real())); 12910b57cec5SDimitry Andric} 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric// atan 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andrictemplate <class _Tp> 1296cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) { 1297bdd1243dSDimitry Andric complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real())); 12980b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 12990b57cec5SDimitry Andric} 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric// sin 13020b57cec5SDimitry Andric 13030b57cec5SDimitry Andrictemplate <class _Tp> 1304cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) { 1305bdd1243dSDimitry Andric complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real())); 13060b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13070b57cec5SDimitry Andric} 13080b57cec5SDimitry Andric 13090b57cec5SDimitry Andric// cos 13100b57cec5SDimitry Andric 13110b57cec5SDimitry Andrictemplate <class _Tp> 1312cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) { 1313bdd1243dSDimitry Andric return std::cosh(complex<_Tp>(-__x.imag(), __x.real())); 13140b57cec5SDimitry Andric} 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric// tan 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andrictemplate <class _Tp> 1319cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) { 1320bdd1243dSDimitry Andric complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real())); 13210b57cec5SDimitry Andric return complex<_Tp>(__z.imag(), -__z.real()); 13220b57cec5SDimitry Andric} 13230b57cec5SDimitry Andric 1324bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) 13250b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1326bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 1327cb14a3feSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) { 1328cb14a3feSDimitry Andric if (__is.good()) { 1329bdd1243dSDimitry Andric std::ws(__is); 1330cb14a3feSDimitry Andric if (__is.peek() == _CharT('(')) { 13310b57cec5SDimitry Andric __is.get(); 13320b57cec5SDimitry Andric _Tp __r; 13330b57cec5SDimitry Andric __is >> __r; 1334cb14a3feSDimitry Andric if (!__is.fail()) { 1335bdd1243dSDimitry Andric std::ws(__is); 13360b57cec5SDimitry Andric _CharT __c = __is.peek(); 1337cb14a3feSDimitry Andric if (__c == _CharT(',')) { 13380b57cec5SDimitry Andric __is.get(); 13390b57cec5SDimitry Andric _Tp __i; 13400b57cec5SDimitry Andric __is >> __i; 1341cb14a3feSDimitry Andric if (!__is.fail()) { 1342bdd1243dSDimitry Andric std::ws(__is); 13430b57cec5SDimitry Andric __c = __is.peek(); 1344cb14a3feSDimitry Andric if (__c == _CharT(')')) { 13450b57cec5SDimitry Andric __is.get(); 13460b57cec5SDimitry Andric __x = complex<_Tp>(__r, __i); 1347cb14a3feSDimitry Andric } else 13485ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1349cb14a3feSDimitry Andric } else 13505ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1351cb14a3feSDimitry Andric } else if (__c == _CharT(')')) { 13520b57cec5SDimitry Andric __is.get(); 13530b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 1354cb14a3feSDimitry Andric } else 13555ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1356cb14a3feSDimitry Andric } else 13575ffd83dbSDimitry Andric __is.setstate(__is.failbit); 1358cb14a3feSDimitry Andric } else { 13590b57cec5SDimitry Andric _Tp __r; 13600b57cec5SDimitry Andric __is >> __r; 13610b57cec5SDimitry Andric if (!__is.fail()) 13620b57cec5SDimitry Andric __x = complex<_Tp>(__r, _Tp(0)); 13630b57cec5SDimitry Andric else 13645ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13650b57cec5SDimitry Andric } 1366cb14a3feSDimitry Andric } else 13675ffd83dbSDimitry Andric __is.setstate(__is.failbit); 13680b57cec5SDimitry Andric return __is; 13690b57cec5SDimitry Andric} 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits> 1372bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 1373cb14a3feSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) { 13740b57cec5SDimitry Andric basic_ostringstream<_CharT, _Traits> __s; 13750b57cec5SDimitry Andric __s.flags(__os.flags()); 13760b57cec5SDimitry Andric __s.imbue(__os.getloc()); 13770b57cec5SDimitry Andric __s.precision(__os.precision()); 13780b57cec5SDimitry Andric __s << '(' << __x.real() << ',' << __x.imag() << ')'; 13790b57cec5SDimitry Andric return __os << __s.str(); 13800b57cec5SDimitry Andric} 1381e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION 13820b57cec5SDimitry Andric 1383*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26 1384*0fca6ea1SDimitry Andric 1385*0fca6ea1SDimitry Andric// [complex.tuple], tuple interface 1386*0fca6ea1SDimitry Andric 1387*0fca6ea1SDimitry Andrictemplate <class _Tp> 1388*0fca6ea1SDimitry Andricstruct tuple_size<complex<_Tp>> : integral_constant<size_t, 2> {}; 1389*0fca6ea1SDimitry Andric 1390*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Tp> 1391*0fca6ea1SDimitry Andricstruct tuple_element<_Ip, complex<_Tp>> { 1392*0fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 1393*0fca6ea1SDimitry Andric using type = _Tp; 1394*0fca6ea1SDimitry Andric}; 1395*0fca6ea1SDimitry Andric 1396*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 1397*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept { 1398*0fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 1399*0fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 1400*0fca6ea1SDimitry Andric return __z.__re_; 1401*0fca6ea1SDimitry Andric } else { 1402*0fca6ea1SDimitry Andric return __z.__im_; 1403*0fca6ea1SDimitry Andric } 1404*0fca6ea1SDimitry Andric} 1405*0fca6ea1SDimitry Andric 1406*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 1407*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept { 1408*0fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 1409*0fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 1410*0fca6ea1SDimitry Andric return std::move(__z.__re_); 1411*0fca6ea1SDimitry Andric } else { 1412*0fca6ea1SDimitry Andric return std::move(__z.__im_); 1413*0fca6ea1SDimitry Andric } 1414*0fca6ea1SDimitry Andric} 1415*0fca6ea1SDimitry Andric 1416*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 1417*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept { 1418*0fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 1419*0fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 1420*0fca6ea1SDimitry Andric return __z.__re_; 1421*0fca6ea1SDimitry Andric } else { 1422*0fca6ea1SDimitry Andric return __z.__im_; 1423*0fca6ea1SDimitry Andric } 1424*0fca6ea1SDimitry Andric} 1425*0fca6ea1SDimitry Andric 1426*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp> 1427*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept { 1428*0fca6ea1SDimitry Andric static_assert(_Ip < 2, "Index value is out of range."); 1429*0fca6ea1SDimitry Andric if constexpr (_Ip == 0) { 1430*0fca6ea1SDimitry Andric return std::move(__z.__re_); 1431*0fca6ea1SDimitry Andric } else { 1432*0fca6ea1SDimitry Andric return std::move(__z.__im_); 1433*0fca6ea1SDimitry Andric } 1434*0fca6ea1SDimitry Andric} 1435*0fca6ea1SDimitry Andric 1436*0fca6ea1SDimitry Andric#endif // _LIBCPP_STD_VER >= 26 1437*0fca6ea1SDimitry Andric 143806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 14390b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals] 1440cb14a3feSDimitry Andricinline namespace literals { 1441cb14a3feSDimitry Andricinline namespace complex_literals { 1442cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(long double __im) { return {0.0l, __im}; } 14430b57cec5SDimitry Andric 1444cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(unsigned long long __im) { 14450b57cec5SDimitry Andric return {0.0l, static_cast<long double>(__im)}; 14460b57cec5SDimitry Andric} 14470b57cec5SDimitry Andric 1448cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(long double __im) { 14490b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 14500b57cec5SDimitry Andric} 14510b57cec5SDimitry Andric 1452cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(unsigned long long __im) { 14530b57cec5SDimitry Andric return {0.0, static_cast<double>(__im)}; 14540b57cec5SDimitry Andric} 14550b57cec5SDimitry Andric 1456cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(long double __im) { 14570b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 14580b57cec5SDimitry Andric} 14590b57cec5SDimitry Andric 1460cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long long __im) { 14610b57cec5SDimitry Andric return {0.0f, static_cast<float>(__im)}; 14620b57cec5SDimitry Andric} 14630eae32dcSDimitry Andric} // namespace complex_literals 14640eae32dcSDimitry Andric} // namespace literals 14650b57cec5SDimitry Andric#endif 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 14680b57cec5SDimitry Andric 1469*0fca6ea1SDimitry Andric_LIBCPP_POP_MACROS 1470*0fca6ea1SDimitry Andric 147106c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 14725f757f3fSDimitry Andric# include <iosfwd> 14735f757f3fSDimitry Andric# include <stdexcept> 147406c3fb27SDimitry Andric# include <type_traits> 147506c3fb27SDimitry Andric#endif 147606c3fb27SDimitry Andric 14770b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX 1478