xref: /freebsd/contrib/llvm-project/libcxx/include/complex (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
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