xref: /freebsd/contrib/llvm-project/libcxx/include/complex (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_COMPLEX
110b57cec5SDimitry Andric#define _LIBCPP_COMPLEX
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    complex synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andrictemplate<class T>
200b57cec5SDimitry Andricclass complex
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andricpublic:
230b57cec5SDimitry Andric    typedef T value_type;
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
260b57cec5SDimitry Andric    complex(const complex&);  // constexpr in C++14
270b57cec5SDimitry Andric    template<class X> complex(const complex<X>&);  // constexpr in C++14
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric    T real() const; // constexpr in C++14
300b57cec5SDimitry Andric    T imag() const; // constexpr in C++14
310b57cec5SDimitry Andric
32bdd1243dSDimitry Andric    void real(T); // constexpr in C++20
33bdd1243dSDimitry Andric    void imag(T); // constexpr in C++20
340b57cec5SDimitry Andric
35bdd1243dSDimitry Andric    complex<T>& operator= (const T&); // constexpr in C++20
36bdd1243dSDimitry Andric    complex<T>& operator+=(const T&); // constexpr in C++20
37bdd1243dSDimitry Andric    complex<T>& operator-=(const T&); // constexpr in C++20
38bdd1243dSDimitry Andric    complex<T>& operator*=(const T&); // constexpr in C++20
39bdd1243dSDimitry Andric    complex<T>& operator/=(const T&); // constexpr in C++20
400b57cec5SDimitry Andric
41bdd1243dSDimitry Andric    complex& operator=(const complex&); // constexpr in C++20
42bdd1243dSDimitry Andric    template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20
43bdd1243dSDimitry Andric    template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20
44bdd1243dSDimitry Andric    template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20
45bdd1243dSDimitry Andric    template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20
46bdd1243dSDimitry Andric    template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++20
470b57cec5SDimitry Andric};
480b57cec5SDimitry Andric
490b57cec5SDimitry Andrictemplate<>
500b57cec5SDimitry Andricclass complex<float>
510b57cec5SDimitry Andric{
520b57cec5SDimitry Andricpublic:
530b57cec5SDimitry Andric    typedef float value_type;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric    constexpr complex(float re = 0.0f, float im = 0.0f);
560b57cec5SDimitry Andric    explicit constexpr complex(const complex<double>&);
570b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric    constexpr float real() const;
60bdd1243dSDimitry Andric    void real(float); // constexpr in C++20
610b57cec5SDimitry Andric    constexpr float imag() const;
62bdd1243dSDimitry Andric    void imag(float); // constexpr in C++20
630b57cec5SDimitry Andric
64bdd1243dSDimitry Andric    complex<float>& operator= (float); // constexpr in C++20
65bdd1243dSDimitry Andric    complex<float>& operator+=(float); // constexpr in C++20
66bdd1243dSDimitry Andric    complex<float>& operator-=(float); // constexpr in C++20
67bdd1243dSDimitry Andric    complex<float>& operator*=(float); // constexpr in C++20
68bdd1243dSDimitry Andric    complex<float>& operator/=(float); // constexpr in C++20
690b57cec5SDimitry Andric
70bdd1243dSDimitry Andric    complex<float>& operator=(const complex<float>&); // constexpr in C++20
71bdd1243dSDimitry Andric    template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20
72bdd1243dSDimitry Andric    template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20
73bdd1243dSDimitry Andric    template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20
74bdd1243dSDimitry Andric    template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20
75bdd1243dSDimitry Andric    template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++20
760b57cec5SDimitry Andric};
770b57cec5SDimitry Andric
780b57cec5SDimitry Andrictemplate<>
790b57cec5SDimitry Andricclass complex<double>
800b57cec5SDimitry Andric{
810b57cec5SDimitry Andricpublic:
820b57cec5SDimitry Andric    typedef double value_type;
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    constexpr complex(double re = 0.0, double im = 0.0);
850b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
860b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    constexpr double real() const;
89bdd1243dSDimitry Andric    void real(double); // constexpr in C++20
900b57cec5SDimitry Andric    constexpr double imag() const;
91bdd1243dSDimitry Andric    void imag(double); // constexpr in C++20
920b57cec5SDimitry Andric
93bdd1243dSDimitry Andric    complex<double>& operator= (double); // constexpr in C++20
94bdd1243dSDimitry Andric    complex<double>& operator+=(double); // constexpr in C++20
95bdd1243dSDimitry Andric    complex<double>& operator-=(double); // constexpr in C++20
96bdd1243dSDimitry Andric    complex<double>& operator*=(double); // constexpr in C++20
97bdd1243dSDimitry Andric    complex<double>& operator/=(double); // constexpr in C++20
98bdd1243dSDimitry Andric    complex<double>& operator=(const complex<double>&); // constexpr in C++20
990b57cec5SDimitry Andric
100bdd1243dSDimitry Andric    template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20
101bdd1243dSDimitry Andric    template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20
102bdd1243dSDimitry Andric    template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20
103bdd1243dSDimitry Andric    template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20
104bdd1243dSDimitry Andric    template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20
1050b57cec5SDimitry Andric};
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andrictemplate<>
1080b57cec5SDimitry Andricclass complex<long double>
1090b57cec5SDimitry Andric{
1100b57cec5SDimitry Andricpublic:
1110b57cec5SDimitry Andric    typedef long double value_type;
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric    constexpr complex(long double re = 0.0L, long double im = 0.0L);
1140b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
1150b57cec5SDimitry Andric    constexpr complex(const complex<double>&);
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric    constexpr long double real() const;
118bdd1243dSDimitry Andric    void real(long double); // constexpr in C++20
1190b57cec5SDimitry Andric    constexpr long double imag() const;
120bdd1243dSDimitry Andric    void imag(long double); // constexpr in C++20
1210b57cec5SDimitry Andric
122bdd1243dSDimitry Andric    complex<long double>& operator=(const complex<long double>&); // constexpr in C++20
123bdd1243dSDimitry Andric    complex<long double>& operator= (long double); // constexpr in C++20
124bdd1243dSDimitry Andric    complex<long double>& operator+=(long double); // constexpr in C++20
125bdd1243dSDimitry Andric    complex<long double>& operator-=(long double); // constexpr in C++20
126bdd1243dSDimitry Andric    complex<long double>& operator*=(long double); // constexpr in C++20
127bdd1243dSDimitry Andric    complex<long double>& operator/=(long double); // constexpr in C++20
1280b57cec5SDimitry Andric
129bdd1243dSDimitry Andric    template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20
130bdd1243dSDimitry Andric    template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20
131bdd1243dSDimitry Andric    template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20
132bdd1243dSDimitry Andric    template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20
133bdd1243dSDimitry Andric    template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20
1340b57cec5SDimitry Andric};
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric// 26.3.6 operators:
137bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20
138bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const T&);          // constexpr in C++20
139bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const T&, const complex<T>&);          // constexpr in C++20
140bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20
141bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const T&);          // constexpr in C++20
142bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const T&, const complex<T>&);          // constexpr in C++20
143bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20
144bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const T&);          // constexpr in C++20
145bdd1243dSDimitry Andrictemplate<class T> complex<T> operator*(const T&, const complex<T>&);          // constexpr in C++20
146bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20
147bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const T&);          // constexpr in C++20
148bdd1243dSDimitry Andrictemplate<class T> complex<T> operator/(const T&, const complex<T>&);          // constexpr in C++20
149bdd1243dSDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&);                    // constexpr in C++20
150bdd1243dSDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&);                    // constexpr in C++20
1510b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const complex<T>&);      // constexpr in C++14
1520b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const T&);               // constexpr in C++14
15306c3fb27SDimitry Andrictemplate<class T> bool operator==(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20
15406c3fb27SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const complex<T>&);      // constexpr in C++14, removed in C++20
15506c3fb27SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const T&);               // constexpr in C++14, removed in C++20
15606c3fb27SDimitry Andrictemplate<class T> bool operator!=(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
1590b57cec5SDimitry Andric  basic_istream<charT, traits>&
1600b57cec5SDimitry Andric  operator>>(basic_istream<charT, traits>&, complex<T>&);
1610b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
1620b57cec5SDimitry Andric  basic_ostream<charT, traits>&
1630b57cec5SDimitry Andric  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric// 26.3.7 values:
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andrictemplate<class T>              T real(const complex<T>&); // constexpr in C++14
1680b57cec5SDimitry Andric                     long double real(long double);       // constexpr in C++14
1690b57cec5SDimitry Andric                          double real(double);            // constexpr in C++14
1700b57cec5SDimitry Andrictemplate<Integral T>      double real(T);                 // constexpr in C++14
1710b57cec5SDimitry Andric                          float  real(float);             // constexpr in C++14
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andrictemplate<class T>              T imag(const complex<T>&); // constexpr in C++14
1740b57cec5SDimitry Andric                     long double imag(long double);       // constexpr in C++14
1750b57cec5SDimitry Andric                          double imag(double);            // constexpr in C++14
1760b57cec5SDimitry Andrictemplate<Integral T>      double imag(T);                 // constexpr in C++14
1770b57cec5SDimitry Andric                          float  imag(float);             // constexpr in C++14
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andrictemplate<class T> T abs(const complex<T>&);
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andrictemplate<class T>              T arg(const complex<T>&);
1820b57cec5SDimitry Andric                     long double arg(long double);
1830b57cec5SDimitry Andric                          double arg(double);
1840b57cec5SDimitry Andrictemplate<Integral T>      double arg(T);
1850b57cec5SDimitry Andric                          float  arg(float);
1860b57cec5SDimitry Andric
187bdd1243dSDimitry Andrictemplate<class T>              T norm(const complex<T>&); // constexpr in C++20
188bdd1243dSDimitry Andric                     long double norm(long double);       // constexpr in C++20
189bdd1243dSDimitry Andric                          double norm(double);            // constexpr in C++20
190bdd1243dSDimitry Andrictemplate<Integral T>      double norm(T);                 // constexpr in C++20
191bdd1243dSDimitry Andric                          float  norm(float);             // constexpr in C++20
1920b57cec5SDimitry Andric
193bdd1243dSDimitry Andrictemplate<class T>      complex<T>           conj(const complex<T>&); // constexpr in C++20
194bdd1243dSDimitry Andric                       complex<long double> conj(long double);       // constexpr in C++20
195bdd1243dSDimitry Andric                       complex<double>      conj(double);            // constexpr in C++20
196bdd1243dSDimitry Andrictemplate<Integral T>   complex<double>      conj(T);                 // constexpr in C++20
197bdd1243dSDimitry Andric                       complex<float>       conj(float);             // constexpr in C++20
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andrictemplate<class T>    complex<T>           proj(const complex<T>&);
2000b57cec5SDimitry Andric                     complex<long double> proj(long double);
2010b57cec5SDimitry Andric                     complex<double>      proj(double);
2020b57cec5SDimitry Andrictemplate<Integral T> complex<double>      proj(T);
2030b57cec5SDimitry Andric                     complex<float>       proj(float);
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andrictemplate<class T> complex<T> polar(const T&, const T& = T());
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andric// 26.3.8 transcendentals:
2080b57cec5SDimitry Andrictemplate<class T> complex<T> acos(const complex<T>&);
2090b57cec5SDimitry Andrictemplate<class T> complex<T> asin(const complex<T>&);
2100b57cec5SDimitry Andrictemplate<class T> complex<T> atan(const complex<T>&);
2110b57cec5SDimitry Andrictemplate<class T> complex<T> acosh(const complex<T>&);
2120b57cec5SDimitry Andrictemplate<class T> complex<T> asinh(const complex<T>&);
2130b57cec5SDimitry Andrictemplate<class T> complex<T> atanh(const complex<T>&);
2140b57cec5SDimitry Andrictemplate<class T> complex<T> cos (const complex<T>&);
2150b57cec5SDimitry Andrictemplate<class T> complex<T> cosh (const complex<T>&);
2160b57cec5SDimitry Andrictemplate<class T> complex<T> exp (const complex<T>&);
2170b57cec5SDimitry Andrictemplate<class T> complex<T> log (const complex<T>&);
2180b57cec5SDimitry Andrictemplate<class T> complex<T> log10(const complex<T>&);
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const T&);
2210b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);
2220b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const T&, const complex<T>&);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andrictemplate<class T> complex<T> sin (const complex<T>&);
2250b57cec5SDimitry Andrictemplate<class T> complex<T> sinh (const complex<T>&);
2260b57cec5SDimitry Andrictemplate<class T> complex<T> sqrt (const complex<T>&);
2270b57cec5SDimitry Andrictemplate<class T> complex<T> tan (const complex<T>&);
2280b57cec5SDimitry Andrictemplate<class T> complex<T> tanh (const complex<T>&);
2290b57cec5SDimitry Andric
230*0fca6ea1SDimitry Andric  // [complex.tuple], tuple interface
231*0fca6ea1SDimitry Andric  template<class T> struct tuple_size;                               // Since C++26
232*0fca6ea1SDimitry Andric  template<size_t I, class T> struct tuple_element;                  // Since C++26
233*0fca6ea1SDimitry Andric  template<class T> struct tuple_size<complex<T>>;                   // Since C++26
234*0fca6ea1SDimitry Andric  template<size_t I, class T> struct tuple_element<I, complex<T>>;   // Since C++26
235*0fca6ea1SDimitry Andric  template<size_t I, class T>
236*0fca6ea1SDimitry Andric    constexpr T& get(complex<T>&) noexcept;                          // Since C++26
237*0fca6ea1SDimitry Andric  template<size_t I, class T>
238*0fca6ea1SDimitry Andric    constexpr T&& get(complex<T>&&) noexcept;                        // Since C++26
239*0fca6ea1SDimitry Andric  template<size_t I, class T>
240*0fca6ea1SDimitry Andric    constexpr const T& get(const complex<T>&) noexcept;              // Since C++26
241*0fca6ea1SDimitry Andric  template<size_t I, class T>
242*0fca6ea1SDimitry Andric    constexpr const T&& get(const complex<T>&&) noexcept;            // Since C++26
243*0fca6ea1SDimitry Andric
244*0fca6ea1SDimitry Andric  // [complex.literals], complex literals
245*0fca6ea1SDimitry Andric  inline namespace literals {
246*0fca6ea1SDimitry Andric  inline namespace complex_literals {
247*0fca6ea1SDimitry Andric    constexpr complex<long double> operator""il(long double);        // Since C++14
248*0fca6ea1SDimitry Andric    constexpr complex<long double> operator""il(unsigned long long); // Since C++14
249*0fca6ea1SDimitry Andric    constexpr complex<double> operator""i(long double);              // Since C++14
250*0fca6ea1SDimitry Andric    constexpr complex<double> operator""i(unsigned long long);       // Since C++14
251*0fca6ea1SDimitry Andric    constexpr complex<float> operator""if(long double);              // Since C++14
252*0fca6ea1SDimitry Andric    constexpr complex<float> operator""if(unsigned long long);       // Since C++14
253*0fca6ea1SDimitry Andric  }
254*0fca6ea1SDimitry Andric  }
2550b57cec5SDimitry Andric}  // std
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric*/
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric#include <__config>
260*0fca6ea1SDimitry Andric#include <__fwd/complex.h>
261*0fca6ea1SDimitry Andric#include <__fwd/tuple.h>
262*0fca6ea1SDimitry Andric#include <__tuple/tuple_element.h>
263*0fca6ea1SDimitry Andric#include <__tuple/tuple_size.h>
264*0fca6ea1SDimitry Andric#include <__type_traits/conditional.h>
265*0fca6ea1SDimitry Andric#include <__utility/move.h>
2660b57cec5SDimitry Andric#include <cmath>
2670b57cec5SDimitry Andric#include <version>
2680b57cec5SDimitry Andric
269e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
270e8d8bef9SDimitry Andric#  include <sstream> // for std::basic_ostringstream
271e8d8bef9SDimitry Andric#endif
272e8d8bef9SDimitry Andric
2730b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2740b57cec5SDimitry Andric#  pragma GCC system_header
2750b57cec5SDimitry Andric#endif
2760b57cec5SDimitry Andric
277*0fca6ea1SDimitry Andric_LIBCPP_PUSH_MACROS
278*0fca6ea1SDimitry Andric#include <__undef_macros>
279*0fca6ea1SDimitry Andric
2800b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2810b57cec5SDimitry Andric
282cb14a3feSDimitry Andrictemplate <class _Tp>
283cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex;
2840b57cec5SDimitry Andric
285*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
286cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
287cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
288*0fca6ea1SDimitry Andric
289*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
290*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
291*0fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
292*0fca6ea1SDimitry Andric
293*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
294*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
295*0fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
296*0fca6ea1SDimitry Andric
297*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
298cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
299cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
300cb14a3feSDimitry Andric
301cb14a3feSDimitry Andrictemplate <class _Tp>
302cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex {
3030b57cec5SDimitry Andricpublic:
3040b57cec5SDimitry Andric  typedef _Tp value_type;
305cb14a3feSDimitry Andric
3060b57cec5SDimitry Andricprivate:
3070b57cec5SDimitry Andric  value_type __re_;
3080b57cec5SDimitry Andric  value_type __im_;
309cb14a3feSDimitry Andric
3100b57cec5SDimitry Andricpublic:
3115f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
3120b57cec5SDimitry Andric  complex(const value_type& __re = value_type(), const value_type& __im = value_type())
3130b57cec5SDimitry Andric      : __re_(__re), __im_(__im) {}
314cb14a3feSDimitry Andric  template <class _Xp>
315cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 complex(const complex<_Xp>& __c)
3160b57cec5SDimitry Andric      : __re_(__c.real()), __im_(__c.imag()) {}
3170b57cec5SDimitry Andric
3185f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type real() const { return __re_; }
3195f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 value_type imag() const { return __im_; }
3200b57cec5SDimitry Andric
3215f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
3225f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
3230b57cec5SDimitry Andric
324cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const value_type& __re) {
325cb14a3feSDimitry Andric    __re_ = __re;
326cb14a3feSDimitry Andric    __im_ = value_type();
327cb14a3feSDimitry Andric    return *this;
328cb14a3feSDimitry Andric  }
329cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const value_type& __re) {
330cb14a3feSDimitry Andric    __re_ += __re;
331cb14a3feSDimitry Andric    return *this;
332cb14a3feSDimitry Andric  }
333cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const value_type& __re) {
334cb14a3feSDimitry Andric    __re_ -= __re;
335cb14a3feSDimitry Andric    return *this;
336cb14a3feSDimitry Andric  }
337cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const value_type& __re) {
338cb14a3feSDimitry Andric    __re_ *= __re;
339cb14a3feSDimitry Andric    __im_ *= __re;
340cb14a3feSDimitry Andric    return *this;
341cb14a3feSDimitry Andric  }
342cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const value_type& __re) {
343cb14a3feSDimitry Andric    __re_ /= __re;
344cb14a3feSDimitry Andric    __im_ /= __re;
345cb14a3feSDimitry Andric    return *this;
346cb14a3feSDimitry Andric  }
3470b57cec5SDimitry Andric
348cb14a3feSDimitry Andric  template <class _Xp>
349cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) {
3500b57cec5SDimitry Andric    __re_ = __c.real();
3510b57cec5SDimitry Andric    __im_ = __c.imag();
3520b57cec5SDimitry Andric    return *this;
3530b57cec5SDimitry Andric  }
354cb14a3feSDimitry Andric  template <class _Xp>
355cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) {
3560b57cec5SDimitry Andric    __re_ += __c.real();
3570b57cec5SDimitry Andric    __im_ += __c.imag();
3580b57cec5SDimitry Andric    return *this;
3590b57cec5SDimitry Andric  }
360cb14a3feSDimitry Andric  template <class _Xp>
361cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) {
3620b57cec5SDimitry Andric    __re_ -= __c.real();
3630b57cec5SDimitry Andric    __im_ -= __c.imag();
3640b57cec5SDimitry Andric    return *this;
3650b57cec5SDimitry Andric  }
366cb14a3feSDimitry Andric  template <class _Xp>
367cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) {
3680b57cec5SDimitry Andric    *this = *this * complex(__c.real(), __c.imag());
3690b57cec5SDimitry Andric    return *this;
3700b57cec5SDimitry Andric  }
371cb14a3feSDimitry Andric  template <class _Xp>
372cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) {
3730b57cec5SDimitry Andric    *this = *this / complex(__c.real(), __c.imag());
3740b57cec5SDimitry Andric    return *this;
3750b57cec5SDimitry Andric  }
376*0fca6ea1SDimitry Andric
377*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26
378*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
379*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept;
380*0fca6ea1SDimitry Andric
381*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
382*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept;
383*0fca6ea1SDimitry Andric
384*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
385*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept;
386*0fca6ea1SDimitry Andric
387*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
388*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept;
389*0fca6ea1SDimitry Andric#endif
3900b57cec5SDimitry Andric};
3910b57cec5SDimitry Andric
392cb14a3feSDimitry Andrictemplate <>
393cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double>;
394cb14a3feSDimitry Andrictemplate <>
395cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double>;
3960b57cec5SDimitry Andric
397*0fca6ea1SDimitry Andricstruct __from_builtin_tag {};
398*0fca6ea1SDimitry Andric
399*0fca6ea1SDimitry Andrictemplate <class _Tp>
400*0fca6ea1SDimitry Andricusing __complex_t =
401*0fca6ea1SDimitry Andric    __conditional_t<is_same<_Tp, float>::value,
402*0fca6ea1SDimitry Andric                    _Complex float,
403*0fca6ea1SDimitry Andric                    __conditional_t<is_same<_Tp, double>::value, _Complex double, _Complex long double> >;
404*0fca6ea1SDimitry Andric
405*0fca6ea1SDimitry Andrictemplate <class _Tp>
406*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __complex_t<_Tp> __make_complex(_Tp __re, _Tp __im) {
407*0fca6ea1SDimitry Andric#if __has_builtin(__builtin_complex)
408*0fca6ea1SDimitry Andric  return __builtin_complex(__re, __im);
409*0fca6ea1SDimitry Andric#else
410*0fca6ea1SDimitry Andric  return __complex_t<_Tp>{__re, __im};
411*0fca6ea1SDimitry Andric#endif
412*0fca6ea1SDimitry Andric}
413*0fca6ea1SDimitry Andric
4140b57cec5SDimitry Andrictemplate <>
415cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float> {
4160b57cec5SDimitry Andric  float __re_;
4170b57cec5SDimitry Andric  float __im_;
418cb14a3feSDimitry Andric
4190b57cec5SDimitry Andricpublic:
4200b57cec5SDimitry Andric  typedef float value_type;
4210b57cec5SDimitry Andric
422cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {}
423*0fca6ea1SDimitry Andric
424*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex float __v)
425*0fca6ea1SDimitry Andric      : __re_(__real__ __v), __im_(__imag__ __v) {}
426*0fca6ea1SDimitry Andric
427cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
428cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
4290b57cec5SDimitry Andric
4305f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float real() const { return __re_; }
4315f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR float imag() const { return __im_; }
4320b57cec5SDimitry Andric
4335f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
4345f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
4350b57cec5SDimitry Andric
436*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex float __builtin() const { return std::__make_complex(__re_, __im_); }
437*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex float __f) {
438*0fca6ea1SDimitry Andric    __re_ = __real__ __f;
439*0fca6ea1SDimitry Andric    __im_ = __imag__ __f;
440*0fca6ea1SDimitry Andric  }
441*0fca6ea1SDimitry Andric
442cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(float __re) {
443cb14a3feSDimitry Andric    __re_ = __re;
444cb14a3feSDimitry Andric    __im_ = value_type();
445cb14a3feSDimitry Andric    return *this;
446cb14a3feSDimitry Andric  }
447cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(float __re) {
448cb14a3feSDimitry Andric    __re_ += __re;
449cb14a3feSDimitry Andric    return *this;
450cb14a3feSDimitry Andric  }
451cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(float __re) {
452cb14a3feSDimitry Andric    __re_ -= __re;
453cb14a3feSDimitry Andric    return *this;
454cb14a3feSDimitry Andric  }
455cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(float __re) {
456cb14a3feSDimitry Andric    __re_ *= __re;
457cb14a3feSDimitry Andric    __im_ *= __re;
458cb14a3feSDimitry Andric    return *this;
459cb14a3feSDimitry Andric  }
460cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(float __re) {
461cb14a3feSDimitry Andric    __re_ /= __re;
462cb14a3feSDimitry Andric    __im_ /= __re;
463cb14a3feSDimitry Andric    return *this;
464cb14a3feSDimitry Andric  }
4650b57cec5SDimitry Andric
466cb14a3feSDimitry Andric  template <class _Xp>
467cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) {
4680b57cec5SDimitry Andric    __re_ = __c.real();
4690b57cec5SDimitry Andric    __im_ = __c.imag();
4700b57cec5SDimitry Andric    return *this;
4710b57cec5SDimitry Andric  }
472cb14a3feSDimitry Andric  template <class _Xp>
473cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) {
4740b57cec5SDimitry Andric    __re_ += __c.real();
4750b57cec5SDimitry Andric    __im_ += __c.imag();
4760b57cec5SDimitry Andric    return *this;
4770b57cec5SDimitry Andric  }
478cb14a3feSDimitry Andric  template <class _Xp>
479cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) {
4800b57cec5SDimitry Andric    __re_ -= __c.real();
4810b57cec5SDimitry Andric    __im_ -= __c.imag();
4820b57cec5SDimitry Andric    return *this;
4830b57cec5SDimitry Andric  }
484cb14a3feSDimitry Andric  template <class _Xp>
485cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) {
4860b57cec5SDimitry Andric    *this = *this * complex(__c.real(), __c.imag());
4870b57cec5SDimitry Andric    return *this;
4880b57cec5SDimitry Andric  }
489cb14a3feSDimitry Andric  template <class _Xp>
490cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) {
4910b57cec5SDimitry Andric    *this = *this / complex(__c.real(), __c.imag());
4920b57cec5SDimitry Andric    return *this;
4930b57cec5SDimitry Andric  }
494*0fca6ea1SDimitry Andric
495*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26
496*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
497*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept;
498*0fca6ea1SDimitry Andric
499*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
500*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept;
501*0fca6ea1SDimitry Andric
502*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
503*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept;
504*0fca6ea1SDimitry Andric
505*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
506*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept;
507*0fca6ea1SDimitry Andric#endif
5080b57cec5SDimitry Andric};
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andrictemplate <>
511cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double> {
5120b57cec5SDimitry Andric  double __re_;
5130b57cec5SDimitry Andric  double __im_;
514cb14a3feSDimitry Andric
5150b57cec5SDimitry Andricpublic:
5160b57cec5SDimitry Andric  typedef double value_type;
5170b57cec5SDimitry Andric
518cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {}
519*0fca6ea1SDimitry Andric
520*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex double __v)
521*0fca6ea1SDimitry Andric      : __re_(__real__ __v), __im_(__imag__ __v) {}
522*0fca6ea1SDimitry Andric
523cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
524cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
5250b57cec5SDimitry Andric
5265f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double real() const { return __re_; }
5275f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR double imag() const { return __im_; }
5280b57cec5SDimitry Andric
5295f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
5305f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
5310b57cec5SDimitry Andric
532*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex double __builtin() const {
533*0fca6ea1SDimitry Andric    return std::__make_complex(__re_, __im_);
534*0fca6ea1SDimitry Andric  }
535*0fca6ea1SDimitry Andric
536*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex double __f) {
537*0fca6ea1SDimitry Andric    __re_ = __real__ __f;
538*0fca6ea1SDimitry Andric    __im_ = __imag__ __f;
539*0fca6ea1SDimitry Andric  }
540*0fca6ea1SDimitry Andric
541cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(double __re) {
542cb14a3feSDimitry Andric    __re_ = __re;
543cb14a3feSDimitry Andric    __im_ = value_type();
544cb14a3feSDimitry Andric    return *this;
545cb14a3feSDimitry Andric  }
546cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(double __re) {
547cb14a3feSDimitry Andric    __re_ += __re;
548cb14a3feSDimitry Andric    return *this;
549cb14a3feSDimitry Andric  }
550cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(double __re) {
551cb14a3feSDimitry Andric    __re_ -= __re;
552cb14a3feSDimitry Andric    return *this;
553cb14a3feSDimitry Andric  }
554cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(double __re) {
555cb14a3feSDimitry Andric    __re_ *= __re;
556cb14a3feSDimitry Andric    __im_ *= __re;
557cb14a3feSDimitry Andric    return *this;
558cb14a3feSDimitry Andric  }
559cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(double __re) {
560cb14a3feSDimitry Andric    __re_ /= __re;
561cb14a3feSDimitry Andric    __im_ /= __re;
562cb14a3feSDimitry Andric    return *this;
563cb14a3feSDimitry Andric  }
5640b57cec5SDimitry Andric
565cb14a3feSDimitry Andric  template <class _Xp>
566cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) {
5670b57cec5SDimitry Andric    __re_ = __c.real();
5680b57cec5SDimitry Andric    __im_ = __c.imag();
5690b57cec5SDimitry Andric    return *this;
5700b57cec5SDimitry Andric  }
571cb14a3feSDimitry Andric  template <class _Xp>
572cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) {
5730b57cec5SDimitry Andric    __re_ += __c.real();
5740b57cec5SDimitry Andric    __im_ += __c.imag();
5750b57cec5SDimitry Andric    return *this;
5760b57cec5SDimitry Andric  }
577cb14a3feSDimitry Andric  template <class _Xp>
578cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) {
5790b57cec5SDimitry Andric    __re_ -= __c.real();
5800b57cec5SDimitry Andric    __im_ -= __c.imag();
5810b57cec5SDimitry Andric    return *this;
5820b57cec5SDimitry Andric  }
583cb14a3feSDimitry Andric  template <class _Xp>
584cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) {
5850b57cec5SDimitry Andric    *this = *this * complex(__c.real(), __c.imag());
5860b57cec5SDimitry Andric    return *this;
5870b57cec5SDimitry Andric  }
588cb14a3feSDimitry Andric  template <class _Xp>
589cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) {
5900b57cec5SDimitry Andric    *this = *this / complex(__c.real(), __c.imag());
5910b57cec5SDimitry Andric    return *this;
5920b57cec5SDimitry Andric  }
593*0fca6ea1SDimitry Andric
594*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26
595*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
596*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept;
597*0fca6ea1SDimitry Andric
598*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
599*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept;
600*0fca6ea1SDimitry Andric
601*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
602*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept;
603*0fca6ea1SDimitry Andric
604*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
605*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept;
606*0fca6ea1SDimitry Andric#endif
6070b57cec5SDimitry Andric};
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andrictemplate <>
610cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double> {
6110b57cec5SDimitry Andric  long double __re_;
6120b57cec5SDimitry Andric  long double __im_;
613cb14a3feSDimitry Andric
6140b57cec5SDimitry Andricpublic:
6150b57cec5SDimitry Andric  typedef long double value_type;
6160b57cec5SDimitry Andric
6175f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
6180b57cec5SDimitry Andric      : __re_(__re), __im_(__im) {}
619*0fca6ea1SDimitry Andric
620*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(__from_builtin_tag, _Complex long double __v)
621*0fca6ea1SDimitry Andric      : __re_(__real__ __v), __im_(__imag__ __v) {}
622*0fca6ea1SDimitry Andric
623cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
624cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
6250b57cec5SDimitry Andric
6265f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double real() const { return __re_; }
6275f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR long double imag() const { return __im_; }
6280b57cec5SDimitry Andric
6295f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void real(value_type __re) { __re_ = __re; }
6305f757f3fSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void imag(value_type __im) { __im_ = __im; }
6310b57cec5SDimitry Andric
632*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Complex long double __builtin() const {
633*0fca6ea1SDimitry Andric    return std::__make_complex(__re_, __im_);
634*0fca6ea1SDimitry Andric  }
635*0fca6ea1SDimitry Andric
636*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __builtin(_Complex long double __f) {
637*0fca6ea1SDimitry Andric    __re_ = __real__ __f;
638*0fca6ea1SDimitry Andric    __im_ = __imag__ __f;
639*0fca6ea1SDimitry Andric  }
640*0fca6ea1SDimitry Andric
641cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(long double __re) {
642cb14a3feSDimitry Andric    __re_ = __re;
643cb14a3feSDimitry Andric    __im_ = value_type();
644cb14a3feSDimitry Andric    return *this;
645cb14a3feSDimitry Andric  }
646cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(long double __re) {
647cb14a3feSDimitry Andric    __re_ += __re;
648cb14a3feSDimitry Andric    return *this;
649cb14a3feSDimitry Andric  }
650cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(long double __re) {
651cb14a3feSDimitry Andric    __re_ -= __re;
652cb14a3feSDimitry Andric    return *this;
653cb14a3feSDimitry Andric  }
654cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(long double __re) {
655cb14a3feSDimitry Andric    __re_ *= __re;
656cb14a3feSDimitry Andric    __im_ *= __re;
657cb14a3feSDimitry Andric    return *this;
658cb14a3feSDimitry Andric  }
659cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(long double __re) {
660cb14a3feSDimitry Andric    __re_ /= __re;
661cb14a3feSDimitry Andric    __im_ /= __re;
662cb14a3feSDimitry Andric    return *this;
663cb14a3feSDimitry Andric  }
6640b57cec5SDimitry Andric
665cb14a3feSDimitry Andric  template <class _Xp>
666cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator=(const complex<_Xp>& __c) {
6670b57cec5SDimitry Andric    __re_ = __c.real();
6680b57cec5SDimitry Andric    __im_ = __c.imag();
6690b57cec5SDimitry Andric    return *this;
6700b57cec5SDimitry Andric  }
671cb14a3feSDimitry Andric  template <class _Xp>
672cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator+=(const complex<_Xp>& __c) {
6730b57cec5SDimitry Andric    __re_ += __c.real();
6740b57cec5SDimitry Andric    __im_ += __c.imag();
6750b57cec5SDimitry Andric    return *this;
6760b57cec5SDimitry Andric  }
677cb14a3feSDimitry Andric  template <class _Xp>
678cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator-=(const complex<_Xp>& __c) {
6790b57cec5SDimitry Andric    __re_ -= __c.real();
6800b57cec5SDimitry Andric    __im_ -= __c.imag();
6810b57cec5SDimitry Andric    return *this;
6820b57cec5SDimitry Andric  }
683cb14a3feSDimitry Andric  template <class _Xp>
684cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator*=(const complex<_Xp>& __c) {
6850b57cec5SDimitry Andric    *this = *this * complex(__c.real(), __c.imag());
6860b57cec5SDimitry Andric    return *this;
6870b57cec5SDimitry Andric  }
688cb14a3feSDimitry Andric  template <class _Xp>
689cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex& operator/=(const complex<_Xp>& __c) {
6900b57cec5SDimitry Andric    *this = *this / complex(__c.real(), __c.imag());
6910b57cec5SDimitry Andric    return *this;
6920b57cec5SDimitry Andric  }
693*0fca6ea1SDimitry Andric
694*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26
695*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
696*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept;
697*0fca6ea1SDimitry Andric
698*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
699*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept;
700*0fca6ea1SDimitry Andric
701*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
702*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept;
703*0fca6ea1SDimitry Andric
704*0fca6ea1SDimitry Andric  template <size_t _Ip, class _Xp>
705*0fca6ea1SDimitry Andric  friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept;
706*0fca6ea1SDimitry Andric#endif
7070b57cec5SDimitry Andric};
7080b57cec5SDimitry Andric
709cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {}
710cb14a3feSDimitry Andric
711cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c)
7120b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
7130b57cec5SDimitry Andric
714cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {}
715cb14a3feSDimitry Andric
716cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c)
7170b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
7180b57cec5SDimitry Andric
719cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c)
7200b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
7210b57cec5SDimitry Andric
722cb14a3feSDimitry Andricinline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c)
7230b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andric// 26.3.6 operators:
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andrictemplate <class _Tp>
728cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
729cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y) {
7300b57cec5SDimitry Andric  complex<_Tp> __t(__x);
7310b57cec5SDimitry Andric  __t += __y;
7320b57cec5SDimitry Andric  return __t;
7330b57cec5SDimitry Andric}
7340b57cec5SDimitry Andric
7350b57cec5SDimitry Andrictemplate <class _Tp>
736cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
737cb14a3feSDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y) {
7380b57cec5SDimitry Andric  complex<_Tp> __t(__x);
7390b57cec5SDimitry Andric  __t += __y;
7400b57cec5SDimitry Andric  return __t;
7410b57cec5SDimitry Andric}
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andrictemplate <class _Tp>
744cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
745cb14a3feSDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y) {
7460b57cec5SDimitry Andric  complex<_Tp> __t(__y);
7470b57cec5SDimitry Andric  __t += __x;
7480b57cec5SDimitry Andric  return __t;
7490b57cec5SDimitry Andric}
7500b57cec5SDimitry Andric
7510b57cec5SDimitry Andrictemplate <class _Tp>
752cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
753cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y) {
7540b57cec5SDimitry Andric  complex<_Tp> __t(__x);
7550b57cec5SDimitry Andric  __t -= __y;
7560b57cec5SDimitry Andric  return __t;
7570b57cec5SDimitry Andric}
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andrictemplate <class _Tp>
760cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
761cb14a3feSDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y) {
7620b57cec5SDimitry Andric  complex<_Tp> __t(__x);
7630b57cec5SDimitry Andric  __t -= __y;
7640b57cec5SDimitry Andric  return __t;
7650b57cec5SDimitry Andric}
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andrictemplate <class _Tp>
768cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
769cb14a3feSDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y) {
7700b57cec5SDimitry Andric  complex<_Tp> __t(-__y);
7710b57cec5SDimitry Andric  __t += __x;
7720b57cec5SDimitry Andric  return __t;
7730b57cec5SDimitry Andric}
7740b57cec5SDimitry Andric
775*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> >
776*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
777*0fca6ea1SDimitry Andricoperator*(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) {
778*0fca6ea1SDimitry Andric  return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() * __rhs.__builtin());
779*0fca6ea1SDimitry Andric}
780*0fca6ea1SDimitry Andric
781*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> >
782bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
783cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w) {
7840b57cec5SDimitry Andric  _Tp __a = __z.real();
7850b57cec5SDimitry Andric  _Tp __b = __z.imag();
7860b57cec5SDimitry Andric  _Tp __c = __w.real();
7870b57cec5SDimitry Andric  _Tp __d = __w.imag();
788bdd1243dSDimitry Andric
789*0fca6ea1SDimitry Andric  return complex<_Tp>((__a * __c) - (__b * __d), (__a * __d) + (__b * __c));
7900b57cec5SDimitry Andric}
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andrictemplate <class _Tp>
793cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
794cb14a3feSDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y) {
7950b57cec5SDimitry Andric  complex<_Tp> __t(__x);
7960b57cec5SDimitry Andric  __t *= __y;
7970b57cec5SDimitry Andric  return __t;
7980b57cec5SDimitry Andric}
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andrictemplate <class _Tp>
801cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
802cb14a3feSDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y) {
8030b57cec5SDimitry Andric  complex<_Tp> __t(__y);
8040b57cec5SDimitry Andric  __t *= __x;
8050b57cec5SDimitry Andric  return __t;
8060b57cec5SDimitry Andric}
8070b57cec5SDimitry Andric
808*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> >
809*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
810*0fca6ea1SDimitry Andricoperator/(const complex<_Tp>& __lhs, const complex<_Tp>& __rhs) {
811*0fca6ea1SDimitry Andric  return complex<_Tp>(__from_builtin_tag(), __lhs.__builtin() / __rhs.__builtin());
812*0fca6ea1SDimitry Andric}
813*0fca6ea1SDimitry Andric
814*0fca6ea1SDimitry Andrictemplate <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> >
815bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
816cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w) {
8170b57cec5SDimitry Andric  _Tp __a = __z.real();
8180b57cec5SDimitry Andric  _Tp __b = __z.imag();
8190b57cec5SDimitry Andric  _Tp __c = __w.real();
8200b57cec5SDimitry Andric  _Tp __d = __w.imag();
821bdd1243dSDimitry Andric
8220b57cec5SDimitry Andric  _Tp __denom = __c * __c + __d * __d;
823*0fca6ea1SDimitry Andric  return complex<_Tp>((__a * __c + __b * __d) / __denom, (__b * __c - __a * __d) / __denom);
8240b57cec5SDimitry Andric}
8250b57cec5SDimitry Andric
8260b57cec5SDimitry Andrictemplate <class _Tp>
827cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
828cb14a3feSDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y) {
8290b57cec5SDimitry Andric  return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
8300b57cec5SDimitry Andric}
8310b57cec5SDimitry Andric
8320b57cec5SDimitry Andrictemplate <class _Tp>
833cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp>
834cb14a3feSDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y) {
8350b57cec5SDimitry Andric  complex<_Tp> __t(__x);
8360b57cec5SDimitry Andric  __t /= __y;
8370b57cec5SDimitry Andric  return __t;
8380b57cec5SDimitry Andric}
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andrictemplate <class _Tp>
841cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator+(const complex<_Tp>& __x) {
8420b57cec5SDimitry Andric  return __x;
8430b57cec5SDimitry Andric}
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andrictemplate <class _Tp>
846cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> operator-(const complex<_Tp>& __x) {
8470b57cec5SDimitry Andric  return complex<_Tp>(-__x.real(), -__x.imag());
8480b57cec5SDimitry Andric}
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andrictemplate <class _Tp>
851cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
852cb14a3feSDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y) {
8530b57cec5SDimitry Andric  return __x.real() == __y.real() && __x.imag() == __y.imag();
8540b57cec5SDimitry Andric}
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andrictemplate <class _Tp>
857cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const complex<_Tp>& __x, const _Tp& __y) {
8580b57cec5SDimitry Andric  return __x.real() == __y && __x.imag() == 0;
8590b57cec5SDimitry Andric}
8600b57cec5SDimitry Andric
86106c3fb27SDimitry Andric#if _LIBCPP_STD_VER <= 17
86206c3fb27SDimitry Andric
8630b57cec5SDimitry Andrictemplate <class _Tp>
864cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const _Tp& __x, const complex<_Tp>& __y) {
8650b57cec5SDimitry Andric  return __x == __y.real() && 0 == __y.imag();
8660b57cec5SDimitry Andric}
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andrictemplate <class _Tp>
869cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
870cb14a3feSDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) {
8710b57cec5SDimitry Andric  return !(__x == __y);
8720b57cec5SDimitry Andric}
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andrictemplate <class _Tp>
875cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const complex<_Tp>& __x, const _Tp& __y) {
8760b57cec5SDimitry Andric  return !(__x == __y);
8770b57cec5SDimitry Andric}
8780b57cec5SDimitry Andric
8790b57cec5SDimitry Andrictemplate <class _Tp>
880cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator!=(const _Tp& __x, const complex<_Tp>& __y) {
8810b57cec5SDimitry Andric  return !(__x == __y);
8820b57cec5SDimitry Andric}
8830b57cec5SDimitry Andric
88406c3fb27SDimitry Andric#endif
88506c3fb27SDimitry Andric
8860b57cec5SDimitry Andric// 26.3.7 values:
8870b57cec5SDimitry Andric
888cb14a3feSDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value, bool = is_floating_point<_Tp>::value >
8890b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {};
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andric// Integral Types
8920b57cec5SDimitry Andrictemplate <class _Tp>
893cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false> {
8940b57cec5SDimitry Andric  typedef double _ValueType;
8950b57cec5SDimitry Andric  typedef complex<double> _ComplexType;
8960b57cec5SDimitry Andric};
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andric// Floating point types
8990b57cec5SDimitry Andrictemplate <class _Tp>
900cb14a3feSDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true> {
9010b57cec5SDimitry Andric  typedef _Tp _ValueType;
9020b57cec5SDimitry Andric  typedef complex<_Tp> _ComplexType;
9030b57cec5SDimitry Andric};
9040b57cec5SDimitry Andric
9050b57cec5SDimitry Andric// real
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andrictemplate <class _Tp>
908cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp real(const complex<_Tp>& __c) {
9090b57cec5SDimitry Andric  return __c.real();
9100b57cec5SDimitry Andric}
9110b57cec5SDimitry Andric
9120b57cec5SDimitry Andrictemplate <class _Tp>
913cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
914cb14a3feSDimitry Andricreal(_Tp __re) {
9150b57cec5SDimitry Andric  return __re;
9160b57cec5SDimitry Andric}
9170b57cec5SDimitry Andric
9180b57cec5SDimitry Andric// imag
9190b57cec5SDimitry Andric
9200b57cec5SDimitry Andrictemplate <class _Tp>
921cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp imag(const complex<_Tp>& __c) {
9220b57cec5SDimitry Andric  return __c.imag();
9230b57cec5SDimitry Andric}
9240b57cec5SDimitry Andric
9250b57cec5SDimitry Andrictemplate <class _Tp>
926cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
927cb14a3feSDimitry Andricimag(_Tp) {
9280b57cec5SDimitry Andric  return 0;
9290b57cec5SDimitry Andric}
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric// abs
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andrictemplate <class _Tp>
934cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp abs(const complex<_Tp>& __c) {
935bdd1243dSDimitry Andric  return std::hypot(__c.real(), __c.imag());
9360b57cec5SDimitry Andric}
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric// arg
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andrictemplate <class _Tp>
941cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp arg(const complex<_Tp>& __c) {
942bdd1243dSDimitry Andric  return std::atan2(__c.imag(), __c.real());
9430b57cec5SDimitry Andric}
9440b57cec5SDimitry Andric
9455f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, long double>::value, int> = 0>
946cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI long double arg(_Tp __re) {
947bdd1243dSDimitry Andric  return std::atan2l(0.L, __re);
9480b57cec5SDimitry Andric}
9490b57cec5SDimitry Andric
9505f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value || is_same<_Tp, double>::value, int> = 0>
951cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI double arg(_Tp __re) {
952bdd1243dSDimitry Andric  return std::atan2(0., __re);
9530b57cec5SDimitry Andric}
9540b57cec5SDimitry Andric
9555f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_same<_Tp, float>::value, int> = 0>
956cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI float arg(_Tp __re) {
957bdd1243dSDimitry Andric  return std::atan2f(0.F, __re);
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric// norm
9610b57cec5SDimitry Andric
9620b57cec5SDimitry Andrictemplate <class _Tp>
963cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp norm(const complex<_Tp>& __c) {
964bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__c.real()))
965bdd1243dSDimitry Andric    return std::abs(__c.real());
966bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__c.imag()))
967bdd1243dSDimitry Andric    return std::abs(__c.imag());
9680b57cec5SDimitry Andric  return __c.real() * __c.real() + __c.imag() * __c.imag();
9690b57cec5SDimitry Andric}
9700b57cec5SDimitry Andric
9710b57cec5SDimitry Andrictemplate <class _Tp>
972cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ValueType
973cb14a3feSDimitry Andricnorm(_Tp __re) {
9740b57cec5SDimitry Andric  typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
9750b57cec5SDimitry Andric  return static_cast<_ValueType>(__re) * __re;
9760b57cec5SDimitry Andric}
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andric// conj
9790b57cec5SDimitry Andric
9800b57cec5SDimitry Andrictemplate <class _Tp>
981cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 complex<_Tp> conj(const complex<_Tp>& __c) {
9820b57cec5SDimitry Andric  return complex<_Tp>(__c.real(), -__c.imag());
9830b57cec5SDimitry Andric}
9840b57cec5SDimitry Andric
9850b57cec5SDimitry Andrictemplate <class _Tp>
986cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
987cb14a3feSDimitry Andricconj(_Tp __re) {
9880b57cec5SDimitry Andric  typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
9890b57cec5SDimitry Andric  return _ComplexType(__re);
9900b57cec5SDimitry Andric}
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andric// proj
9930b57cec5SDimitry Andric
9940b57cec5SDimitry Andrictemplate <class _Tp>
995cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> proj(const complex<_Tp>& __c) {
996e8d8bef9SDimitry Andric  complex<_Tp> __r = __c;
997bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__c.real()) || std::__constexpr_isinf(__c.imag()))
998bdd1243dSDimitry Andric    __r = complex<_Tp>(INFINITY, std::copysign(_Tp(0), __c.imag()));
9990b57cec5SDimitry Andric  return __r;
10000b57cec5SDimitry Andric}
10010b57cec5SDimitry Andric
10025f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
1003cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) {
1004bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__re))
1005bdd1243dSDimitry Andric    __re = std::abs(__re);
10060b57cec5SDimitry Andric  return complex<_Tp>(__re);
10070b57cec5SDimitry Andric}
10080b57cec5SDimitry Andric
10095f757f3fSDimitry Andrictemplate <class _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
1010cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI typename __libcpp_complex_overload_traits<_Tp>::_ComplexType proj(_Tp __re) {
10110b57cec5SDimitry Andric  typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
10120b57cec5SDimitry Andric  return _ComplexType(__re);
10130b57cec5SDimitry Andric}
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric// polar
10160b57cec5SDimitry Andric
10170b57cec5SDimitry Andrictemplate <class _Tp>
1018cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp()) {
1019bdd1243dSDimitry Andric  if (std::__constexpr_isnan(__rho) || std::signbit(__rho))
10200b57cec5SDimitry Andric    return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1021cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__theta)) {
1022bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__rho))
10230b57cec5SDimitry Andric      return complex<_Tp>(__rho, __theta);
10240b57cec5SDimitry Andric    return complex<_Tp>(__theta, __theta);
10250b57cec5SDimitry Andric  }
1026cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__theta)) {
1027bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__rho))
10280b57cec5SDimitry Andric      return complex<_Tp>(__rho, _Tp(NAN));
10290b57cec5SDimitry Andric    return complex<_Tp>(_Tp(NAN), _Tp(NAN));
10300b57cec5SDimitry Andric  }
1031bdd1243dSDimitry Andric  _Tp __x = __rho * std::cos(__theta);
1032bdd1243dSDimitry Andric  if (std::__constexpr_isnan(__x))
10330b57cec5SDimitry Andric    __x = 0;
1034bdd1243dSDimitry Andric  _Tp __y = __rho * std::sin(__theta);
1035bdd1243dSDimitry Andric  if (std::__constexpr_isnan(__y))
10360b57cec5SDimitry Andric    __y = 0;
10370b57cec5SDimitry Andric  return complex<_Tp>(__x, __y);
10380b57cec5SDimitry Andric}
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric// log
10410b57cec5SDimitry Andric
10420b57cec5SDimitry Andrictemplate <class _Tp>
1043cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log(const complex<_Tp>& __x) {
1044bdd1243dSDimitry Andric  return complex<_Tp>(std::log(std::abs(__x)), std::arg(__x));
10450b57cec5SDimitry Andric}
10460b57cec5SDimitry Andric
10470b57cec5SDimitry Andric// log10
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andrictemplate <class _Tp>
1050cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> log10(const complex<_Tp>& __x) {
1051bdd1243dSDimitry Andric  return std::log(__x) / std::log(_Tp(10));
10520b57cec5SDimitry Andric}
10530b57cec5SDimitry Andric
10540b57cec5SDimitry Andric// sqrt
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andrictemplate <class _Tp>
1057cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sqrt(const complex<_Tp>& __x) {
1058bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.imag()))
10590b57cec5SDimitry Andric    return complex<_Tp>(_Tp(INFINITY), __x.imag());
1060cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
10610b57cec5SDimitry Andric    if (__x.real() > _Tp(0))
1062cb14a3feSDimitry Andric      return complex<_Tp>(
1063cb14a3feSDimitry Andric          __x.real(), std::__constexpr_isnan(__x.imag()) ? __x.imag() : std::copysign(_Tp(0), __x.imag()));
1064cb14a3feSDimitry Andric    return complex<_Tp>(
1065cb14a3feSDimitry Andric        std::__constexpr_isnan(__x.imag()) ? __x.imag() : _Tp(0), std::copysign(__x.real(), __x.imag()));
10660b57cec5SDimitry Andric  }
1067bdd1243dSDimitry Andric  return std::polar(std::sqrt(std::abs(__x)), std::arg(__x) / _Tp(2));
10680b57cec5SDimitry Andric}
10690b57cec5SDimitry Andric
10700b57cec5SDimitry Andric// exp
10710b57cec5SDimitry Andric
10720b57cec5SDimitry Andrictemplate <class _Tp>
1073cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> exp(const complex<_Tp>& __x) {
10740b57cec5SDimitry Andric  _Tp __i = __x.imag();
1075349cc55cSDimitry Andric  if (__i == 0) {
1076bdd1243dSDimitry Andric    return complex<_Tp>(std::exp(__x.real()), std::copysign(_Tp(0), __x.imag()));
1077349cc55cSDimitry Andric  }
1078cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1079cb14a3feSDimitry Andric    if (__x.real() < _Tp(0)) {
1080bdd1243dSDimitry Andric      if (!std::__constexpr_isfinite(__i))
10810b57cec5SDimitry Andric        __i = _Tp(1);
1082cb14a3feSDimitry Andric    } else if (__i == 0 || !std::__constexpr_isfinite(__i)) {
1083bdd1243dSDimitry Andric      if (std::__constexpr_isinf(__i))
10840b57cec5SDimitry Andric        __i = _Tp(NAN);
10850b57cec5SDimitry Andric      return complex<_Tp>(__x.real(), __i);
10860b57cec5SDimitry Andric    }
10870b57cec5SDimitry Andric  }
1088bdd1243dSDimitry Andric  _Tp __e = std::exp(__x.real());
1089bdd1243dSDimitry Andric  return complex<_Tp>(__e * std::cos(__i), __e * std::sin(__i));
10900b57cec5SDimitry Andric}
10910b57cec5SDimitry Andric
10920b57cec5SDimitry Andric// pow
10930b57cec5SDimitry Andric
10940b57cec5SDimitry Andrictemplate <class _Tp>
1095cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) {
1096bdd1243dSDimitry Andric  return std::exp(__y * std::log(__x));
10970b57cec5SDimitry Andric}
10980b57cec5SDimitry Andric
10990b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
1100cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type>
1101cb14a3feSDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y) {
11020b57cec5SDimitry Andric  typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11035f757f3fSDimitry Andric  return std::pow(result_type(__x), result_type(__y));
11040b57cec5SDimitry Andric}
11050b57cec5SDimitry Andric
11065f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0>
1107cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) {
11080b57cec5SDimitry Andric  typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11095f757f3fSDimitry Andric  return std::pow(result_type(__x), result_type(__y));
11100b57cec5SDimitry Andric}
11110b57cec5SDimitry Andric
11125f757f3fSDimitry Andrictemplate <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Tp>::value, int> = 0>
1113cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const _Tp& __x, const complex<_Up>& __y) {
11140b57cec5SDimitry Andric  typedef complex<typename __promote<_Tp, _Up>::type> result_type;
11155f757f3fSDimitry Andric  return std::pow(result_type(__x), result_type(__y));
11160b57cec5SDimitry Andric}
11170b57cec5SDimitry Andric
11180b57cec5SDimitry Andric// __sqr, computes pow(x, 2)
11190b57cec5SDimitry Andric
11200b57cec5SDimitry Andrictemplate <class _Tp>
1121cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) {
1122cb14a3feSDimitry Andric  return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()), _Tp(2) * __x.real() * __x.imag());
11230b57cec5SDimitry Andric}
11240b57cec5SDimitry Andric
11250b57cec5SDimitry Andric// asinh
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andrictemplate <class _Tp>
1128cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
11290b57cec5SDimitry Andric  const _Tp __pi(atan2(+0., -0.));
1130cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1131bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.imag()))
11320b57cec5SDimitry Andric      return __x;
1133bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
1134bdd1243dSDimitry Andric      return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
1135bdd1243dSDimitry Andric    return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
11360b57cec5SDimitry Andric  }
1137cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__x.real())) {
1138bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
11390b57cec5SDimitry Andric      return complex<_Tp>(__x.imag(), __x.real());
11400b57cec5SDimitry Andric    if (__x.imag() == 0)
11410b57cec5SDimitry Andric      return __x;
11420b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), __x.real());
11430b57cec5SDimitry Andric  }
1144bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.imag()))
1145bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
1146bdd1243dSDimitry Andric  complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
1147bdd1243dSDimitry Andric  return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
11480b57cec5SDimitry Andric}
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andric// acosh
11510b57cec5SDimitry Andric
11520b57cec5SDimitry Andrictemplate <class _Tp>
1153cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
11540b57cec5SDimitry Andric  const _Tp __pi(atan2(+0., -0.));
1155cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1156bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.imag()))
1157bdd1243dSDimitry Andric      return complex<_Tp>(std::abs(__x.real()), __x.imag());
1158cb14a3feSDimitry Andric    if (std::__constexpr_isinf(__x.imag())) {
11590b57cec5SDimitry Andric      if (__x.real() > 0)
1160bdd1243dSDimitry Andric        return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
11610b57cec5SDimitry Andric      else
1162bdd1243dSDimitry Andric        return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
11630b57cec5SDimitry Andric    }
11640b57cec5SDimitry Andric    if (__x.real() < 0)
1165bdd1243dSDimitry Andric      return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
1166bdd1243dSDimitry Andric    return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
11670b57cec5SDimitry Andric  }
1168cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__x.real())) {
1169bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
1170bdd1243dSDimitry Andric      return complex<_Tp>(std::abs(__x.imag()), __x.real());
11710b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), __x.real());
11720b57cec5SDimitry Andric  }
1173bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.imag()))
1174bdd1243dSDimitry Andric    return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag()));
1175bdd1243dSDimitry Andric  complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1176bdd1243dSDimitry Andric  return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
11770b57cec5SDimitry Andric}
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andric// atanh
11800b57cec5SDimitry Andric
11810b57cec5SDimitry Andrictemplate <class _Tp>
1182cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
11830b57cec5SDimitry Andric  const _Tp __pi(atan2(+0., -0.));
1184cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.imag())) {
1185bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
11860b57cec5SDimitry Andric  }
1187cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__x.imag())) {
1188bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.real()) || __x.real() == 0)
1189bdd1243dSDimitry Andric      return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
11900b57cec5SDimitry Andric    return complex<_Tp>(__x.imag(), __x.imag());
11910b57cec5SDimitry Andric  }
1192cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__x.real())) {
11930b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), __x.real());
11940b57cec5SDimitry Andric  }
1195cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1196bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
11970b57cec5SDimitry Andric  }
1198cb14a3feSDimitry Andric  if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) {
1199bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
12000b57cec5SDimitry Andric  }
1201bdd1243dSDimitry Andric  complex<_Tp> __z = std::log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1202bdd1243dSDimitry Andric  return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
12030b57cec5SDimitry Andric}
12040b57cec5SDimitry Andric
12050b57cec5SDimitry Andric// sinh
12060b57cec5SDimitry Andric
12070b57cec5SDimitry Andrictemplate <class _Tp>
1208cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sinh(const complex<_Tp>& __x) {
1209bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
12100b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), _Tp(NAN));
1211bdd1243dSDimitry Andric  if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
12120b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), _Tp(NAN));
1213bdd1243dSDimitry Andric  if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
12140b57cec5SDimitry Andric    return __x;
1215bdd1243dSDimitry Andric  return complex<_Tp>(std::sinh(__x.real()) * std::cos(__x.imag()), std::cosh(__x.real()) * std::sin(__x.imag()));
12160b57cec5SDimitry Andric}
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andric// cosh
12190b57cec5SDimitry Andric
12200b57cec5SDimitry Andrictemplate <class _Tp>
1221cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) {
1222bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.real()) && !std::__constexpr_isfinite(__x.imag()))
1223bdd1243dSDimitry Andric    return complex<_Tp>(std::abs(__x.real()), _Tp(NAN));
1224bdd1243dSDimitry Andric  if (__x.real() == 0 && !std::__constexpr_isfinite(__x.imag()))
12250b57cec5SDimitry Andric    return complex<_Tp>(_Tp(NAN), __x.real());
12260b57cec5SDimitry Andric  if (__x.real() == 0 && __x.imag() == 0)
12270b57cec5SDimitry Andric    return complex<_Tp>(_Tp(1), __x.imag());
1228bdd1243dSDimitry Andric  if (__x.imag() == 0 && !std::__constexpr_isfinite(__x.real()))
1229bdd1243dSDimitry Andric    return complex<_Tp>(std::abs(__x.real()), __x.imag());
1230bdd1243dSDimitry Andric  return complex<_Tp>(std::cosh(__x.real()) * std::cos(__x.imag()), std::sinh(__x.real()) * std::sin(__x.imag()));
12310b57cec5SDimitry Andric}
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andric// tanh
12340b57cec5SDimitry Andric
12350b57cec5SDimitry Andrictemplate <class _Tp>
1236cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) {
1237cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1238bdd1243dSDimitry Andric    if (!std::__constexpr_isfinite(__x.imag()))
1239bdd1243dSDimitry Andric      return complex<_Tp>(std::copysign(_Tp(1), __x.real()), _Tp(0));
1240bdd1243dSDimitry Andric    return complex<_Tp>(std::copysign(_Tp(1), __x.real()), std::copysign(_Tp(0), std::sin(_Tp(2) * __x.imag())));
12410b57cec5SDimitry Andric  }
1242bdd1243dSDimitry Andric  if (std::__constexpr_isnan(__x.real()) && __x.imag() == 0)
12430b57cec5SDimitry Andric    return __x;
12440b57cec5SDimitry Andric  _Tp __2r(_Tp(2) * __x.real());
12450b57cec5SDimitry Andric  _Tp __2i(_Tp(2) * __x.imag());
1246bdd1243dSDimitry Andric  _Tp __d(std::cosh(__2r) + std::cos(__2i));
1247bdd1243dSDimitry Andric  _Tp __2rsh(std::sinh(__2r));
1248bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__2rsh) && std::__constexpr_isinf(__d))
1249cb14a3feSDimitry Andric    return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1250bdd1243dSDimitry Andric  return complex<_Tp>(__2rsh / __d, std::sin(__2i) / __d);
12510b57cec5SDimitry Andric}
12520b57cec5SDimitry Andric
12530b57cec5SDimitry Andric// asin
12540b57cec5SDimitry Andric
12550b57cec5SDimitry Andrictemplate <class _Tp>
1256cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> asin(const complex<_Tp>& __x) {
1257bdd1243dSDimitry Andric  complex<_Tp> __z = std::asinh(complex<_Tp>(-__x.imag(), __x.real()));
12580b57cec5SDimitry Andric  return complex<_Tp>(__z.imag(), -__z.real());
12590b57cec5SDimitry Andric}
12600b57cec5SDimitry Andric
12610b57cec5SDimitry Andric// acos
12620b57cec5SDimitry Andric
12630b57cec5SDimitry Andrictemplate <class _Tp>
1264cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> acos(const complex<_Tp>& __x) {
12650b57cec5SDimitry Andric  const _Tp __pi(atan2(+0., -0.));
1266cb14a3feSDimitry Andric  if (std::__constexpr_isinf(__x.real())) {
1267bdd1243dSDimitry Andric    if (std::__constexpr_isnan(__x.imag()))
12680b57cec5SDimitry Andric      return complex<_Tp>(__x.imag(), __x.real());
1269cb14a3feSDimitry Andric    if (std::__constexpr_isinf(__x.imag())) {
12700b57cec5SDimitry Andric      if (__x.real() < _Tp(0))
12710b57cec5SDimitry Andric        return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
12720b57cec5SDimitry Andric      return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
12730b57cec5SDimitry Andric    }
12740b57cec5SDimitry Andric    if (__x.real() < _Tp(0))
1275bdd1243dSDimitry Andric      return complex<_Tp>(__pi, std::signbit(__x.imag()) ? -__x.real() : __x.real());
1276bdd1243dSDimitry Andric    return complex<_Tp>(_Tp(0), std::signbit(__x.imag()) ? __x.real() : -__x.real());
12770b57cec5SDimitry Andric  }
1278cb14a3feSDimitry Andric  if (std::__constexpr_isnan(__x.real())) {
1279bdd1243dSDimitry Andric    if (std::__constexpr_isinf(__x.imag()))
12800b57cec5SDimitry Andric      return complex<_Tp>(__x.real(), -__x.imag());
12810b57cec5SDimitry Andric    return complex<_Tp>(__x.real(), __x.real());
12820b57cec5SDimitry Andric  }
1283bdd1243dSDimitry Andric  if (std::__constexpr_isinf(__x.imag()))
12840b57cec5SDimitry Andric    return complex<_Tp>(__pi / _Tp(2), -__x.imag());
1285bdd1243dSDimitry Andric  if (__x.real() == 0 && (__x.imag() == 0 || std::isnan(__x.imag())))
12860b57cec5SDimitry Andric    return complex<_Tp>(__pi / _Tp(2), -__x.imag());
1287bdd1243dSDimitry Andric  complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
1288bdd1243dSDimitry Andric  if (std::signbit(__x.imag()))
1289bdd1243dSDimitry Andric    return complex<_Tp>(std::abs(__z.imag()), std::abs(__z.real()));
1290bdd1243dSDimitry Andric  return complex<_Tp>(std::abs(__z.imag()), -std::abs(__z.real()));
12910b57cec5SDimitry Andric}
12920b57cec5SDimitry Andric
12930b57cec5SDimitry Andric// atan
12940b57cec5SDimitry Andric
12950b57cec5SDimitry Andrictemplate <class _Tp>
1296cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> atan(const complex<_Tp>& __x) {
1297bdd1243dSDimitry Andric  complex<_Tp> __z = std::atanh(complex<_Tp>(-__x.imag(), __x.real()));
12980b57cec5SDimitry Andric  return complex<_Tp>(__z.imag(), -__z.real());
12990b57cec5SDimitry Andric}
13000b57cec5SDimitry Andric
13010b57cec5SDimitry Andric// sin
13020b57cec5SDimitry Andric
13030b57cec5SDimitry Andrictemplate <class _Tp>
1304cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> sin(const complex<_Tp>& __x) {
1305bdd1243dSDimitry Andric  complex<_Tp> __z = std::sinh(complex<_Tp>(-__x.imag(), __x.real()));
13060b57cec5SDimitry Andric  return complex<_Tp>(__z.imag(), -__z.real());
13070b57cec5SDimitry Andric}
13080b57cec5SDimitry Andric
13090b57cec5SDimitry Andric// cos
13100b57cec5SDimitry Andric
13110b57cec5SDimitry Andrictemplate <class _Tp>
1312cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI complex<_Tp> cos(const complex<_Tp>& __x) {
1313bdd1243dSDimitry Andric  return std::cosh(complex<_Tp>(-__x.imag(), __x.real()));
13140b57cec5SDimitry Andric}
13150b57cec5SDimitry Andric
13160b57cec5SDimitry Andric// tan
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andrictemplate <class _Tp>
1319cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI complex<_Tp> tan(const complex<_Tp>& __x) {
1320bdd1243dSDimitry Andric  complex<_Tp> __z = std::tanh(complex<_Tp>(-__x.imag(), __x.real()));
13210b57cec5SDimitry Andric  return complex<_Tp>(__z.imag(), -__z.real());
13220b57cec5SDimitry Andric}
13230b57cec5SDimitry Andric
1324bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
13250b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits>
1326bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
1327cb14a3feSDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) {
1328cb14a3feSDimitry Andric  if (__is.good()) {
1329bdd1243dSDimitry Andric    std::ws(__is);
1330cb14a3feSDimitry Andric    if (__is.peek() == _CharT('(')) {
13310b57cec5SDimitry Andric      __is.get();
13320b57cec5SDimitry Andric      _Tp __r;
13330b57cec5SDimitry Andric      __is >> __r;
1334cb14a3feSDimitry Andric      if (!__is.fail()) {
1335bdd1243dSDimitry Andric        std::ws(__is);
13360b57cec5SDimitry Andric        _CharT __c = __is.peek();
1337cb14a3feSDimitry Andric        if (__c == _CharT(',')) {
13380b57cec5SDimitry Andric          __is.get();
13390b57cec5SDimitry Andric          _Tp __i;
13400b57cec5SDimitry Andric          __is >> __i;
1341cb14a3feSDimitry Andric          if (!__is.fail()) {
1342bdd1243dSDimitry Andric            std::ws(__is);
13430b57cec5SDimitry Andric            __c = __is.peek();
1344cb14a3feSDimitry Andric            if (__c == _CharT(')')) {
13450b57cec5SDimitry Andric              __is.get();
13460b57cec5SDimitry Andric              __x = complex<_Tp>(__r, __i);
1347cb14a3feSDimitry Andric            } else
13485ffd83dbSDimitry Andric              __is.setstate(__is.failbit);
1349cb14a3feSDimitry Andric          } else
13505ffd83dbSDimitry Andric            __is.setstate(__is.failbit);
1351cb14a3feSDimitry Andric        } else if (__c == _CharT(')')) {
13520b57cec5SDimitry Andric          __is.get();
13530b57cec5SDimitry Andric          __x = complex<_Tp>(__r, _Tp(0));
1354cb14a3feSDimitry Andric        } else
13555ffd83dbSDimitry Andric          __is.setstate(__is.failbit);
1356cb14a3feSDimitry Andric      } else
13575ffd83dbSDimitry Andric        __is.setstate(__is.failbit);
1358cb14a3feSDimitry Andric    } else {
13590b57cec5SDimitry Andric      _Tp __r;
13600b57cec5SDimitry Andric      __is >> __r;
13610b57cec5SDimitry Andric      if (!__is.fail())
13620b57cec5SDimitry Andric        __x = complex<_Tp>(__r, _Tp(0));
13630b57cec5SDimitry Andric      else
13645ffd83dbSDimitry Andric        __is.setstate(__is.failbit);
13650b57cec5SDimitry Andric    }
1366cb14a3feSDimitry Andric  } else
13675ffd83dbSDimitry Andric    __is.setstate(__is.failbit);
13680b57cec5SDimitry Andric  return __is;
13690b57cec5SDimitry Andric}
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andrictemplate <class _Tp, class _CharT, class _Traits>
1372bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
1373cb14a3feSDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) {
13740b57cec5SDimitry Andric  basic_ostringstream<_CharT, _Traits> __s;
13750b57cec5SDimitry Andric  __s.flags(__os.flags());
13760b57cec5SDimitry Andric  __s.imbue(__os.getloc());
13770b57cec5SDimitry Andric  __s.precision(__os.precision());
13780b57cec5SDimitry Andric  __s << '(' << __x.real() << ',' << __x.imag() << ')';
13790b57cec5SDimitry Andric  return __os << __s.str();
13800b57cec5SDimitry Andric}
1381e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_LOCALIZATION
13820b57cec5SDimitry Andric
1383*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 26
1384*0fca6ea1SDimitry Andric
1385*0fca6ea1SDimitry Andric// [complex.tuple], tuple interface
1386*0fca6ea1SDimitry Andric
1387*0fca6ea1SDimitry Andrictemplate <class _Tp>
1388*0fca6ea1SDimitry Andricstruct tuple_size<complex<_Tp>> : integral_constant<size_t, 2> {};
1389*0fca6ea1SDimitry Andric
1390*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Tp>
1391*0fca6ea1SDimitry Andricstruct tuple_element<_Ip, complex<_Tp>> {
1392*0fca6ea1SDimitry Andric  static_assert(_Ip < 2, "Index value is out of range.");
1393*0fca6ea1SDimitry Andric  using type = _Tp;
1394*0fca6ea1SDimitry Andric};
1395*0fca6ea1SDimitry Andric
1396*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp>
1397*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept {
1398*0fca6ea1SDimitry Andric  static_assert(_Ip < 2, "Index value is out of range.");
1399*0fca6ea1SDimitry Andric  if constexpr (_Ip == 0) {
1400*0fca6ea1SDimitry Andric    return __z.__re_;
1401*0fca6ea1SDimitry Andric  } else {
1402*0fca6ea1SDimitry Andric    return __z.__im_;
1403*0fca6ea1SDimitry Andric  }
1404*0fca6ea1SDimitry Andric}
1405*0fca6ea1SDimitry Andric
1406*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp>
1407*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept {
1408*0fca6ea1SDimitry Andric  static_assert(_Ip < 2, "Index value is out of range.");
1409*0fca6ea1SDimitry Andric  if constexpr (_Ip == 0) {
1410*0fca6ea1SDimitry Andric    return std::move(__z.__re_);
1411*0fca6ea1SDimitry Andric  } else {
1412*0fca6ea1SDimitry Andric    return std::move(__z.__im_);
1413*0fca6ea1SDimitry Andric  }
1414*0fca6ea1SDimitry Andric}
1415*0fca6ea1SDimitry Andric
1416*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp>
1417*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept {
1418*0fca6ea1SDimitry Andric  static_assert(_Ip < 2, "Index value is out of range.");
1419*0fca6ea1SDimitry Andric  if constexpr (_Ip == 0) {
1420*0fca6ea1SDimitry Andric    return __z.__re_;
1421*0fca6ea1SDimitry Andric  } else {
1422*0fca6ea1SDimitry Andric    return __z.__im_;
1423*0fca6ea1SDimitry Andric  }
1424*0fca6ea1SDimitry Andric}
1425*0fca6ea1SDimitry Andric
1426*0fca6ea1SDimitry Andrictemplate <size_t _Ip, class _Xp>
1427*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept {
1428*0fca6ea1SDimitry Andric  static_assert(_Ip < 2, "Index value is out of range.");
1429*0fca6ea1SDimitry Andric  if constexpr (_Ip == 0) {
1430*0fca6ea1SDimitry Andric    return std::move(__z.__re_);
1431*0fca6ea1SDimitry Andric  } else {
1432*0fca6ea1SDimitry Andric    return std::move(__z.__im_);
1433*0fca6ea1SDimitry Andric  }
1434*0fca6ea1SDimitry Andric}
1435*0fca6ea1SDimitry Andric
1436*0fca6ea1SDimitry Andric#endif // _LIBCPP_STD_VER >= 26
1437*0fca6ea1SDimitry Andric
143806c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14
14390b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals]
1440cb14a3feSDimitry Andricinline namespace literals {
1441cb14a3feSDimitry Andricinline namespace complex_literals {
1442cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(long double __im) { return {0.0l, __im}; }
14430b57cec5SDimitry Andric
1444cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<long double> operator""il(unsigned long long __im) {
14450b57cec5SDimitry Andric  return {0.0l, static_cast<long double>(__im)};
14460b57cec5SDimitry Andric}
14470b57cec5SDimitry Andric
1448cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(long double __im) {
14490b57cec5SDimitry Andric  return {0.0, static_cast<double>(__im)};
14500b57cec5SDimitry Andric}
14510b57cec5SDimitry Andric
1452cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<double> operator""i(unsigned long long __im) {
14530b57cec5SDimitry Andric  return {0.0, static_cast<double>(__im)};
14540b57cec5SDimitry Andric}
14550b57cec5SDimitry Andric
1456cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(long double __im) {
14570b57cec5SDimitry Andric  return {0.0f, static_cast<float>(__im)};
14580b57cec5SDimitry Andric}
14590b57cec5SDimitry Andric
1460cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long long __im) {
14610b57cec5SDimitry Andric  return {0.0f, static_cast<float>(__im)};
14620b57cec5SDimitry Andric}
14630eae32dcSDimitry Andric} // namespace complex_literals
14640eae32dcSDimitry Andric} // namespace literals
14650b57cec5SDimitry Andric#endif
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
14680b57cec5SDimitry Andric
1469*0fca6ea1SDimitry Andric_LIBCPP_POP_MACROS
1470*0fca6ea1SDimitry Andric
147106c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
14725f757f3fSDimitry Andric#  include <iosfwd>
14735f757f3fSDimitry Andric#  include <stdexcept>
147406c3fb27SDimitry Andric#  include <type_traits>
147506c3fb27SDimitry Andric#endif
147606c3fb27SDimitry Andric
14770b57cec5SDimitry Andric#endif // _LIBCPP_COMPLEX
1478