xref: /freebsd/contrib/llvm-project/libcxx/include/complex (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===--------------------------- complex ----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_COMPLEX
11*0b57cec5SDimitry Andric#define _LIBCPP_COMPLEX
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    complex synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andrictemplate<class T>
20*0b57cec5SDimitry Andricclass complex
21*0b57cec5SDimitry Andric{
22*0b57cec5SDimitry Andricpublic:
23*0b57cec5SDimitry Andric    typedef T value_type;
24*0b57cec5SDimitry Andric
25*0b57cec5SDimitry Andric    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
26*0b57cec5SDimitry Andric    complex(const complex&);  // constexpr in C++14
27*0b57cec5SDimitry Andric    template<class X> complex(const complex<X>&);  // constexpr in C++14
28*0b57cec5SDimitry Andric
29*0b57cec5SDimitry Andric    T real() const; // constexpr in C++14
30*0b57cec5SDimitry Andric    T imag() const; // constexpr in C++14
31*0b57cec5SDimitry Andric
32*0b57cec5SDimitry Andric    void real(T);
33*0b57cec5SDimitry Andric    void imag(T);
34*0b57cec5SDimitry Andric
35*0b57cec5SDimitry Andric    complex<T>& operator= (const T&);
36*0b57cec5SDimitry Andric    complex<T>& operator+=(const T&);
37*0b57cec5SDimitry Andric    complex<T>& operator-=(const T&);
38*0b57cec5SDimitry Andric    complex<T>& operator*=(const T&);
39*0b57cec5SDimitry Andric    complex<T>& operator/=(const T&);
40*0b57cec5SDimitry Andric
41*0b57cec5SDimitry Andric    complex& operator=(const complex&);
42*0b57cec5SDimitry Andric    template<class X> complex<T>& operator= (const complex<X>&);
43*0b57cec5SDimitry Andric    template<class X> complex<T>& operator+=(const complex<X>&);
44*0b57cec5SDimitry Andric    template<class X> complex<T>& operator-=(const complex<X>&);
45*0b57cec5SDimitry Andric    template<class X> complex<T>& operator*=(const complex<X>&);
46*0b57cec5SDimitry Andric    template<class X> complex<T>& operator/=(const complex<X>&);
47*0b57cec5SDimitry Andric};
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry Andrictemplate<>
50*0b57cec5SDimitry Andricclass complex<float>
51*0b57cec5SDimitry Andric{
52*0b57cec5SDimitry Andricpublic:
53*0b57cec5SDimitry Andric    typedef float value_type;
54*0b57cec5SDimitry Andric
55*0b57cec5SDimitry Andric    constexpr complex(float re = 0.0f, float im = 0.0f);
56*0b57cec5SDimitry Andric    explicit constexpr complex(const complex<double>&);
57*0b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
58*0b57cec5SDimitry Andric
59*0b57cec5SDimitry Andric    constexpr float real() const;
60*0b57cec5SDimitry Andric    void real(float);
61*0b57cec5SDimitry Andric    constexpr float imag() const;
62*0b57cec5SDimitry Andric    void imag(float);
63*0b57cec5SDimitry Andric
64*0b57cec5SDimitry Andric    complex<float>& operator= (float);
65*0b57cec5SDimitry Andric    complex<float>& operator+=(float);
66*0b57cec5SDimitry Andric    complex<float>& operator-=(float);
67*0b57cec5SDimitry Andric    complex<float>& operator*=(float);
68*0b57cec5SDimitry Andric    complex<float>& operator/=(float);
69*0b57cec5SDimitry Andric
70*0b57cec5SDimitry Andric    complex<float>& operator=(const complex<float>&);
71*0b57cec5SDimitry Andric    template<class X> complex<float>& operator= (const complex<X>&);
72*0b57cec5SDimitry Andric    template<class X> complex<float>& operator+=(const complex<X>&);
73*0b57cec5SDimitry Andric    template<class X> complex<float>& operator-=(const complex<X>&);
74*0b57cec5SDimitry Andric    template<class X> complex<float>& operator*=(const complex<X>&);
75*0b57cec5SDimitry Andric    template<class X> complex<float>& operator/=(const complex<X>&);
76*0b57cec5SDimitry Andric};
77*0b57cec5SDimitry Andric
78*0b57cec5SDimitry Andrictemplate<>
79*0b57cec5SDimitry Andricclass complex<double>
80*0b57cec5SDimitry Andric{
81*0b57cec5SDimitry Andricpublic:
82*0b57cec5SDimitry Andric    typedef double value_type;
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric    constexpr complex(double re = 0.0, double im = 0.0);
85*0b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
86*0b57cec5SDimitry Andric    explicit constexpr complex(const complex<long double>&);
87*0b57cec5SDimitry Andric
88*0b57cec5SDimitry Andric    constexpr double real() const;
89*0b57cec5SDimitry Andric    void real(double);
90*0b57cec5SDimitry Andric    constexpr double imag() const;
91*0b57cec5SDimitry Andric    void imag(double);
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andric    complex<double>& operator= (double);
94*0b57cec5SDimitry Andric    complex<double>& operator+=(double);
95*0b57cec5SDimitry Andric    complex<double>& operator-=(double);
96*0b57cec5SDimitry Andric    complex<double>& operator*=(double);
97*0b57cec5SDimitry Andric    complex<double>& operator/=(double);
98*0b57cec5SDimitry Andric    complex<double>& operator=(const complex<double>&);
99*0b57cec5SDimitry Andric
100*0b57cec5SDimitry Andric    template<class X> complex<double>& operator= (const complex<X>&);
101*0b57cec5SDimitry Andric    template<class X> complex<double>& operator+=(const complex<X>&);
102*0b57cec5SDimitry Andric    template<class X> complex<double>& operator-=(const complex<X>&);
103*0b57cec5SDimitry Andric    template<class X> complex<double>& operator*=(const complex<X>&);
104*0b57cec5SDimitry Andric    template<class X> complex<double>& operator/=(const complex<X>&);
105*0b57cec5SDimitry Andric};
106*0b57cec5SDimitry Andric
107*0b57cec5SDimitry Andrictemplate<>
108*0b57cec5SDimitry Andricclass complex<long double>
109*0b57cec5SDimitry Andric{
110*0b57cec5SDimitry Andricpublic:
111*0b57cec5SDimitry Andric    typedef long double value_type;
112*0b57cec5SDimitry Andric
113*0b57cec5SDimitry Andric    constexpr complex(long double re = 0.0L, long double im = 0.0L);
114*0b57cec5SDimitry Andric    constexpr complex(const complex<float>&);
115*0b57cec5SDimitry Andric    constexpr complex(const complex<double>&);
116*0b57cec5SDimitry Andric
117*0b57cec5SDimitry Andric    constexpr long double real() const;
118*0b57cec5SDimitry Andric    void real(long double);
119*0b57cec5SDimitry Andric    constexpr long double imag() const;
120*0b57cec5SDimitry Andric    void imag(long double);
121*0b57cec5SDimitry Andric
122*0b57cec5SDimitry Andric    complex<long double>& operator=(const complex<long double>&);
123*0b57cec5SDimitry Andric    complex<long double>& operator= (long double);
124*0b57cec5SDimitry Andric    complex<long double>& operator+=(long double);
125*0b57cec5SDimitry Andric    complex<long double>& operator-=(long double);
126*0b57cec5SDimitry Andric    complex<long double>& operator*=(long double);
127*0b57cec5SDimitry Andric    complex<long double>& operator/=(long double);
128*0b57cec5SDimitry Andric
129*0b57cec5SDimitry Andric    template<class X> complex<long double>& operator= (const complex<X>&);
130*0b57cec5SDimitry Andric    template<class X> complex<long double>& operator+=(const complex<X>&);
131*0b57cec5SDimitry Andric    template<class X> complex<long double>& operator-=(const complex<X>&);
132*0b57cec5SDimitry Andric    template<class X> complex<long double>& operator*=(const complex<X>&);
133*0b57cec5SDimitry Andric    template<class X> complex<long double>& operator/=(const complex<X>&);
134*0b57cec5SDimitry Andric};
135*0b57cec5SDimitry Andric
136*0b57cec5SDimitry Andric// 26.3.6 operators:
137*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
138*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&, const T&);
139*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const T&, const complex<T>&);
140*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
141*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&, const T&);
142*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const T&, const complex<T>&);
143*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
144*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const complex<T>&, const T&);
145*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator*(const T&, const complex<T>&);
146*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
147*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const complex<T>&, const T&);
148*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator/(const T&, const complex<T>&);
149*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator+(const complex<T>&);
150*0b57cec5SDimitry Andrictemplate<class T> complex<T> operator-(const complex<T>&);
151*0b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
152*0b57cec5SDimitry Andrictemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
153*0b57cec5SDimitry Andrictemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
154*0b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
155*0b57cec5SDimitry Andrictemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
156*0b57cec5SDimitry Andrictemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
157*0b57cec5SDimitry Andric
158*0b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
159*0b57cec5SDimitry Andric  basic_istream<charT, traits>&
160*0b57cec5SDimitry Andric  operator>>(basic_istream<charT, traits>&, complex<T>&);
161*0b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
162*0b57cec5SDimitry Andric  basic_ostream<charT, traits>&
163*0b57cec5SDimitry Andric  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
164*0b57cec5SDimitry Andric
165*0b57cec5SDimitry Andric// 26.3.7 values:
166*0b57cec5SDimitry Andric
167*0b57cec5SDimitry Andrictemplate<class T>              T real(const complex<T>&); // constexpr in C++14
168*0b57cec5SDimitry Andric                     long double real(long double);       // constexpr in C++14
169*0b57cec5SDimitry Andric                          double real(double);            // constexpr in C++14
170*0b57cec5SDimitry Andrictemplate<Integral T>      double real(T);                 // constexpr in C++14
171*0b57cec5SDimitry Andric                          float  real(float);             // constexpr in C++14
172*0b57cec5SDimitry Andric
173*0b57cec5SDimitry Andrictemplate<class T>              T imag(const complex<T>&); // constexpr in C++14
174*0b57cec5SDimitry Andric                     long double imag(long double);       // constexpr in C++14
175*0b57cec5SDimitry Andric                          double imag(double);            // constexpr in C++14
176*0b57cec5SDimitry Andrictemplate<Integral T>      double imag(T);                 // constexpr in C++14
177*0b57cec5SDimitry Andric                          float  imag(float);             // constexpr in C++14
178*0b57cec5SDimitry Andric
179*0b57cec5SDimitry Andrictemplate<class T> T abs(const complex<T>&);
180*0b57cec5SDimitry Andric
181*0b57cec5SDimitry Andrictemplate<class T>              T arg(const complex<T>&);
182*0b57cec5SDimitry Andric                     long double arg(long double);
183*0b57cec5SDimitry Andric                          double arg(double);
184*0b57cec5SDimitry Andrictemplate<Integral T>      double arg(T);
185*0b57cec5SDimitry Andric                          float  arg(float);
186*0b57cec5SDimitry Andric
187*0b57cec5SDimitry Andrictemplate<class T>              T norm(const complex<T>&);
188*0b57cec5SDimitry Andric                     long double norm(long double);
189*0b57cec5SDimitry Andric                          double norm(double);
190*0b57cec5SDimitry Andrictemplate<Integral T>      double norm(T);
191*0b57cec5SDimitry Andric                          float  norm(float);
192*0b57cec5SDimitry Andric
193*0b57cec5SDimitry Andrictemplate<class T>      complex<T>           conj(const complex<T>&);
194*0b57cec5SDimitry Andric                       complex<long double> conj(long double);
195*0b57cec5SDimitry Andric                       complex<double>      conj(double);
196*0b57cec5SDimitry Andrictemplate<Integral T>   complex<double>      conj(T);
197*0b57cec5SDimitry Andric                       complex<float>       conj(float);
198*0b57cec5SDimitry Andric
199*0b57cec5SDimitry Andrictemplate<class T>    complex<T>           proj(const complex<T>&);
200*0b57cec5SDimitry Andric                     complex<long double> proj(long double);
201*0b57cec5SDimitry Andric                     complex<double>      proj(double);
202*0b57cec5SDimitry Andrictemplate<Integral T> complex<double>      proj(T);
203*0b57cec5SDimitry Andric                     complex<float>       proj(float);
204*0b57cec5SDimitry Andric
205*0b57cec5SDimitry Andrictemplate<class T> complex<T> polar(const T&, const T& = T());
206*0b57cec5SDimitry Andric
207*0b57cec5SDimitry Andric// 26.3.8 transcendentals:
208*0b57cec5SDimitry Andrictemplate<class T> complex<T> acos(const complex<T>&);
209*0b57cec5SDimitry Andrictemplate<class T> complex<T> asin(const complex<T>&);
210*0b57cec5SDimitry Andrictemplate<class T> complex<T> atan(const complex<T>&);
211*0b57cec5SDimitry Andrictemplate<class T> complex<T> acosh(const complex<T>&);
212*0b57cec5SDimitry Andrictemplate<class T> complex<T> asinh(const complex<T>&);
213*0b57cec5SDimitry Andrictemplate<class T> complex<T> atanh(const complex<T>&);
214*0b57cec5SDimitry Andrictemplate<class T> complex<T> cos (const complex<T>&);
215*0b57cec5SDimitry Andrictemplate<class T> complex<T> cosh (const complex<T>&);
216*0b57cec5SDimitry Andrictemplate<class T> complex<T> exp (const complex<T>&);
217*0b57cec5SDimitry Andrictemplate<class T> complex<T> log (const complex<T>&);
218*0b57cec5SDimitry Andrictemplate<class T> complex<T> log10(const complex<T>&);
219*0b57cec5SDimitry Andric
220*0b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const T&);
221*0b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);
222*0b57cec5SDimitry Andrictemplate<class T> complex<T> pow(const T&, const complex<T>&);
223*0b57cec5SDimitry Andric
224*0b57cec5SDimitry Andrictemplate<class T> complex<T> sin (const complex<T>&);
225*0b57cec5SDimitry Andrictemplate<class T> complex<T> sinh (const complex<T>&);
226*0b57cec5SDimitry Andrictemplate<class T> complex<T> sqrt (const complex<T>&);
227*0b57cec5SDimitry Andrictemplate<class T> complex<T> tan (const complex<T>&);
228*0b57cec5SDimitry Andrictemplate<class T> complex<T> tanh (const complex<T>&);
229*0b57cec5SDimitry Andric
230*0b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
231*0b57cec5SDimitry Andric  basic_istream<charT, traits>&
232*0b57cec5SDimitry Andric  operator>>(basic_istream<charT, traits>& is, complex<T>& x);
233*0b57cec5SDimitry Andric
234*0b57cec5SDimitry Andrictemplate<class T, class charT, class traits>
235*0b57cec5SDimitry Andric  basic_ostream<charT, traits>&
236*0b57cec5SDimitry Andric  operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);
237*0b57cec5SDimitry Andric
238*0b57cec5SDimitry Andric}  // std
239*0b57cec5SDimitry Andric
240*0b57cec5SDimitry Andric*/
241*0b57cec5SDimitry Andric
242*0b57cec5SDimitry Andric#include <__config>
243*0b57cec5SDimitry Andric#include <type_traits>
244*0b57cec5SDimitry Andric#include <stdexcept>
245*0b57cec5SDimitry Andric#include <cmath>
246*0b57cec5SDimitry Andric#include <sstream>
247*0b57cec5SDimitry Andric#include <version>
248*0b57cec5SDimitry Andric
249*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
250*0b57cec5SDimitry Andric#pragma GCC system_header
251*0b57cec5SDimitry Andric#endif
252*0b57cec5SDimitry Andric
253*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
254*0b57cec5SDimitry Andric
255*0b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
256*0b57cec5SDimitry Andric
257*0b57cec5SDimitry Andrictemplate<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
258*0b57cec5SDimitry Andrictemplate<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
259*0b57cec5SDimitry Andric
260*0b57cec5SDimitry Andrictemplate<class _Tp>
261*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex
262*0b57cec5SDimitry Andric{
263*0b57cec5SDimitry Andricpublic:
264*0b57cec5SDimitry Andric    typedef _Tp value_type;
265*0b57cec5SDimitry Andricprivate:
266*0b57cec5SDimitry Andric    value_type __re_;
267*0b57cec5SDimitry Andric    value_type __im_;
268*0b57cec5SDimitry Andricpublic:
269*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
270*0b57cec5SDimitry Andric    complex(const value_type& __re = value_type(), const value_type& __im = value_type())
271*0b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
272*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
273*0b57cec5SDimitry Andric    complex(const complex<_Xp>& __c)
274*0b57cec5SDimitry Andric        : __re_(__c.real()), __im_(__c.imag()) {}
275*0b57cec5SDimitry Andric
276*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
277*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
278*0b57cec5SDimitry Andric
279*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
280*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
281*0b57cec5SDimitry Andric
282*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
283*0b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
284*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
285*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
286*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
287*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
288*0b57cec5SDimitry Andric
289*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
290*0b57cec5SDimitry Andric        {
291*0b57cec5SDimitry Andric            __re_ = __c.real();
292*0b57cec5SDimitry Andric            __im_ = __c.imag();
293*0b57cec5SDimitry Andric            return *this;
294*0b57cec5SDimitry Andric        }
295*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
296*0b57cec5SDimitry Andric        {
297*0b57cec5SDimitry Andric            __re_ += __c.real();
298*0b57cec5SDimitry Andric            __im_ += __c.imag();
299*0b57cec5SDimitry Andric            return *this;
300*0b57cec5SDimitry Andric        }
301*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
302*0b57cec5SDimitry Andric        {
303*0b57cec5SDimitry Andric            __re_ -= __c.real();
304*0b57cec5SDimitry Andric            __im_ -= __c.imag();
305*0b57cec5SDimitry Andric            return *this;
306*0b57cec5SDimitry Andric        }
307*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
308*0b57cec5SDimitry Andric        {
309*0b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
310*0b57cec5SDimitry Andric            return *this;
311*0b57cec5SDimitry Andric        }
312*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
313*0b57cec5SDimitry Andric        {
314*0b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
315*0b57cec5SDimitry Andric            return *this;
316*0b57cec5SDimitry Andric        }
317*0b57cec5SDimitry Andric};
318*0b57cec5SDimitry Andric
319*0b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>;
320*0b57cec5SDimitry Andrictemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
321*0b57cec5SDimitry Andric
322*0b57cec5SDimitry Andrictemplate<>
323*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<float>
324*0b57cec5SDimitry Andric{
325*0b57cec5SDimitry Andric    float __re_;
326*0b57cec5SDimitry Andric    float __im_;
327*0b57cec5SDimitry Andricpublic:
328*0b57cec5SDimitry Andric    typedef float value_type;
329*0b57cec5SDimitry Andric
330*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
331*0b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
332*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
333*0b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
334*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
335*0b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
336*0b57cec5SDimitry Andric
337*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
338*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
339*0b57cec5SDimitry Andric
340*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
341*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
342*0b57cec5SDimitry Andric
343*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
344*0b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
345*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
346*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
347*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
348*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
349*0b57cec5SDimitry Andric
350*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
351*0b57cec5SDimitry Andric        {
352*0b57cec5SDimitry Andric            __re_ = __c.real();
353*0b57cec5SDimitry Andric            __im_ = __c.imag();
354*0b57cec5SDimitry Andric            return *this;
355*0b57cec5SDimitry Andric        }
356*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
357*0b57cec5SDimitry Andric        {
358*0b57cec5SDimitry Andric            __re_ += __c.real();
359*0b57cec5SDimitry Andric            __im_ += __c.imag();
360*0b57cec5SDimitry Andric            return *this;
361*0b57cec5SDimitry Andric        }
362*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
363*0b57cec5SDimitry Andric        {
364*0b57cec5SDimitry Andric            __re_ -= __c.real();
365*0b57cec5SDimitry Andric            __im_ -= __c.imag();
366*0b57cec5SDimitry Andric            return *this;
367*0b57cec5SDimitry Andric        }
368*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
369*0b57cec5SDimitry Andric        {
370*0b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
371*0b57cec5SDimitry Andric            return *this;
372*0b57cec5SDimitry Andric        }
373*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
374*0b57cec5SDimitry Andric        {
375*0b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
376*0b57cec5SDimitry Andric            return *this;
377*0b57cec5SDimitry Andric        }
378*0b57cec5SDimitry Andric};
379*0b57cec5SDimitry Andric
380*0b57cec5SDimitry Andrictemplate<>
381*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<double>
382*0b57cec5SDimitry Andric{
383*0b57cec5SDimitry Andric    double __re_;
384*0b57cec5SDimitry Andric    double __im_;
385*0b57cec5SDimitry Andricpublic:
386*0b57cec5SDimitry Andric    typedef double value_type;
387*0b57cec5SDimitry Andric
388*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
389*0b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
390*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
391*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
392*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
393*0b57cec5SDimitry Andric    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
394*0b57cec5SDimitry Andric
395*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
396*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
397*0b57cec5SDimitry Andric
398*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
399*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
400*0b57cec5SDimitry Andric
401*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
402*0b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
403*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
404*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
405*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
406*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
407*0b57cec5SDimitry Andric
408*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
409*0b57cec5SDimitry Andric        {
410*0b57cec5SDimitry Andric            __re_ = __c.real();
411*0b57cec5SDimitry Andric            __im_ = __c.imag();
412*0b57cec5SDimitry Andric            return *this;
413*0b57cec5SDimitry Andric        }
414*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
415*0b57cec5SDimitry Andric        {
416*0b57cec5SDimitry Andric            __re_ += __c.real();
417*0b57cec5SDimitry Andric            __im_ += __c.imag();
418*0b57cec5SDimitry Andric            return *this;
419*0b57cec5SDimitry Andric        }
420*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
421*0b57cec5SDimitry Andric        {
422*0b57cec5SDimitry Andric            __re_ -= __c.real();
423*0b57cec5SDimitry Andric            __im_ -= __c.imag();
424*0b57cec5SDimitry Andric            return *this;
425*0b57cec5SDimitry Andric        }
426*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
427*0b57cec5SDimitry Andric        {
428*0b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
429*0b57cec5SDimitry Andric            return *this;
430*0b57cec5SDimitry Andric        }
431*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
432*0b57cec5SDimitry Andric        {
433*0b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
434*0b57cec5SDimitry Andric            return *this;
435*0b57cec5SDimitry Andric        }
436*0b57cec5SDimitry Andric};
437*0b57cec5SDimitry Andric
438*0b57cec5SDimitry Andrictemplate<>
439*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS complex<long double>
440*0b57cec5SDimitry Andric{
441*0b57cec5SDimitry Andric    long double __re_;
442*0b57cec5SDimitry Andric    long double __im_;
443*0b57cec5SDimitry Andricpublic:
444*0b57cec5SDimitry Andric    typedef long double value_type;
445*0b57cec5SDimitry Andric
446*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
447*0b57cec5SDimitry Andric        : __re_(__re), __im_(__im) {}
448*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
449*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
450*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
451*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
452*0b57cec5SDimitry Andric
453*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
454*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
455*0b57cec5SDimitry Andric
456*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
457*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
458*0b57cec5SDimitry Andric
459*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
460*0b57cec5SDimitry Andric        {__re_ = __re; __im_ = value_type(); return *this;}
461*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
462*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
463*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
464*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
465*0b57cec5SDimitry Andric
466*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
467*0b57cec5SDimitry Andric        {
468*0b57cec5SDimitry Andric            __re_ = __c.real();
469*0b57cec5SDimitry Andric            __im_ = __c.imag();
470*0b57cec5SDimitry Andric            return *this;
471*0b57cec5SDimitry Andric        }
472*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
473*0b57cec5SDimitry Andric        {
474*0b57cec5SDimitry Andric            __re_ += __c.real();
475*0b57cec5SDimitry Andric            __im_ += __c.imag();
476*0b57cec5SDimitry Andric            return *this;
477*0b57cec5SDimitry Andric        }
478*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
479*0b57cec5SDimitry Andric        {
480*0b57cec5SDimitry Andric            __re_ -= __c.real();
481*0b57cec5SDimitry Andric            __im_ -= __c.imag();
482*0b57cec5SDimitry Andric            return *this;
483*0b57cec5SDimitry Andric        }
484*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
485*0b57cec5SDimitry Andric        {
486*0b57cec5SDimitry Andric            *this = *this * complex(__c.real(), __c.imag());
487*0b57cec5SDimitry Andric            return *this;
488*0b57cec5SDimitry Andric        }
489*0b57cec5SDimitry Andric    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
490*0b57cec5SDimitry Andric        {
491*0b57cec5SDimitry Andric            *this = *this / complex(__c.real(), __c.imag());
492*0b57cec5SDimitry Andric            return *this;
493*0b57cec5SDimitry Andric        }
494*0b57cec5SDimitry Andric};
495*0b57cec5SDimitry Andric
496*0b57cec5SDimitry Andricinline
497*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
498*0b57cec5SDimitry Andriccomplex<float>::complex(const complex<double>& __c)
499*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
500*0b57cec5SDimitry Andric
501*0b57cec5SDimitry Andricinline
502*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
503*0b57cec5SDimitry Andriccomplex<float>::complex(const complex<long double>& __c)
504*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
505*0b57cec5SDimitry Andric
506*0b57cec5SDimitry Andricinline
507*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
508*0b57cec5SDimitry Andriccomplex<double>::complex(const complex<float>& __c)
509*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
510*0b57cec5SDimitry Andric
511*0b57cec5SDimitry Andricinline
512*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
513*0b57cec5SDimitry Andriccomplex<double>::complex(const complex<long double>& __c)
514*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
515*0b57cec5SDimitry Andric
516*0b57cec5SDimitry Andricinline
517*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
518*0b57cec5SDimitry Andriccomplex<long double>::complex(const complex<float>& __c)
519*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
520*0b57cec5SDimitry Andric
521*0b57cec5SDimitry Andricinline
522*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
523*0b57cec5SDimitry Andriccomplex<long double>::complex(const complex<double>& __c)
524*0b57cec5SDimitry Andric    : __re_(__c.real()), __im_(__c.imag()) {}
525*0b57cec5SDimitry Andric
526*0b57cec5SDimitry Andric// 26.3.6 operators:
527*0b57cec5SDimitry Andric
528*0b57cec5SDimitry Andrictemplate<class _Tp>
529*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
530*0b57cec5SDimitry Andriccomplex<_Tp>
531*0b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
532*0b57cec5SDimitry Andric{
533*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
534*0b57cec5SDimitry Andric    __t += __y;
535*0b57cec5SDimitry Andric    return __t;
536*0b57cec5SDimitry Andric}
537*0b57cec5SDimitry Andric
538*0b57cec5SDimitry Andrictemplate<class _Tp>
539*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
540*0b57cec5SDimitry Andriccomplex<_Tp>
541*0b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x, const _Tp& __y)
542*0b57cec5SDimitry Andric{
543*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
544*0b57cec5SDimitry Andric    __t += __y;
545*0b57cec5SDimitry Andric    return __t;
546*0b57cec5SDimitry Andric}
547*0b57cec5SDimitry Andric
548*0b57cec5SDimitry Andrictemplate<class _Tp>
549*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
550*0b57cec5SDimitry Andriccomplex<_Tp>
551*0b57cec5SDimitry Andricoperator+(const _Tp& __x, const complex<_Tp>& __y)
552*0b57cec5SDimitry Andric{
553*0b57cec5SDimitry Andric    complex<_Tp> __t(__y);
554*0b57cec5SDimitry Andric    __t += __x;
555*0b57cec5SDimitry Andric    return __t;
556*0b57cec5SDimitry Andric}
557*0b57cec5SDimitry Andric
558*0b57cec5SDimitry Andrictemplate<class _Tp>
559*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
560*0b57cec5SDimitry Andriccomplex<_Tp>
561*0b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
562*0b57cec5SDimitry Andric{
563*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
564*0b57cec5SDimitry Andric    __t -= __y;
565*0b57cec5SDimitry Andric    return __t;
566*0b57cec5SDimitry Andric}
567*0b57cec5SDimitry Andric
568*0b57cec5SDimitry Andrictemplate<class _Tp>
569*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
570*0b57cec5SDimitry Andriccomplex<_Tp>
571*0b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x, const _Tp& __y)
572*0b57cec5SDimitry Andric{
573*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
574*0b57cec5SDimitry Andric    __t -= __y;
575*0b57cec5SDimitry Andric    return __t;
576*0b57cec5SDimitry Andric}
577*0b57cec5SDimitry Andric
578*0b57cec5SDimitry Andrictemplate<class _Tp>
579*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
580*0b57cec5SDimitry Andriccomplex<_Tp>
581*0b57cec5SDimitry Andricoperator-(const _Tp& __x, const complex<_Tp>& __y)
582*0b57cec5SDimitry Andric{
583*0b57cec5SDimitry Andric    complex<_Tp> __t(-__y);
584*0b57cec5SDimitry Andric    __t += __x;
585*0b57cec5SDimitry Andric    return __t;
586*0b57cec5SDimitry Andric}
587*0b57cec5SDimitry Andric
588*0b57cec5SDimitry Andrictemplate<class _Tp>
589*0b57cec5SDimitry Andriccomplex<_Tp>
590*0b57cec5SDimitry Andricoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
591*0b57cec5SDimitry Andric{
592*0b57cec5SDimitry Andric    _Tp __a = __z.real();
593*0b57cec5SDimitry Andric    _Tp __b = __z.imag();
594*0b57cec5SDimitry Andric    _Tp __c = __w.real();
595*0b57cec5SDimitry Andric    _Tp __d = __w.imag();
596*0b57cec5SDimitry Andric    _Tp __ac = __a * __c;
597*0b57cec5SDimitry Andric    _Tp __bd = __b * __d;
598*0b57cec5SDimitry Andric    _Tp __ad = __a * __d;
599*0b57cec5SDimitry Andric    _Tp __bc = __b * __c;
600*0b57cec5SDimitry Andric    _Tp __x = __ac - __bd;
601*0b57cec5SDimitry Andric    _Tp __y = __ad + __bc;
602*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
603*0b57cec5SDimitry Andric    {
604*0b57cec5SDimitry Andric        bool __recalc = false;
605*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b))
606*0b57cec5SDimitry Andric        {
607*0b57cec5SDimitry Andric            __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
608*0b57cec5SDimitry Andric            __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
609*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__c))
610*0b57cec5SDimitry Andric                __c = copysign(_Tp(0), __c);
611*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__d))
612*0b57cec5SDimitry Andric                __d = copysign(_Tp(0), __d);
613*0b57cec5SDimitry Andric            __recalc = true;
614*0b57cec5SDimitry Andric        }
615*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d))
616*0b57cec5SDimitry Andric        {
617*0b57cec5SDimitry Andric            __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
618*0b57cec5SDimitry Andric            __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
619*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__a))
620*0b57cec5SDimitry Andric                __a = copysign(_Tp(0), __a);
621*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__b))
622*0b57cec5SDimitry Andric                __b = copysign(_Tp(0), __b);
623*0b57cec5SDimitry Andric            __recalc = true;
624*0b57cec5SDimitry Andric        }
625*0b57cec5SDimitry Andric        if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) ||
626*0b57cec5SDimitry Andric                          __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc)))
627*0b57cec5SDimitry Andric        {
628*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__a))
629*0b57cec5SDimitry Andric                __a = copysign(_Tp(0), __a);
630*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__b))
631*0b57cec5SDimitry Andric                __b = copysign(_Tp(0), __b);
632*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__c))
633*0b57cec5SDimitry Andric                __c = copysign(_Tp(0), __c);
634*0b57cec5SDimitry Andric            if (__libcpp_isnan_or_builtin(__d))
635*0b57cec5SDimitry Andric                __d = copysign(_Tp(0), __d);
636*0b57cec5SDimitry Andric            __recalc = true;
637*0b57cec5SDimitry Andric        }
638*0b57cec5SDimitry Andric        if (__recalc)
639*0b57cec5SDimitry Andric        {
640*0b57cec5SDimitry Andric            __x = _Tp(INFINITY) * (__a * __c - __b * __d);
641*0b57cec5SDimitry Andric            __y = _Tp(INFINITY) * (__a * __d + __b * __c);
642*0b57cec5SDimitry Andric        }
643*0b57cec5SDimitry Andric    }
644*0b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
645*0b57cec5SDimitry Andric}
646*0b57cec5SDimitry Andric
647*0b57cec5SDimitry Andrictemplate<class _Tp>
648*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
649*0b57cec5SDimitry Andriccomplex<_Tp>
650*0b57cec5SDimitry Andricoperator*(const complex<_Tp>& __x, const _Tp& __y)
651*0b57cec5SDimitry Andric{
652*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
653*0b57cec5SDimitry Andric    __t *= __y;
654*0b57cec5SDimitry Andric    return __t;
655*0b57cec5SDimitry Andric}
656*0b57cec5SDimitry Andric
657*0b57cec5SDimitry Andrictemplate<class _Tp>
658*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
659*0b57cec5SDimitry Andriccomplex<_Tp>
660*0b57cec5SDimitry Andricoperator*(const _Tp& __x, const complex<_Tp>& __y)
661*0b57cec5SDimitry Andric{
662*0b57cec5SDimitry Andric    complex<_Tp> __t(__y);
663*0b57cec5SDimitry Andric    __t *= __x;
664*0b57cec5SDimitry Andric    return __t;
665*0b57cec5SDimitry Andric}
666*0b57cec5SDimitry Andric
667*0b57cec5SDimitry Andrictemplate<class _Tp>
668*0b57cec5SDimitry Andriccomplex<_Tp>
669*0b57cec5SDimitry Andricoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
670*0b57cec5SDimitry Andric{
671*0b57cec5SDimitry Andric    int __ilogbw = 0;
672*0b57cec5SDimitry Andric    _Tp __a = __z.real();
673*0b57cec5SDimitry Andric    _Tp __b = __z.imag();
674*0b57cec5SDimitry Andric    _Tp __c = __w.real();
675*0b57cec5SDimitry Andric    _Tp __d = __w.imag();
676*0b57cec5SDimitry Andric    _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
677*0b57cec5SDimitry Andric    if (__libcpp_isfinite_or_builtin(__logbw))
678*0b57cec5SDimitry Andric    {
679*0b57cec5SDimitry Andric        __ilogbw = static_cast<int>(__logbw);
680*0b57cec5SDimitry Andric        __c = scalbn(__c, -__ilogbw);
681*0b57cec5SDimitry Andric        __d = scalbn(__d, -__ilogbw);
682*0b57cec5SDimitry Andric    }
683*0b57cec5SDimitry Andric    _Tp __denom = __c * __c + __d * __d;
684*0b57cec5SDimitry Andric    _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
685*0b57cec5SDimitry Andric    _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
686*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
687*0b57cec5SDimitry Andric    {
688*0b57cec5SDimitry Andric        if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b)))
689*0b57cec5SDimitry Andric        {
690*0b57cec5SDimitry Andric            __x = copysign(_Tp(INFINITY), __c) * __a;
691*0b57cec5SDimitry Andric            __y = copysign(_Tp(INFINITY), __c) * __b;
692*0b57cec5SDimitry Andric        }
693*0b57cec5SDimitry Andric        else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d))
694*0b57cec5SDimitry Andric        {
695*0b57cec5SDimitry Andric            __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
696*0b57cec5SDimitry Andric            __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
697*0b57cec5SDimitry Andric            __x = _Tp(INFINITY) * (__a * __c + __b * __d);
698*0b57cec5SDimitry Andric            __y = _Tp(INFINITY) * (__b * __c - __a * __d);
699*0b57cec5SDimitry Andric        }
700*0b57cec5SDimitry Andric        else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b))
701*0b57cec5SDimitry Andric        {
702*0b57cec5SDimitry Andric            __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
703*0b57cec5SDimitry Andric            __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
704*0b57cec5SDimitry Andric            __x = _Tp(0) * (__a * __c + __b * __d);
705*0b57cec5SDimitry Andric            __y = _Tp(0) * (__b * __c - __a * __d);
706*0b57cec5SDimitry Andric        }
707*0b57cec5SDimitry Andric    }
708*0b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
709*0b57cec5SDimitry Andric}
710*0b57cec5SDimitry Andric
711*0b57cec5SDimitry Andrictemplate<class _Tp>
712*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
713*0b57cec5SDimitry Andriccomplex<_Tp>
714*0b57cec5SDimitry Andricoperator/(const complex<_Tp>& __x, const _Tp& __y)
715*0b57cec5SDimitry Andric{
716*0b57cec5SDimitry Andric    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
717*0b57cec5SDimitry Andric}
718*0b57cec5SDimitry Andric
719*0b57cec5SDimitry Andrictemplate<class _Tp>
720*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
721*0b57cec5SDimitry Andriccomplex<_Tp>
722*0b57cec5SDimitry Andricoperator/(const _Tp& __x, const complex<_Tp>& __y)
723*0b57cec5SDimitry Andric{
724*0b57cec5SDimitry Andric    complex<_Tp> __t(__x);
725*0b57cec5SDimitry Andric    __t /= __y;
726*0b57cec5SDimitry Andric    return __t;
727*0b57cec5SDimitry Andric}
728*0b57cec5SDimitry Andric
729*0b57cec5SDimitry Andrictemplate<class _Tp>
730*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
731*0b57cec5SDimitry Andriccomplex<_Tp>
732*0b57cec5SDimitry Andricoperator+(const complex<_Tp>& __x)
733*0b57cec5SDimitry Andric{
734*0b57cec5SDimitry Andric    return __x;
735*0b57cec5SDimitry Andric}
736*0b57cec5SDimitry Andric
737*0b57cec5SDimitry Andrictemplate<class _Tp>
738*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
739*0b57cec5SDimitry Andriccomplex<_Tp>
740*0b57cec5SDimitry Andricoperator-(const complex<_Tp>& __x)
741*0b57cec5SDimitry Andric{
742*0b57cec5SDimitry Andric    return complex<_Tp>(-__x.real(), -__x.imag());
743*0b57cec5SDimitry Andric}
744*0b57cec5SDimitry Andric
745*0b57cec5SDimitry Andrictemplate<class _Tp>
746*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
747*0b57cec5SDimitry Andricbool
748*0b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
749*0b57cec5SDimitry Andric{
750*0b57cec5SDimitry Andric    return __x.real() == __y.real() && __x.imag() == __y.imag();
751*0b57cec5SDimitry Andric}
752*0b57cec5SDimitry Andric
753*0b57cec5SDimitry Andrictemplate<class _Tp>
754*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
755*0b57cec5SDimitry Andricbool
756*0b57cec5SDimitry Andricoperator==(const complex<_Tp>& __x, const _Tp& __y)
757*0b57cec5SDimitry Andric{
758*0b57cec5SDimitry Andric    return __x.real() == __y && __x.imag() == 0;
759*0b57cec5SDimitry Andric}
760*0b57cec5SDimitry Andric
761*0b57cec5SDimitry Andrictemplate<class _Tp>
762*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
763*0b57cec5SDimitry Andricbool
764*0b57cec5SDimitry Andricoperator==(const _Tp& __x, const complex<_Tp>& __y)
765*0b57cec5SDimitry Andric{
766*0b57cec5SDimitry Andric    return __x == __y.real() && 0 == __y.imag();
767*0b57cec5SDimitry Andric}
768*0b57cec5SDimitry Andric
769*0b57cec5SDimitry Andrictemplate<class _Tp>
770*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
771*0b57cec5SDimitry Andricbool
772*0b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
773*0b57cec5SDimitry Andric{
774*0b57cec5SDimitry Andric    return !(__x == __y);
775*0b57cec5SDimitry Andric}
776*0b57cec5SDimitry Andric
777*0b57cec5SDimitry Andrictemplate<class _Tp>
778*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
779*0b57cec5SDimitry Andricbool
780*0b57cec5SDimitry Andricoperator!=(const complex<_Tp>& __x, const _Tp& __y)
781*0b57cec5SDimitry Andric{
782*0b57cec5SDimitry Andric    return !(__x == __y);
783*0b57cec5SDimitry Andric}
784*0b57cec5SDimitry Andric
785*0b57cec5SDimitry Andrictemplate<class _Tp>
786*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
787*0b57cec5SDimitry Andricbool
788*0b57cec5SDimitry Andricoperator!=(const _Tp& __x, const complex<_Tp>& __y)
789*0b57cec5SDimitry Andric{
790*0b57cec5SDimitry Andric    return !(__x == __y);
791*0b57cec5SDimitry Andric}
792*0b57cec5SDimitry Andric
793*0b57cec5SDimitry Andric// 26.3.7 values:
794*0b57cec5SDimitry Andric
795*0b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value,
796*0b57cec5SDimitry Andric                     bool = is_floating_point<_Tp>::value
797*0b57cec5SDimitry Andric                     >
798*0b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits {};
799*0b57cec5SDimitry Andric
800*0b57cec5SDimitry Andric// Integral Types
801*0b57cec5SDimitry Andrictemplate <class _Tp>
802*0b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, true, false>
803*0b57cec5SDimitry Andric{
804*0b57cec5SDimitry Andric    typedef double _ValueType;
805*0b57cec5SDimitry Andric    typedef complex<double> _ComplexType;
806*0b57cec5SDimitry Andric};
807*0b57cec5SDimitry Andric
808*0b57cec5SDimitry Andric// Floating point types
809*0b57cec5SDimitry Andrictemplate <class _Tp>
810*0b57cec5SDimitry Andricstruct __libcpp_complex_overload_traits<_Tp, false, true>
811*0b57cec5SDimitry Andric{
812*0b57cec5SDimitry Andric    typedef _Tp _ValueType;
813*0b57cec5SDimitry Andric    typedef complex<_Tp> _ComplexType;
814*0b57cec5SDimitry Andric};
815*0b57cec5SDimitry Andric
816*0b57cec5SDimitry Andric// real
817*0b57cec5SDimitry Andric
818*0b57cec5SDimitry Andrictemplate<class _Tp>
819*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
820*0b57cec5SDimitry Andric_Tp
821*0b57cec5SDimitry Andricreal(const complex<_Tp>& __c)
822*0b57cec5SDimitry Andric{
823*0b57cec5SDimitry Andric    return __c.real();
824*0b57cec5SDimitry Andric}
825*0b57cec5SDimitry Andric
826*0b57cec5SDimitry Andrictemplate <class _Tp>
827*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
828*0b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
829*0b57cec5SDimitry Andricreal(_Tp __re)
830*0b57cec5SDimitry Andric{
831*0b57cec5SDimitry Andric    return __re;
832*0b57cec5SDimitry Andric}
833*0b57cec5SDimitry Andric
834*0b57cec5SDimitry Andric// imag
835*0b57cec5SDimitry Andric
836*0b57cec5SDimitry Andrictemplate<class _Tp>
837*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
838*0b57cec5SDimitry Andric_Tp
839*0b57cec5SDimitry Andricimag(const complex<_Tp>& __c)
840*0b57cec5SDimitry Andric{
841*0b57cec5SDimitry Andric    return __c.imag();
842*0b57cec5SDimitry Andric}
843*0b57cec5SDimitry Andric
844*0b57cec5SDimitry Andrictemplate <class _Tp>
845*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
846*0b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
847*0b57cec5SDimitry Andricimag(_Tp)
848*0b57cec5SDimitry Andric{
849*0b57cec5SDimitry Andric    return 0;
850*0b57cec5SDimitry Andric}
851*0b57cec5SDimitry Andric
852*0b57cec5SDimitry Andric// abs
853*0b57cec5SDimitry Andric
854*0b57cec5SDimitry Andrictemplate<class _Tp>
855*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
856*0b57cec5SDimitry Andric_Tp
857*0b57cec5SDimitry Andricabs(const complex<_Tp>& __c)
858*0b57cec5SDimitry Andric{
859*0b57cec5SDimitry Andric    return hypot(__c.real(), __c.imag());
860*0b57cec5SDimitry Andric}
861*0b57cec5SDimitry Andric
862*0b57cec5SDimitry Andric// arg
863*0b57cec5SDimitry Andric
864*0b57cec5SDimitry Andrictemplate<class _Tp>
865*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
866*0b57cec5SDimitry Andric_Tp
867*0b57cec5SDimitry Andricarg(const complex<_Tp>& __c)
868*0b57cec5SDimitry Andric{
869*0b57cec5SDimitry Andric    return atan2(__c.imag(), __c.real());
870*0b57cec5SDimitry Andric}
871*0b57cec5SDimitry Andric
872*0b57cec5SDimitry Andrictemplate <class _Tp>
873*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
874*0b57cec5SDimitry Andrictypename enable_if<
875*0b57cec5SDimitry Andric    is_same<_Tp, long double>::value,
876*0b57cec5SDimitry Andric    long double
877*0b57cec5SDimitry Andric>::type
878*0b57cec5SDimitry Andricarg(_Tp __re)
879*0b57cec5SDimitry Andric{
880*0b57cec5SDimitry Andric    return atan2l(0.L, __re);
881*0b57cec5SDimitry Andric}
882*0b57cec5SDimitry Andric
883*0b57cec5SDimitry Andrictemplate<class _Tp>
884*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
885*0b57cec5SDimitry Andrictypename enable_if
886*0b57cec5SDimitry Andric<
887*0b57cec5SDimitry Andric    is_integral<_Tp>::value || is_same<_Tp, double>::value,
888*0b57cec5SDimitry Andric    double
889*0b57cec5SDimitry Andric>::type
890*0b57cec5SDimitry Andricarg(_Tp __re)
891*0b57cec5SDimitry Andric{
892*0b57cec5SDimitry Andric    return atan2(0., __re);
893*0b57cec5SDimitry Andric}
894*0b57cec5SDimitry Andric
895*0b57cec5SDimitry Andrictemplate <class _Tp>
896*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
897*0b57cec5SDimitry Andrictypename enable_if<
898*0b57cec5SDimitry Andric    is_same<_Tp, float>::value,
899*0b57cec5SDimitry Andric    float
900*0b57cec5SDimitry Andric>::type
901*0b57cec5SDimitry Andricarg(_Tp __re)
902*0b57cec5SDimitry Andric{
903*0b57cec5SDimitry Andric    return atan2f(0.F, __re);
904*0b57cec5SDimitry Andric}
905*0b57cec5SDimitry Andric
906*0b57cec5SDimitry Andric// norm
907*0b57cec5SDimitry Andric
908*0b57cec5SDimitry Andrictemplate<class _Tp>
909*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
910*0b57cec5SDimitry Andric_Tp
911*0b57cec5SDimitry Andricnorm(const complex<_Tp>& __c)
912*0b57cec5SDimitry Andric{
913*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__c.real()))
914*0b57cec5SDimitry Andric        return abs(__c.real());
915*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__c.imag()))
916*0b57cec5SDimitry Andric        return abs(__c.imag());
917*0b57cec5SDimitry Andric    return __c.real() * __c.real() + __c.imag() * __c.imag();
918*0b57cec5SDimitry Andric}
919*0b57cec5SDimitry Andric
920*0b57cec5SDimitry Andrictemplate <class _Tp>
921*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
922*0b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ValueType
923*0b57cec5SDimitry Andricnorm(_Tp __re)
924*0b57cec5SDimitry Andric{
925*0b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
926*0b57cec5SDimitry Andric    return static_cast<_ValueType>(__re) * __re;
927*0b57cec5SDimitry Andric}
928*0b57cec5SDimitry Andric
929*0b57cec5SDimitry Andric// conj
930*0b57cec5SDimitry Andric
931*0b57cec5SDimitry Andrictemplate<class _Tp>
932*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
933*0b57cec5SDimitry Andriccomplex<_Tp>
934*0b57cec5SDimitry Andricconj(const complex<_Tp>& __c)
935*0b57cec5SDimitry Andric{
936*0b57cec5SDimitry Andric    return complex<_Tp>(__c.real(), -__c.imag());
937*0b57cec5SDimitry Andric}
938*0b57cec5SDimitry Andric
939*0b57cec5SDimitry Andrictemplate <class _Tp>
940*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
941*0b57cec5SDimitry Andrictypename __libcpp_complex_overload_traits<_Tp>::_ComplexType
942*0b57cec5SDimitry Andricconj(_Tp __re)
943*0b57cec5SDimitry Andric{
944*0b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
945*0b57cec5SDimitry Andric    return _ComplexType(__re);
946*0b57cec5SDimitry Andric}
947*0b57cec5SDimitry Andric
948*0b57cec5SDimitry Andric
949*0b57cec5SDimitry Andric
950*0b57cec5SDimitry Andric// proj
951*0b57cec5SDimitry Andric
952*0b57cec5SDimitry Andrictemplate<class _Tp>
953*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
954*0b57cec5SDimitry Andriccomplex<_Tp>
955*0b57cec5SDimitry Andricproj(const complex<_Tp>& __c)
956*0b57cec5SDimitry Andric{
957*0b57cec5SDimitry Andric    std::complex<_Tp> __r = __c;
958*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag()))
959*0b57cec5SDimitry Andric        __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
960*0b57cec5SDimitry Andric    return __r;
961*0b57cec5SDimitry Andric}
962*0b57cec5SDimitry Andric
963*0b57cec5SDimitry Andrictemplate <class _Tp>
964*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
965*0b57cec5SDimitry Andrictypename enable_if
966*0b57cec5SDimitry Andric<
967*0b57cec5SDimitry Andric    is_floating_point<_Tp>::value,
968*0b57cec5SDimitry Andric    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
969*0b57cec5SDimitry Andric>::type
970*0b57cec5SDimitry Andricproj(_Tp __re)
971*0b57cec5SDimitry Andric{
972*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__re))
973*0b57cec5SDimitry Andric        __re = abs(__re);
974*0b57cec5SDimitry Andric    return complex<_Tp>(__re);
975*0b57cec5SDimitry Andric}
976*0b57cec5SDimitry Andric
977*0b57cec5SDimitry Andrictemplate <class _Tp>
978*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
979*0b57cec5SDimitry Andrictypename enable_if
980*0b57cec5SDimitry Andric<
981*0b57cec5SDimitry Andric    is_integral<_Tp>::value,
982*0b57cec5SDimitry Andric    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
983*0b57cec5SDimitry Andric>::type
984*0b57cec5SDimitry Andricproj(_Tp __re)
985*0b57cec5SDimitry Andric{
986*0b57cec5SDimitry Andric    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
987*0b57cec5SDimitry Andric    return _ComplexType(__re);
988*0b57cec5SDimitry Andric}
989*0b57cec5SDimitry Andric
990*0b57cec5SDimitry Andric// polar
991*0b57cec5SDimitry Andric
992*0b57cec5SDimitry Andrictemplate<class _Tp>
993*0b57cec5SDimitry Andriccomplex<_Tp>
994*0b57cec5SDimitry Andricpolar(const _Tp& __rho, const _Tp& __theta = _Tp())
995*0b57cec5SDimitry Andric{
996*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho))
997*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
998*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__theta))
999*0b57cec5SDimitry Andric    {
1000*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__rho))
1001*0b57cec5SDimitry Andric            return complex<_Tp>(__rho, __theta);
1002*0b57cec5SDimitry Andric        return complex<_Tp>(__theta, __theta);
1003*0b57cec5SDimitry Andric    }
1004*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__theta))
1005*0b57cec5SDimitry Andric    {
1006*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__rho))
1007*0b57cec5SDimitry Andric            return complex<_Tp>(__rho, _Tp(NAN));
1008*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1009*0b57cec5SDimitry Andric    }
1010*0b57cec5SDimitry Andric    _Tp __x = __rho * cos(__theta);
1011*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x))
1012*0b57cec5SDimitry Andric        __x = 0;
1013*0b57cec5SDimitry Andric    _Tp __y = __rho * sin(__theta);
1014*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__y))
1015*0b57cec5SDimitry Andric        __y = 0;
1016*0b57cec5SDimitry Andric    return complex<_Tp>(__x, __y);
1017*0b57cec5SDimitry Andric}
1018*0b57cec5SDimitry Andric
1019*0b57cec5SDimitry Andric// log
1020*0b57cec5SDimitry Andric
1021*0b57cec5SDimitry Andrictemplate<class _Tp>
1022*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1023*0b57cec5SDimitry Andriccomplex<_Tp>
1024*0b57cec5SDimitry Andriclog(const complex<_Tp>& __x)
1025*0b57cec5SDimitry Andric{
1026*0b57cec5SDimitry Andric    return complex<_Tp>(log(abs(__x)), arg(__x));
1027*0b57cec5SDimitry Andric}
1028*0b57cec5SDimitry Andric
1029*0b57cec5SDimitry Andric// log10
1030*0b57cec5SDimitry Andric
1031*0b57cec5SDimitry Andrictemplate<class _Tp>
1032*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1033*0b57cec5SDimitry Andriccomplex<_Tp>
1034*0b57cec5SDimitry Andriclog10(const complex<_Tp>& __x)
1035*0b57cec5SDimitry Andric{
1036*0b57cec5SDimitry Andric    return log(__x) / log(_Tp(10));
1037*0b57cec5SDimitry Andric}
1038*0b57cec5SDimitry Andric
1039*0b57cec5SDimitry Andric// sqrt
1040*0b57cec5SDimitry Andric
1041*0b57cec5SDimitry Andrictemplate<class _Tp>
1042*0b57cec5SDimitry Andriccomplex<_Tp>
1043*0b57cec5SDimitry Andricsqrt(const complex<_Tp>& __x)
1044*0b57cec5SDimitry Andric{
1045*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.imag()))
1046*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(INFINITY), __x.imag());
1047*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1048*0b57cec5SDimitry Andric    {
1049*0b57cec5SDimitry Andric        if (__x.real() > _Tp(0))
1050*0b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1051*0b57cec5SDimitry Andric        return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
1052*0b57cec5SDimitry Andric    }
1053*0b57cec5SDimitry Andric    return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
1054*0b57cec5SDimitry Andric}
1055*0b57cec5SDimitry Andric
1056*0b57cec5SDimitry Andric// exp
1057*0b57cec5SDimitry Andric
1058*0b57cec5SDimitry Andrictemplate<class _Tp>
1059*0b57cec5SDimitry Andriccomplex<_Tp>
1060*0b57cec5SDimitry Andricexp(const complex<_Tp>& __x)
1061*0b57cec5SDimitry Andric{
1062*0b57cec5SDimitry Andric    _Tp __i = __x.imag();
1063*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1064*0b57cec5SDimitry Andric    {
1065*0b57cec5SDimitry Andric        if (__x.real() < _Tp(0))
1066*0b57cec5SDimitry Andric        {
1067*0b57cec5SDimitry Andric            if (!__libcpp_isfinite_or_builtin(__i))
1068*0b57cec5SDimitry Andric                __i = _Tp(1);
1069*0b57cec5SDimitry Andric        }
1070*0b57cec5SDimitry Andric        else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i))
1071*0b57cec5SDimitry Andric        {
1072*0b57cec5SDimitry Andric            if (__libcpp_isinf_or_builtin(__i))
1073*0b57cec5SDimitry Andric                __i = _Tp(NAN);
1074*0b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), __i);
1075*0b57cec5SDimitry Andric        }
1076*0b57cec5SDimitry Andric    }
1077*0b57cec5SDimitry Andric    else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
1078*0b57cec5SDimitry Andric        return __x;
1079*0b57cec5SDimitry Andric    _Tp __e = exp(__x.real());
1080*0b57cec5SDimitry Andric    return complex<_Tp>(__e * cos(__i), __e * sin(__i));
1081*0b57cec5SDimitry Andric}
1082*0b57cec5SDimitry Andric
1083*0b57cec5SDimitry Andric// pow
1084*0b57cec5SDimitry Andric
1085*0b57cec5SDimitry Andrictemplate<class _Tp>
1086*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1087*0b57cec5SDimitry Andriccomplex<_Tp>
1088*0b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1089*0b57cec5SDimitry Andric{
1090*0b57cec5SDimitry Andric    return exp(__y * log(__x));
1091*0b57cec5SDimitry Andric}
1092*0b57cec5SDimitry Andric
1093*0b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
1094*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1095*0b57cec5SDimitry Andriccomplex<typename __promote<_Tp, _Up>::type>
1096*0b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const complex<_Up>& __y)
1097*0b57cec5SDimitry Andric{
1098*0b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1099*0b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
1100*0b57cec5SDimitry Andric}
1101*0b57cec5SDimitry Andric
1102*0b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
1103*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1104*0b57cec5SDimitry Andrictypename enable_if
1105*0b57cec5SDimitry Andric<
1106*0b57cec5SDimitry Andric    is_arithmetic<_Up>::value,
1107*0b57cec5SDimitry Andric    complex<typename __promote<_Tp, _Up>::type>
1108*0b57cec5SDimitry Andric>::type
1109*0b57cec5SDimitry Andricpow(const complex<_Tp>& __x, const _Up& __y)
1110*0b57cec5SDimitry Andric{
1111*0b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1112*0b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
1113*0b57cec5SDimitry Andric}
1114*0b57cec5SDimitry Andric
1115*0b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
1116*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1117*0b57cec5SDimitry Andrictypename enable_if
1118*0b57cec5SDimitry Andric<
1119*0b57cec5SDimitry Andric    is_arithmetic<_Tp>::value,
1120*0b57cec5SDimitry Andric    complex<typename __promote<_Tp, _Up>::type>
1121*0b57cec5SDimitry Andric>::type
1122*0b57cec5SDimitry Andricpow(const _Tp& __x, const complex<_Up>& __y)
1123*0b57cec5SDimitry Andric{
1124*0b57cec5SDimitry Andric    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1125*0b57cec5SDimitry Andric    return _VSTD::pow(result_type(__x), result_type(__y));
1126*0b57cec5SDimitry Andric}
1127*0b57cec5SDimitry Andric
1128*0b57cec5SDimitry Andric// __sqr, computes pow(x, 2)
1129*0b57cec5SDimitry Andric
1130*0b57cec5SDimitry Andrictemplate<class _Tp>
1131*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1132*0b57cec5SDimitry Andriccomplex<_Tp>
1133*0b57cec5SDimitry Andric__sqr(const complex<_Tp>& __x)
1134*0b57cec5SDimitry Andric{
1135*0b57cec5SDimitry Andric    return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
1136*0b57cec5SDimitry Andric                        _Tp(2) * __x.real() * __x.imag());
1137*0b57cec5SDimitry Andric}
1138*0b57cec5SDimitry Andric
1139*0b57cec5SDimitry Andric// asinh
1140*0b57cec5SDimitry Andric
1141*0b57cec5SDimitry Andrictemplate<class _Tp>
1142*0b57cec5SDimitry Andriccomplex<_Tp>
1143*0b57cec5SDimitry Andricasinh(const complex<_Tp>& __x)
1144*0b57cec5SDimitry Andric{
1145*0b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1146*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1147*0b57cec5SDimitry Andric    {
1148*0b57cec5SDimitry Andric        if (__libcpp_isnan_or_builtin(__x.imag()))
1149*0b57cec5SDimitry Andric            return __x;
1150*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1151*0b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1152*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1153*0b57cec5SDimitry Andric    }
1154*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.real()))
1155*0b57cec5SDimitry Andric    {
1156*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1157*0b57cec5SDimitry Andric            return complex<_Tp>(__x.imag(), __x.real());
1158*0b57cec5SDimitry Andric        if (__x.imag() == 0)
1159*0b57cec5SDimitry Andric            return __x;
1160*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
1161*0b57cec5SDimitry Andric    }
1162*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.imag()))
1163*0b57cec5SDimitry Andric        return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1164*0b57cec5SDimitry Andric    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
1165*0b57cec5SDimitry Andric    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1166*0b57cec5SDimitry Andric}
1167*0b57cec5SDimitry Andric
1168*0b57cec5SDimitry Andric// acosh
1169*0b57cec5SDimitry Andric
1170*0b57cec5SDimitry Andrictemplate<class _Tp>
1171*0b57cec5SDimitry Andriccomplex<_Tp>
1172*0b57cec5SDimitry Andricacosh(const complex<_Tp>& __x)
1173*0b57cec5SDimitry Andric{
1174*0b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1175*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1176*0b57cec5SDimitry Andric    {
1177*0b57cec5SDimitry Andric        if (__libcpp_isnan_or_builtin(__x.imag()))
1178*0b57cec5SDimitry Andric            return complex<_Tp>(abs(__x.real()), __x.imag());
1179*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1180*0b57cec5SDimitry Andric        {
1181*0b57cec5SDimitry Andric            if (__x.real() > 0)
1182*0b57cec5SDimitry Andric                return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1183*0b57cec5SDimitry Andric            else
1184*0b57cec5SDimitry Andric                return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
1185*0b57cec5SDimitry Andric        }
1186*0b57cec5SDimitry Andric        if (__x.real() < 0)
1187*0b57cec5SDimitry Andric            return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
1188*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1189*0b57cec5SDimitry Andric    }
1190*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.real()))
1191*0b57cec5SDimitry Andric    {
1192*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1193*0b57cec5SDimitry Andric            return complex<_Tp>(abs(__x.imag()), __x.real());
1194*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
1195*0b57cec5SDimitry Andric    }
1196*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.imag()))
1197*0b57cec5SDimitry Andric        return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
1198*0b57cec5SDimitry Andric    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
1199*0b57cec5SDimitry Andric    return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
1200*0b57cec5SDimitry Andric}
1201*0b57cec5SDimitry Andric
1202*0b57cec5SDimitry Andric// atanh
1203*0b57cec5SDimitry Andric
1204*0b57cec5SDimitry Andrictemplate<class _Tp>
1205*0b57cec5SDimitry Andriccomplex<_Tp>
1206*0b57cec5SDimitry Andricatanh(const complex<_Tp>& __x)
1207*0b57cec5SDimitry Andric{
1208*0b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1209*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.imag()))
1210*0b57cec5SDimitry Andric    {
1211*0b57cec5SDimitry Andric        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1212*0b57cec5SDimitry Andric    }
1213*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.imag()))
1214*0b57cec5SDimitry Andric    {
1215*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0)
1216*0b57cec5SDimitry Andric            return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
1217*0b57cec5SDimitry Andric        return complex<_Tp>(__x.imag(), __x.imag());
1218*0b57cec5SDimitry Andric    }
1219*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.real()))
1220*0b57cec5SDimitry Andric    {
1221*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
1222*0b57cec5SDimitry Andric    }
1223*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1224*0b57cec5SDimitry Andric    {
1225*0b57cec5SDimitry Andric        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1226*0b57cec5SDimitry Andric    }
1227*0b57cec5SDimitry Andric    if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
1228*0b57cec5SDimitry Andric    {
1229*0b57cec5SDimitry Andric        return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
1230*0b57cec5SDimitry Andric    }
1231*0b57cec5SDimitry Andric    complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1232*0b57cec5SDimitry Andric    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1233*0b57cec5SDimitry Andric}
1234*0b57cec5SDimitry Andric
1235*0b57cec5SDimitry Andric// sinh
1236*0b57cec5SDimitry Andric
1237*0b57cec5SDimitry Andrictemplate<class _Tp>
1238*0b57cec5SDimitry Andriccomplex<_Tp>
1239*0b57cec5SDimitry Andricsinh(const complex<_Tp>& __x)
1240*0b57cec5SDimitry Andric{
1241*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
1242*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), _Tp(NAN));
1243*0b57cec5SDimitry Andric    if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
1244*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), _Tp(NAN));
1245*0b57cec5SDimitry Andric    if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
1246*0b57cec5SDimitry Andric        return __x;
1247*0b57cec5SDimitry Andric    return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
1248*0b57cec5SDimitry Andric}
1249*0b57cec5SDimitry Andric
1250*0b57cec5SDimitry Andric// cosh
1251*0b57cec5SDimitry Andric
1252*0b57cec5SDimitry Andrictemplate<class _Tp>
1253*0b57cec5SDimitry Andriccomplex<_Tp>
1254*0b57cec5SDimitry Andriccosh(const complex<_Tp>& __x)
1255*0b57cec5SDimitry Andric{
1256*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
1257*0b57cec5SDimitry Andric        return complex<_Tp>(abs(__x.real()), _Tp(NAN));
1258*0b57cec5SDimitry Andric    if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
1259*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(NAN), __x.real());
1260*0b57cec5SDimitry Andric    if (__x.real() == 0 && __x.imag() == 0)
1261*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(1), __x.imag());
1262*0b57cec5SDimitry Andric    if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
1263*0b57cec5SDimitry Andric        return complex<_Tp>(abs(__x.real()), __x.imag());
1264*0b57cec5SDimitry Andric    return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
1265*0b57cec5SDimitry Andric}
1266*0b57cec5SDimitry Andric
1267*0b57cec5SDimitry Andric// tanh
1268*0b57cec5SDimitry Andric
1269*0b57cec5SDimitry Andrictemplate<class _Tp>
1270*0b57cec5SDimitry Andriccomplex<_Tp>
1271*0b57cec5SDimitry Andrictanh(const complex<_Tp>& __x)
1272*0b57cec5SDimitry Andric{
1273*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1274*0b57cec5SDimitry Andric    {
1275*0b57cec5SDimitry Andric        if (!__libcpp_isfinite_or_builtin(__x.imag()))
1276*0b57cec5SDimitry Andric            return complex<_Tp>(_Tp(1), _Tp(0));
1277*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
1278*0b57cec5SDimitry Andric    }
1279*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
1280*0b57cec5SDimitry Andric        return __x;
1281*0b57cec5SDimitry Andric    _Tp __2r(_Tp(2) * __x.real());
1282*0b57cec5SDimitry Andric    _Tp __2i(_Tp(2) * __x.imag());
1283*0b57cec5SDimitry Andric    _Tp __d(cosh(__2r) + cos(__2i));
1284*0b57cec5SDimitry Andric    _Tp __2rsh(sinh(__2r));
1285*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d))
1286*0b57cec5SDimitry Andric        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
1287*0b57cec5SDimitry Andric                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1288*0b57cec5SDimitry Andric    return  complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
1289*0b57cec5SDimitry Andric}
1290*0b57cec5SDimitry Andric
1291*0b57cec5SDimitry Andric// asin
1292*0b57cec5SDimitry Andric
1293*0b57cec5SDimitry Andrictemplate<class _Tp>
1294*0b57cec5SDimitry Andriccomplex<_Tp>
1295*0b57cec5SDimitry Andricasin(const complex<_Tp>& __x)
1296*0b57cec5SDimitry Andric{
1297*0b57cec5SDimitry Andric    complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
1298*0b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
1299*0b57cec5SDimitry Andric}
1300*0b57cec5SDimitry Andric
1301*0b57cec5SDimitry Andric// acos
1302*0b57cec5SDimitry Andric
1303*0b57cec5SDimitry Andrictemplate<class _Tp>
1304*0b57cec5SDimitry Andriccomplex<_Tp>
1305*0b57cec5SDimitry Andricacos(const complex<_Tp>& __x)
1306*0b57cec5SDimitry Andric{
1307*0b57cec5SDimitry Andric    const _Tp __pi(atan2(+0., -0.));
1308*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.real()))
1309*0b57cec5SDimitry Andric    {
1310*0b57cec5SDimitry Andric        if (__libcpp_isnan_or_builtin(__x.imag()))
1311*0b57cec5SDimitry Andric            return complex<_Tp>(__x.imag(), __x.real());
1312*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1313*0b57cec5SDimitry Andric        {
1314*0b57cec5SDimitry Andric            if (__x.real() < _Tp(0))
1315*0b57cec5SDimitry Andric                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
1316*0b57cec5SDimitry Andric            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
1317*0b57cec5SDimitry Andric        }
1318*0b57cec5SDimitry Andric        if (__x.real() < _Tp(0))
1319*0b57cec5SDimitry Andric            return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
1320*0b57cec5SDimitry Andric        return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
1321*0b57cec5SDimitry Andric    }
1322*0b57cec5SDimitry Andric    if (__libcpp_isnan_or_builtin(__x.real()))
1323*0b57cec5SDimitry Andric    {
1324*0b57cec5SDimitry Andric        if (__libcpp_isinf_or_builtin(__x.imag()))
1325*0b57cec5SDimitry Andric            return complex<_Tp>(__x.real(), -__x.imag());
1326*0b57cec5SDimitry Andric        return complex<_Tp>(__x.real(), __x.real());
1327*0b57cec5SDimitry Andric    }
1328*0b57cec5SDimitry Andric    if (__libcpp_isinf_or_builtin(__x.imag()))
1329*0b57cec5SDimitry Andric        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1330*0b57cec5SDimitry Andric    if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
1331*0b57cec5SDimitry Andric        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1332*0b57cec5SDimitry Andric    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
1333*0b57cec5SDimitry Andric    if (signbit(__x.imag()))
1334*0b57cec5SDimitry Andric        return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
1335*0b57cec5SDimitry Andric    return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
1336*0b57cec5SDimitry Andric}
1337*0b57cec5SDimitry Andric
1338*0b57cec5SDimitry Andric// atan
1339*0b57cec5SDimitry Andric
1340*0b57cec5SDimitry Andrictemplate<class _Tp>
1341*0b57cec5SDimitry Andriccomplex<_Tp>
1342*0b57cec5SDimitry Andricatan(const complex<_Tp>& __x)
1343*0b57cec5SDimitry Andric{
1344*0b57cec5SDimitry Andric    complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
1345*0b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
1346*0b57cec5SDimitry Andric}
1347*0b57cec5SDimitry Andric
1348*0b57cec5SDimitry Andric// sin
1349*0b57cec5SDimitry Andric
1350*0b57cec5SDimitry Andrictemplate<class _Tp>
1351*0b57cec5SDimitry Andriccomplex<_Tp>
1352*0b57cec5SDimitry Andricsin(const complex<_Tp>& __x)
1353*0b57cec5SDimitry Andric{
1354*0b57cec5SDimitry Andric    complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
1355*0b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
1356*0b57cec5SDimitry Andric}
1357*0b57cec5SDimitry Andric
1358*0b57cec5SDimitry Andric// cos
1359*0b57cec5SDimitry Andric
1360*0b57cec5SDimitry Andrictemplate<class _Tp>
1361*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1362*0b57cec5SDimitry Andriccomplex<_Tp>
1363*0b57cec5SDimitry Andriccos(const complex<_Tp>& __x)
1364*0b57cec5SDimitry Andric{
1365*0b57cec5SDimitry Andric    return cosh(complex<_Tp>(-__x.imag(), __x.real()));
1366*0b57cec5SDimitry Andric}
1367*0b57cec5SDimitry Andric
1368*0b57cec5SDimitry Andric// tan
1369*0b57cec5SDimitry Andric
1370*0b57cec5SDimitry Andrictemplate<class _Tp>
1371*0b57cec5SDimitry Andriccomplex<_Tp>
1372*0b57cec5SDimitry Andrictan(const complex<_Tp>& __x)
1373*0b57cec5SDimitry Andric{
1374*0b57cec5SDimitry Andric    complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
1375*0b57cec5SDimitry Andric    return complex<_Tp>(__z.imag(), -__z.real());
1376*0b57cec5SDimitry Andric}
1377*0b57cec5SDimitry Andric
1378*0b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits>
1379*0b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
1380*0b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
1381*0b57cec5SDimitry Andric{
1382*0b57cec5SDimitry Andric    if (__is.good())
1383*0b57cec5SDimitry Andric    {
1384*0b57cec5SDimitry Andric        ws(__is);
1385*0b57cec5SDimitry Andric        if (__is.peek() == _CharT('('))
1386*0b57cec5SDimitry Andric        {
1387*0b57cec5SDimitry Andric            __is.get();
1388*0b57cec5SDimitry Andric            _Tp __r;
1389*0b57cec5SDimitry Andric            __is >> __r;
1390*0b57cec5SDimitry Andric            if (!__is.fail())
1391*0b57cec5SDimitry Andric            {
1392*0b57cec5SDimitry Andric                ws(__is);
1393*0b57cec5SDimitry Andric                _CharT __c = __is.peek();
1394*0b57cec5SDimitry Andric                if (__c == _CharT(','))
1395*0b57cec5SDimitry Andric                {
1396*0b57cec5SDimitry Andric                    __is.get();
1397*0b57cec5SDimitry Andric                    _Tp __i;
1398*0b57cec5SDimitry Andric                    __is >> __i;
1399*0b57cec5SDimitry Andric                    if (!__is.fail())
1400*0b57cec5SDimitry Andric                    {
1401*0b57cec5SDimitry Andric                        ws(__is);
1402*0b57cec5SDimitry Andric                        __c = __is.peek();
1403*0b57cec5SDimitry Andric                        if (__c == _CharT(')'))
1404*0b57cec5SDimitry Andric                        {
1405*0b57cec5SDimitry Andric                            __is.get();
1406*0b57cec5SDimitry Andric                            __x = complex<_Tp>(__r, __i);
1407*0b57cec5SDimitry Andric                        }
1408*0b57cec5SDimitry Andric                        else
1409*0b57cec5SDimitry Andric                            __is.setstate(ios_base::failbit);
1410*0b57cec5SDimitry Andric                    }
1411*0b57cec5SDimitry Andric                    else
1412*0b57cec5SDimitry Andric                        __is.setstate(ios_base::failbit);
1413*0b57cec5SDimitry Andric                }
1414*0b57cec5SDimitry Andric                else if (__c == _CharT(')'))
1415*0b57cec5SDimitry Andric                {
1416*0b57cec5SDimitry Andric                    __is.get();
1417*0b57cec5SDimitry Andric                    __x = complex<_Tp>(__r, _Tp(0));
1418*0b57cec5SDimitry Andric                }
1419*0b57cec5SDimitry Andric                else
1420*0b57cec5SDimitry Andric                    __is.setstate(ios_base::failbit);
1421*0b57cec5SDimitry Andric            }
1422*0b57cec5SDimitry Andric            else
1423*0b57cec5SDimitry Andric                __is.setstate(ios_base::failbit);
1424*0b57cec5SDimitry Andric        }
1425*0b57cec5SDimitry Andric        else
1426*0b57cec5SDimitry Andric        {
1427*0b57cec5SDimitry Andric            _Tp __r;
1428*0b57cec5SDimitry Andric            __is >> __r;
1429*0b57cec5SDimitry Andric            if (!__is.fail())
1430*0b57cec5SDimitry Andric                __x = complex<_Tp>(__r, _Tp(0));
1431*0b57cec5SDimitry Andric            else
1432*0b57cec5SDimitry Andric                __is.setstate(ios_base::failbit);
1433*0b57cec5SDimitry Andric        }
1434*0b57cec5SDimitry Andric    }
1435*0b57cec5SDimitry Andric    else
1436*0b57cec5SDimitry Andric        __is.setstate(ios_base::failbit);
1437*0b57cec5SDimitry Andric    return __is;
1438*0b57cec5SDimitry Andric}
1439*0b57cec5SDimitry Andric
1440*0b57cec5SDimitry Andrictemplate<class _Tp, class _CharT, class _Traits>
1441*0b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
1442*0b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
1443*0b57cec5SDimitry Andric{
1444*0b57cec5SDimitry Andric    basic_ostringstream<_CharT, _Traits> __s;
1445*0b57cec5SDimitry Andric    __s.flags(__os.flags());
1446*0b57cec5SDimitry Andric    __s.imbue(__os.getloc());
1447*0b57cec5SDimitry Andric    __s.precision(__os.precision());
1448*0b57cec5SDimitry Andric    __s << '(' << __x.real() << ',' << __x.imag() << ')';
1449*0b57cec5SDimitry Andric    return __os << __s.str();
1450*0b57cec5SDimitry Andric}
1451*0b57cec5SDimitry Andric
1452*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
1453*0b57cec5SDimitry Andric// Literal suffix for complex number literals [complex.literals]
1454*0b57cec5SDimitry Andricinline namespace literals
1455*0b57cec5SDimitry Andric{
1456*0b57cec5SDimitry Andric  inline namespace complex_literals
1457*0b57cec5SDimitry Andric  {
1458*0b57cec5SDimitry Andric    constexpr complex<long double> operator""il(long double __im)
1459*0b57cec5SDimitry Andric    {
1460*0b57cec5SDimitry Andric        return { 0.0l, __im };
1461*0b57cec5SDimitry Andric    }
1462*0b57cec5SDimitry Andric
1463*0b57cec5SDimitry Andric    constexpr complex<long double> operator""il(unsigned long long __im)
1464*0b57cec5SDimitry Andric    {
1465*0b57cec5SDimitry Andric        return { 0.0l, static_cast<long double>(__im) };
1466*0b57cec5SDimitry Andric    }
1467*0b57cec5SDimitry Andric
1468*0b57cec5SDimitry Andric
1469*0b57cec5SDimitry Andric    constexpr complex<double> operator""i(long double __im)
1470*0b57cec5SDimitry Andric    {
1471*0b57cec5SDimitry Andric        return { 0.0, static_cast<double>(__im) };
1472*0b57cec5SDimitry Andric    }
1473*0b57cec5SDimitry Andric
1474*0b57cec5SDimitry Andric    constexpr complex<double> operator""i(unsigned long long __im)
1475*0b57cec5SDimitry Andric    {
1476*0b57cec5SDimitry Andric        return { 0.0, static_cast<double>(__im) };
1477*0b57cec5SDimitry Andric    }
1478*0b57cec5SDimitry Andric
1479*0b57cec5SDimitry Andric
1480*0b57cec5SDimitry Andric    constexpr complex<float> operator""if(long double __im)
1481*0b57cec5SDimitry Andric    {
1482*0b57cec5SDimitry Andric        return { 0.0f, static_cast<float>(__im) };
1483*0b57cec5SDimitry Andric    }
1484*0b57cec5SDimitry Andric
1485*0b57cec5SDimitry Andric    constexpr complex<float> operator""if(unsigned long long __im)
1486*0b57cec5SDimitry Andric    {
1487*0b57cec5SDimitry Andric        return { 0.0f, static_cast<float>(__im) };
1488*0b57cec5SDimitry Andric    }
1489*0b57cec5SDimitry Andric  }
1490*0b57cec5SDimitry Andric}
1491*0b57cec5SDimitry Andric#endif
1492*0b57cec5SDimitry Andric
1493*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
1494*0b57cec5SDimitry Andric
1495*0b57cec5SDimitry Andric#endif  // _LIBCPP_COMPLEX
1496