1227825Stheraven// -*- C++ -*-
2227825Stheraven//===--------------------------- complex ----------------------------------===//
3227825Stheraven//
4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5353358Sdim// See https://llvm.org/LICENSE.txt for license information.
6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7227825Stheraven//
8227825Stheraven//===----------------------------------------------------------------------===//
9227825Stheraven
10227825Stheraven#ifndef _LIBCPP_COMPLEX
11227825Stheraven#define _LIBCPP_COMPLEX
12227825Stheraven
13227825Stheraven/*
14227825Stheraven    complex synopsis
15227825Stheraven
16227825Stheravennamespace std
17227825Stheraven{
18227825Stheraven
19227825Stheraventemplate<class T>
20227825Stheravenclass complex
21227825Stheraven{
22227825Stheravenpublic:
23227825Stheraven    typedef T value_type;
24227825Stheraven
25261272Sdim    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
26261272Sdim    complex(const complex&);  // constexpr in C++14
27261272Sdim    template<class X> complex(const complex<X>&);  // constexpr in C++14
28227825Stheraven
29261272Sdim    T real() const; // constexpr in C++14
30261272Sdim    T imag() const; // constexpr in C++14
31227825Stheraven
32227825Stheraven    void real(T);
33227825Stheraven    void imag(T);
34227825Stheraven
35227825Stheraven    complex<T>& operator= (const T&);
36227825Stheraven    complex<T>& operator+=(const T&);
37227825Stheraven    complex<T>& operator-=(const T&);
38227825Stheraven    complex<T>& operator*=(const T&);
39227825Stheraven    complex<T>& operator/=(const T&);
40227825Stheraven
41227825Stheraven    complex& operator=(const complex&);
42227825Stheraven    template<class X> complex<T>& operator= (const complex<X>&);
43227825Stheraven    template<class X> complex<T>& operator+=(const complex<X>&);
44227825Stheraven    template<class X> complex<T>& operator-=(const complex<X>&);
45227825Stheraven    template<class X> complex<T>& operator*=(const complex<X>&);
46227825Stheraven    template<class X> complex<T>& operator/=(const complex<X>&);
47227825Stheraven};
48227825Stheraven
49227825Stheraventemplate<>
50227825Stheravenclass complex<float>
51227825Stheraven{
52227825Stheravenpublic:
53227825Stheraven    typedef float value_type;
54227825Stheraven
55227825Stheraven    constexpr complex(float re = 0.0f, float im = 0.0f);
56227825Stheraven    explicit constexpr complex(const complex<double>&);
57227825Stheraven    explicit constexpr complex(const complex<long double>&);
58227825Stheraven
59227825Stheraven    constexpr float real() const;
60227825Stheraven    void real(float);
61227825Stheraven    constexpr float imag() const;
62227825Stheraven    void imag(float);
63227825Stheraven
64227825Stheraven    complex<float>& operator= (float);
65227825Stheraven    complex<float>& operator+=(float);
66227825Stheraven    complex<float>& operator-=(float);
67227825Stheraven    complex<float>& operator*=(float);
68227825Stheraven    complex<float>& operator/=(float);
69227825Stheraven
70227825Stheraven    complex<float>& operator=(const complex<float>&);
71227825Stheraven    template<class X> complex<float>& operator= (const complex<X>&);
72227825Stheraven    template<class X> complex<float>& operator+=(const complex<X>&);
73227825Stheraven    template<class X> complex<float>& operator-=(const complex<X>&);
74227825Stheraven    template<class X> complex<float>& operator*=(const complex<X>&);
75227825Stheraven    template<class X> complex<float>& operator/=(const complex<X>&);
76227825Stheraven};
77227825Stheraven
78227825Stheraventemplate<>
79227825Stheravenclass complex<double>
80227825Stheraven{
81227825Stheravenpublic:
82227825Stheraven    typedef double value_type;
83227825Stheraven
84227825Stheraven    constexpr complex(double re = 0.0, double im = 0.0);
85227825Stheraven    constexpr complex(const complex<float>&);
86227825Stheraven    explicit constexpr complex(const complex<long double>&);
87227825Stheraven
88227825Stheraven    constexpr double real() const;
89227825Stheraven    void real(double);
90227825Stheraven    constexpr double imag() const;
91227825Stheraven    void imag(double);
92227825Stheraven
93227825Stheraven    complex<double>& operator= (double);
94227825Stheraven    complex<double>& operator+=(double);
95227825Stheraven    complex<double>& operator-=(double);
96227825Stheraven    complex<double>& operator*=(double);
97227825Stheraven    complex<double>& operator/=(double);
98227825Stheraven    complex<double>& operator=(const complex<double>&);
99227825Stheraven
100227825Stheraven    template<class X> complex<double>& operator= (const complex<X>&);
101227825Stheraven    template<class X> complex<double>& operator+=(const complex<X>&);
102227825Stheraven    template<class X> complex<double>& operator-=(const complex<X>&);
103227825Stheraven    template<class X> complex<double>& operator*=(const complex<X>&);
104227825Stheraven    template<class X> complex<double>& operator/=(const complex<X>&);
105227825Stheraven};
106227825Stheraven
107227825Stheraventemplate<>
108227825Stheravenclass complex<long double>
109227825Stheraven{
110227825Stheravenpublic:
111227825Stheraven    typedef long double value_type;
112227825Stheraven
113227825Stheraven    constexpr complex(long double re = 0.0L, long double im = 0.0L);
114227825Stheraven    constexpr complex(const complex<float>&);
115227825Stheraven    constexpr complex(const complex<double>&);
116227825Stheraven
117227825Stheraven    constexpr long double real() const;
118227825Stheraven    void real(long double);
119227825Stheraven    constexpr long double imag() const;
120227825Stheraven    void imag(long double);
121227825Stheraven
122227825Stheraven    complex<long double>& operator=(const complex<long double>&);
123227825Stheraven    complex<long double>& operator= (long double);
124227825Stheraven    complex<long double>& operator+=(long double);
125227825Stheraven    complex<long double>& operator-=(long double);
126227825Stheraven    complex<long double>& operator*=(long double);
127227825Stheraven    complex<long double>& operator/=(long double);
128227825Stheraven
129227825Stheraven    template<class X> complex<long double>& operator= (const complex<X>&);
130227825Stheraven    template<class X> complex<long double>& operator+=(const complex<X>&);
131227825Stheraven    template<class X> complex<long double>& operator-=(const complex<X>&);
132227825Stheraven    template<class X> complex<long double>& operator*=(const complex<X>&);
133227825Stheraven    template<class X> complex<long double>& operator/=(const complex<X>&);
134227825Stheraven};
135227825Stheraven
136227825Stheraven// 26.3.6 operators:
137227825Stheraventemplate<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
138227825Stheraventemplate<class T> complex<T> operator+(const complex<T>&, const T&);
139227825Stheraventemplate<class T> complex<T> operator+(const T&, const complex<T>&);
140227825Stheraventemplate<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
141227825Stheraventemplate<class T> complex<T> operator-(const complex<T>&, const T&);
142227825Stheraventemplate<class T> complex<T> operator-(const T&, const complex<T>&);
143227825Stheraventemplate<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
144227825Stheraventemplate<class T> complex<T> operator*(const complex<T>&, const T&);
145227825Stheraventemplate<class T> complex<T> operator*(const T&, const complex<T>&);
146227825Stheraventemplate<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
147227825Stheraventemplate<class T> complex<T> operator/(const complex<T>&, const T&);
148227825Stheraventemplate<class T> complex<T> operator/(const T&, const complex<T>&);
149227825Stheraventemplate<class T> complex<T> operator+(const complex<T>&);
150227825Stheraventemplate<class T> complex<T> operator-(const complex<T>&);
151261272Sdimtemplate<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
152261272Sdimtemplate<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
153261272Sdimtemplate<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
154261272Sdimtemplate<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
155261272Sdimtemplate<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
156261272Sdimtemplate<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
157227825Stheraven
158227825Stheraventemplate<class T, class charT, class traits>
159227825Stheraven  basic_istream<charT, traits>&
160227825Stheraven  operator>>(basic_istream<charT, traits>&, complex<T>&);
161227825Stheraventemplate<class T, class charT, class traits>
162227825Stheraven  basic_ostream<charT, traits>&
163227825Stheraven  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
164227825Stheraven
165227825Stheraven// 26.3.7 values:
166227825Stheraven
167261272Sdimtemplate<class T>              T real(const complex<T>&); // constexpr in C++14
168261272Sdim                     long double real(long double);       // constexpr in C++14
169261272Sdim                          double real(double);            // constexpr in C++14
170261272Sdimtemplate<Integral T>      double real(T);                 // constexpr in C++14
171261272Sdim                          float  real(float);             // constexpr in C++14
172227825Stheraven
173261272Sdimtemplate<class T>              T imag(const complex<T>&); // constexpr in C++14
174261272Sdim                     long double imag(long double);       // constexpr in C++14
175261272Sdim                          double imag(double);            // constexpr in C++14
176261272Sdimtemplate<Integral T>      double imag(T);                 // constexpr in C++14
177261272Sdim                          float  imag(float);             // constexpr in C++14
178227825Stheraven
179227825Stheraventemplate<class T> T abs(const complex<T>&);
180227825Stheraven
181227825Stheraventemplate<class T>              T arg(const complex<T>&);
182227825Stheraven                     long double arg(long double);
183227825Stheraven                          double arg(double);
184227825Stheraventemplate<Integral T>      double arg(T);
185227825Stheraven                          float  arg(float);
186227825Stheraven
187227825Stheraventemplate<class T>              T norm(const complex<T>&);
188227825Stheraven                     long double norm(long double);
189227825Stheraven                          double norm(double);
190227825Stheraventemplate<Integral T>      double norm(T);
191227825Stheraven                          float  norm(float);
192227825Stheraven
193227825Stheraventemplate<class T>      complex<T>           conj(const complex<T>&);
194227825Stheraven                       complex<long double> conj(long double);
195227825Stheraven                       complex<double>      conj(double);
196227825Stheraventemplate<Integral T>   complex<double>      conj(T);
197227825Stheraven                       complex<float>       conj(float);
198227825Stheraven
199227825Stheraventemplate<class T>    complex<T>           proj(const complex<T>&);
200227825Stheraven                     complex<long double> proj(long double);
201227825Stheraven                     complex<double>      proj(double);
202227825Stheraventemplate<Integral T> complex<double>      proj(T);
203227825Stheraven                     complex<float>       proj(float);
204227825Stheraven
205341825Sdimtemplate<class T> complex<T> polar(const T&, const T& = T());
206227825Stheraven
207227825Stheraven// 26.3.8 transcendentals:
208227825Stheraventemplate<class T> complex<T> acos(const complex<T>&);
209227825Stheraventemplate<class T> complex<T> asin(const complex<T>&);
210227825Stheraventemplate<class T> complex<T> atan(const complex<T>&);
211227825Stheraventemplate<class T> complex<T> acosh(const complex<T>&);
212227825Stheraventemplate<class T> complex<T> asinh(const complex<T>&);
213227825Stheraventemplate<class T> complex<T> atanh(const complex<T>&);
214227825Stheraventemplate<class T> complex<T> cos (const complex<T>&);
215227825Stheraventemplate<class T> complex<T> cosh (const complex<T>&);
216227825Stheraventemplate<class T> complex<T> exp (const complex<T>&);
217227825Stheraventemplate<class T> complex<T> log (const complex<T>&);
218227825Stheraventemplate<class T> complex<T> log10(const complex<T>&);
219227825Stheraven
220227825Stheraventemplate<class T> complex<T> pow(const complex<T>&, const T&);
221227825Stheraventemplate<class T> complex<T> pow(const complex<T>&, const complex<T>&);
222227825Stheraventemplate<class T> complex<T> pow(const T&, const complex<T>&);
223227825Stheraven
224227825Stheraventemplate<class T> complex<T> sin (const complex<T>&);
225227825Stheraventemplate<class T> complex<T> sinh (const complex<T>&);
226227825Stheraventemplate<class T> complex<T> sqrt (const complex<T>&);
227227825Stheraventemplate<class T> complex<T> tan (const complex<T>&);
228227825Stheraventemplate<class T> complex<T> tanh (const complex<T>&);
229227825Stheraven
230227825Stheraventemplate<class T, class charT, class traits>
231227825Stheraven  basic_istream<charT, traits>&
232227825Stheraven  operator>>(basic_istream<charT, traits>& is, complex<T>& x);
233227825Stheraven
234227825Stheraventemplate<class T, class charT, class traits>
235227825Stheraven  basic_ostream<charT, traits>&
236227825Stheraven  operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);
237227825Stheraven
238227825Stheraven}  // std
239227825Stheraven
240227825Stheraven*/
241227825Stheraven
242227825Stheraven#include <__config>
243227825Stheraven#include <type_traits>
244227825Stheraven#include <stdexcept>
245227825Stheraven#include <cmath>
246227825Stheraven#include <sstream>
247344779Sdim#include <version>
248227825Stheraven
249227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
250227825Stheraven#pragma GCC system_header
251227825Stheraven#endif
252227825Stheraven
253227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
254227825Stheraven
255314564Sdimtemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
256227825Stheraven
257227825Stheraventemplate<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
258227825Stheraventemplate<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
259227825Stheraven
260227825Stheraventemplate<class _Tp>
261314564Sdimclass _LIBCPP_TEMPLATE_VIS complex
262227825Stheraven{
263227825Stheravenpublic:
264227825Stheraven    typedef _Tp value_type;
265227825Stheravenprivate:
266227825Stheraven    value_type __re_;
267227825Stheraven    value_type __im_;
268227825Stheravenpublic:
269261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
270227825Stheraven    complex(const value_type& __re = value_type(), const value_type& __im = value_type())
271227825Stheraven        : __re_(__re), __im_(__im) {}
272261272Sdim    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
273227825Stheraven    complex(const complex<_Xp>& __c)
274227825Stheraven        : __re_(__c.real()), __im_(__c.imag()) {}
275227825Stheraven
276261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
277261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
278227825Stheraven
279227825Stheraven    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
280227825Stheraven    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
281227825Stheraven
282232924Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
283232924Stheraven        {__re_ = __re; __im_ = value_type(); return *this;}
284227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
285227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
286227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
287227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
288227825Stheraven
289227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
290227825Stheraven        {
291227825Stheraven            __re_ = __c.real();
292227825Stheraven            __im_ = __c.imag();
293227825Stheraven            return *this;
294227825Stheraven        }
295227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
296227825Stheraven        {
297227825Stheraven            __re_ += __c.real();
298227825Stheraven            __im_ += __c.imag();
299227825Stheraven            return *this;
300227825Stheraven        }
301227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
302227825Stheraven        {
303227825Stheraven            __re_ -= __c.real();
304227825Stheraven            __im_ -= __c.imag();
305227825Stheraven            return *this;
306227825Stheraven        }
307227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
308227825Stheraven        {
309261272Sdim            *this = *this * complex(__c.real(), __c.imag());
310227825Stheraven            return *this;
311227825Stheraven        }
312227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
313227825Stheraven        {
314261272Sdim            *this = *this / complex(__c.real(), __c.imag());
315227825Stheraven            return *this;
316227825Stheraven        }
317227825Stheraven};
318227825Stheraven
319314564Sdimtemplate<> class _LIBCPP_TEMPLATE_VIS complex<double>;
320314564Sdimtemplate<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
321227825Stheraven
322227825Stheraventemplate<>
323314564Sdimclass _LIBCPP_TEMPLATE_VIS complex<float>
324227825Stheraven{
325227825Stheraven    float __re_;
326227825Stheraven    float __im_;
327227825Stheravenpublic:
328227825Stheraven    typedef float value_type;
329227825Stheraven
330241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
331227825Stheraven        : __re_(__re), __im_(__im) {}
332309124Sdim    _LIBCPP_INLINE_VISIBILITY
333241900Sdim    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
334309124Sdim    _LIBCPP_INLINE_VISIBILITY
335241900Sdim    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
336227825Stheraven
337241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
338241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
339227825Stheraven
340227825Stheraven    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
341227825Stheraven    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
342227825Stheraven
343232924Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
344232924Stheraven        {__re_ = __re; __im_ = value_type(); return *this;}
345227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
346227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
347227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
348227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
349227825Stheraven
350227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
351227825Stheraven        {
352227825Stheraven            __re_ = __c.real();
353227825Stheraven            __im_ = __c.imag();
354227825Stheraven            return *this;
355227825Stheraven        }
356227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
357227825Stheraven        {
358227825Stheraven            __re_ += __c.real();
359227825Stheraven            __im_ += __c.imag();
360227825Stheraven            return *this;
361227825Stheraven        }
362227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
363227825Stheraven        {
364227825Stheraven            __re_ -= __c.real();
365227825Stheraven            __im_ -= __c.imag();
366227825Stheraven            return *this;
367227825Stheraven        }
368227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
369227825Stheraven        {
370261272Sdim            *this = *this * complex(__c.real(), __c.imag());
371227825Stheraven            return *this;
372227825Stheraven        }
373227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
374227825Stheraven        {
375261272Sdim            *this = *this / complex(__c.real(), __c.imag());
376227825Stheraven            return *this;
377227825Stheraven        }
378227825Stheraven};
379227825Stheraven
380227825Stheraventemplate<>
381314564Sdimclass _LIBCPP_TEMPLATE_VIS complex<double>
382227825Stheraven{
383227825Stheraven    double __re_;
384227825Stheraven    double __im_;
385227825Stheravenpublic:
386227825Stheraven    typedef double value_type;
387227825Stheraven
388241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
389227825Stheraven        : __re_(__re), __im_(__im) {}
390309124Sdim    _LIBCPP_INLINE_VISIBILITY
391241900Sdim    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
392309124Sdim    _LIBCPP_INLINE_VISIBILITY
393241900Sdim    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
394227825Stheraven
395241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
396241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
397227825Stheraven
398227825Stheraven    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
399227825Stheraven    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
400227825Stheraven
401232924Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
402232924Stheraven        {__re_ = __re; __im_ = value_type(); return *this;}
403227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
404227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
405227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
406227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
407227825Stheraven
408227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
409227825Stheraven        {
410227825Stheraven            __re_ = __c.real();
411227825Stheraven            __im_ = __c.imag();
412227825Stheraven            return *this;
413227825Stheraven        }
414227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
415227825Stheraven        {
416227825Stheraven            __re_ += __c.real();
417227825Stheraven            __im_ += __c.imag();
418227825Stheraven            return *this;
419227825Stheraven        }
420227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
421227825Stheraven        {
422227825Stheraven            __re_ -= __c.real();
423227825Stheraven            __im_ -= __c.imag();
424227825Stheraven            return *this;
425227825Stheraven        }
426227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
427227825Stheraven        {
428261272Sdim            *this = *this * complex(__c.real(), __c.imag());
429227825Stheraven            return *this;
430227825Stheraven        }
431227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
432227825Stheraven        {
433261272Sdim            *this = *this / complex(__c.real(), __c.imag());
434227825Stheraven            return *this;
435227825Stheraven        }
436227825Stheraven};
437227825Stheraven
438227825Stheraventemplate<>
439314564Sdimclass _LIBCPP_TEMPLATE_VIS complex<long double>
440227825Stheraven{
441227825Stheraven    long double __re_;
442227825Stheraven    long double __im_;
443227825Stheravenpublic:
444227825Stheraven    typedef long double value_type;
445227825Stheraven
446241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
447227825Stheraven        : __re_(__re), __im_(__im) {}
448309124Sdim    _LIBCPP_INLINE_VISIBILITY
449241900Sdim    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
450309124Sdim    _LIBCPP_INLINE_VISIBILITY
451241900Sdim    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
452227825Stheraven
453241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
454241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
455227825Stheraven
456227825Stheraven    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
457227825Stheraven    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
458227825Stheraven
459232924Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
460232924Stheraven        {__re_ = __re; __im_ = value_type(); return *this;}
461227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
462227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
463227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
464227825Stheraven    _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
465227825Stheraven
466227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
467227825Stheraven        {
468227825Stheraven            __re_ = __c.real();
469227825Stheraven            __im_ = __c.imag();
470227825Stheraven            return *this;
471227825Stheraven        }
472227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
473227825Stheraven        {
474227825Stheraven            __re_ += __c.real();
475227825Stheraven            __im_ += __c.imag();
476227825Stheraven            return *this;
477227825Stheraven        }
478227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
479227825Stheraven        {
480227825Stheraven            __re_ -= __c.real();
481227825Stheraven            __im_ -= __c.imag();
482227825Stheraven            return *this;
483227825Stheraven        }
484227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
485227825Stheraven        {
486261272Sdim            *this = *this * complex(__c.real(), __c.imag());
487227825Stheraven            return *this;
488227825Stheraven        }
489227825Stheraven    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
490227825Stheraven        {
491261272Sdim            *this = *this / complex(__c.real(), __c.imag());
492227825Stheraven            return *this;
493227825Stheraven        }
494227825Stheraven};
495227825Stheraven
496309124Sdiminline
497241900Sdim_LIBCPP_CONSTEXPR
498227825Stheravencomplex<float>::complex(const complex<double>& __c)
499227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
500227825Stheraven
501309124Sdiminline
502241900Sdim_LIBCPP_CONSTEXPR
503227825Stheravencomplex<float>::complex(const complex<long double>& __c)
504227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
505227825Stheraven
506309124Sdiminline
507241900Sdim_LIBCPP_CONSTEXPR
508227825Stheravencomplex<double>::complex(const complex<float>& __c)
509227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
510227825Stheraven
511309124Sdiminline
512241900Sdim_LIBCPP_CONSTEXPR
513227825Stheravencomplex<double>::complex(const complex<long double>& __c)
514227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
515227825Stheraven
516309124Sdiminline
517241900Sdim_LIBCPP_CONSTEXPR
518227825Stheravencomplex<long double>::complex(const complex<float>& __c)
519227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
520227825Stheraven
521309124Sdiminline
522241900Sdim_LIBCPP_CONSTEXPR
523227825Stheravencomplex<long double>::complex(const complex<double>& __c)
524227825Stheraven    : __re_(__c.real()), __im_(__c.imag()) {}
525227825Stheraven
526227825Stheraven// 26.3.6 operators:
527227825Stheraven
528227825Stheraventemplate<class _Tp>
529227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
530227825Stheravencomplex<_Tp>
531227825Stheravenoperator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
532227825Stheraven{
533227825Stheraven    complex<_Tp> __t(__x);
534227825Stheraven    __t += __y;
535227825Stheraven    return __t;
536227825Stheraven}
537227825Stheraven
538227825Stheraventemplate<class _Tp>
539227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
540227825Stheravencomplex<_Tp>
541227825Stheravenoperator+(const complex<_Tp>& __x, const _Tp& __y)
542227825Stheraven{
543227825Stheraven    complex<_Tp> __t(__x);
544227825Stheraven    __t += __y;
545227825Stheraven    return __t;
546227825Stheraven}
547227825Stheraven
548227825Stheraventemplate<class _Tp>
549227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
550227825Stheravencomplex<_Tp>
551227825Stheravenoperator+(const _Tp& __x, const complex<_Tp>& __y)
552227825Stheraven{
553227825Stheraven    complex<_Tp> __t(__y);
554227825Stheraven    __t += __x;
555227825Stheraven    return __t;
556227825Stheraven}
557227825Stheraven
558227825Stheraventemplate<class _Tp>
559227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
560227825Stheravencomplex<_Tp>
561227825Stheravenoperator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
562227825Stheraven{
563227825Stheraven    complex<_Tp> __t(__x);
564227825Stheraven    __t -= __y;
565227825Stheraven    return __t;
566227825Stheraven}
567227825Stheraven
568227825Stheraventemplate<class _Tp>
569227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
570227825Stheravencomplex<_Tp>
571227825Stheravenoperator-(const complex<_Tp>& __x, const _Tp& __y)
572227825Stheraven{
573227825Stheraven    complex<_Tp> __t(__x);
574227825Stheraven    __t -= __y;
575227825Stheraven    return __t;
576227825Stheraven}
577227825Stheraven
578227825Stheraventemplate<class _Tp>
579227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
580227825Stheravencomplex<_Tp>
581227825Stheravenoperator-(const _Tp& __x, const complex<_Tp>& __y)
582227825Stheraven{
583227825Stheraven    complex<_Tp> __t(-__y);
584227825Stheraven    __t += __x;
585227825Stheraven    return __t;
586227825Stheraven}
587227825Stheraven
588227825Stheraventemplate<class _Tp>
589227825Stheravencomplex<_Tp>
590227825Stheravenoperator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
591227825Stheraven{
592227825Stheraven    _Tp __a = __z.real();
593227825Stheraven    _Tp __b = __z.imag();
594227825Stheraven    _Tp __c = __w.real();
595227825Stheraven    _Tp __d = __w.imag();
596227825Stheraven    _Tp __ac = __a * __c;
597227825Stheraven    _Tp __bd = __b * __d;
598227825Stheraven    _Tp __ad = __a * __d;
599227825Stheraven    _Tp __bc = __b * __c;
600227825Stheraven    _Tp __x = __ac - __bd;
601227825Stheraven    _Tp __y = __ad + __bc;
602321369Sdim    if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
603227825Stheraven    {
604227825Stheraven        bool __recalc = false;
605321369Sdim        if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b))
606227825Stheraven        {
607321369Sdim            __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
608321369Sdim            __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
609321369Sdim            if (__libcpp_isnan_or_builtin(__c))
610227825Stheraven                __c = copysign(_Tp(0), __c);
611321369Sdim            if (__libcpp_isnan_or_builtin(__d))
612227825Stheraven                __d = copysign(_Tp(0), __d);
613227825Stheraven            __recalc = true;
614227825Stheraven        }
615321369Sdim        if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d))
616227825Stheraven        {
617321369Sdim            __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
618321369Sdim            __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
619321369Sdim            if (__libcpp_isnan_or_builtin(__a))
620227825Stheraven                __a = copysign(_Tp(0), __a);
621321369Sdim            if (__libcpp_isnan_or_builtin(__b))
622227825Stheraven                __b = copysign(_Tp(0), __b);
623227825Stheraven            __recalc = true;
624227825Stheraven        }
625321369Sdim        if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) ||
626321369Sdim                          __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc)))
627227825Stheraven        {
628321369Sdim            if (__libcpp_isnan_or_builtin(__a))
629227825Stheraven                __a = copysign(_Tp(0), __a);
630321369Sdim            if (__libcpp_isnan_or_builtin(__b))
631227825Stheraven                __b = copysign(_Tp(0), __b);
632321369Sdim            if (__libcpp_isnan_or_builtin(__c))
633227825Stheraven                __c = copysign(_Tp(0), __c);
634321369Sdim            if (__libcpp_isnan_or_builtin(__d))
635227825Stheraven                __d = copysign(_Tp(0), __d);
636227825Stheraven            __recalc = true;
637227825Stheraven        }
638227825Stheraven        if (__recalc)
639227825Stheraven        {
640227825Stheraven            __x = _Tp(INFINITY) * (__a * __c - __b * __d);
641227825Stheraven            __y = _Tp(INFINITY) * (__a * __d + __b * __c);
642227825Stheraven        }
643227825Stheraven    }
644227825Stheraven    return complex<_Tp>(__x, __y);
645227825Stheraven}
646227825Stheraven
647227825Stheraventemplate<class _Tp>
648227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
649227825Stheravencomplex<_Tp>
650227825Stheravenoperator*(const complex<_Tp>& __x, const _Tp& __y)
651227825Stheraven{
652227825Stheraven    complex<_Tp> __t(__x);
653227825Stheraven    __t *= __y;
654227825Stheraven    return __t;
655227825Stheraven}
656227825Stheraven
657227825Stheraventemplate<class _Tp>
658227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
659227825Stheravencomplex<_Tp>
660227825Stheravenoperator*(const _Tp& __x, const complex<_Tp>& __y)
661227825Stheraven{
662227825Stheraven    complex<_Tp> __t(__y);
663227825Stheraven    __t *= __x;
664227825Stheraven    return __t;
665227825Stheraven}
666227825Stheraven
667227825Stheraventemplate<class _Tp>
668227825Stheravencomplex<_Tp>
669227825Stheravenoperator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
670227825Stheraven{
671227825Stheraven    int __ilogbw = 0;
672227825Stheraven    _Tp __a = __z.real();
673227825Stheraven    _Tp __b = __z.imag();
674227825Stheraven    _Tp __c = __w.real();
675227825Stheraven    _Tp __d = __w.imag();
676227825Stheraven    _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
677321369Sdim    if (__libcpp_isfinite_or_builtin(__logbw))
678227825Stheraven    {
679227825Stheraven        __ilogbw = static_cast<int>(__logbw);
680227825Stheraven        __c = scalbn(__c, -__ilogbw);
681227825Stheraven        __d = scalbn(__d, -__ilogbw);
682227825Stheraven    }
683227825Stheraven    _Tp __denom = __c * __c + __d * __d;
684227825Stheraven    _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
685227825Stheraven    _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
686321369Sdim    if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
687227825Stheraven    {
688321369Sdim        if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b)))
689227825Stheraven        {
690227825Stheraven            __x = copysign(_Tp(INFINITY), __c) * __a;
691227825Stheraven            __y = copysign(_Tp(INFINITY), __c) * __b;
692227825Stheraven        }
693321369Sdim        else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d))
694227825Stheraven        {
695321369Sdim            __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
696321369Sdim            __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
697227825Stheraven            __x = _Tp(INFINITY) * (__a * __c + __b * __d);
698227825Stheraven            __y = _Tp(INFINITY) * (__b * __c - __a * __d);
699227825Stheraven        }
700321369Sdim        else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b))
701227825Stheraven        {
702321369Sdim            __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
703321369Sdim            __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
704227825Stheraven            __x = _Tp(0) * (__a * __c + __b * __d);
705227825Stheraven            __y = _Tp(0) * (__b * __c - __a * __d);
706227825Stheraven        }
707227825Stheraven    }
708227825Stheraven    return complex<_Tp>(__x, __y);
709227825Stheraven}
710227825Stheraven
711227825Stheraventemplate<class _Tp>
712227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
713227825Stheravencomplex<_Tp>
714227825Stheravenoperator/(const complex<_Tp>& __x, const _Tp& __y)
715227825Stheraven{
716227825Stheraven    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
717227825Stheraven}
718227825Stheraven
719227825Stheraventemplate<class _Tp>
720227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
721227825Stheravencomplex<_Tp>
722227825Stheravenoperator/(const _Tp& __x, const complex<_Tp>& __y)
723227825Stheraven{
724227825Stheraven    complex<_Tp> __t(__x);
725227825Stheraven    __t /= __y;
726227825Stheraven    return __t;
727227825Stheraven}
728227825Stheraven
729227825Stheraventemplate<class _Tp>
730227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
731227825Stheravencomplex<_Tp>
732227825Stheravenoperator+(const complex<_Tp>& __x)
733227825Stheraven{
734227825Stheraven    return __x;
735227825Stheraven}
736227825Stheraven
737227825Stheraventemplate<class _Tp>
738227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
739227825Stheravencomplex<_Tp>
740227825Stheravenoperator-(const complex<_Tp>& __x)
741227825Stheraven{
742227825Stheraven    return complex<_Tp>(-__x.real(), -__x.imag());
743227825Stheraven}
744227825Stheraven
745227825Stheraventemplate<class _Tp>
746261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
747227825Stheravenbool
748227825Stheravenoperator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
749227825Stheraven{
750227825Stheraven    return __x.real() == __y.real() && __x.imag() == __y.imag();
751227825Stheraven}
752227825Stheraven
753227825Stheraventemplate<class _Tp>
754261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
755227825Stheravenbool
756227825Stheravenoperator==(const complex<_Tp>& __x, const _Tp& __y)
757227825Stheraven{
758227825Stheraven    return __x.real() == __y && __x.imag() == 0;
759227825Stheraven}
760227825Stheraven
761227825Stheraventemplate<class _Tp>
762261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
763227825Stheravenbool
764227825Stheravenoperator==(const _Tp& __x, const complex<_Tp>& __y)
765227825Stheraven{
766227825Stheraven    return __x == __y.real() && 0 == __y.imag();
767227825Stheraven}
768227825Stheraven
769227825Stheraventemplate<class _Tp>
770261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
771227825Stheravenbool
772227825Stheravenoperator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
773227825Stheraven{
774227825Stheraven    return !(__x == __y);
775227825Stheraven}
776227825Stheraven
777227825Stheraventemplate<class _Tp>
778261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
779227825Stheravenbool
780227825Stheravenoperator!=(const complex<_Tp>& __x, const _Tp& __y)
781227825Stheraven{
782227825Stheraven    return !(__x == __y);
783227825Stheraven}
784227825Stheraven
785227825Stheraventemplate<class _Tp>
786261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
787227825Stheravenbool
788227825Stheravenoperator!=(const _Tp& __x, const complex<_Tp>& __y)
789227825Stheraven{
790227825Stheraven    return !(__x == __y);
791227825Stheraven}
792227825Stheraven
793227825Stheraven// 26.3.7 values:
794227825Stheraven
795314564Sdimtemplate <class _Tp, bool = is_integral<_Tp>::value,
796314564Sdim                     bool = is_floating_point<_Tp>::value
797314564Sdim                     >
798314564Sdimstruct __libcpp_complex_overload_traits {};
799227825Stheraven
800314564Sdim// Integral Types
801314564Sdimtemplate <class _Tp>
802314564Sdimstruct __libcpp_complex_overload_traits<_Tp, true, false>
803227825Stheraven{
804314564Sdim    typedef double _ValueType;
805314564Sdim    typedef complex<double> _ComplexType;
806314564Sdim};
807227825Stheraven
808314564Sdim// Floating point types
809314564Sdimtemplate <class _Tp>
810314564Sdimstruct __libcpp_complex_overload_traits<_Tp, false, true>
811227825Stheraven{
812314564Sdim    typedef _Tp _ValueType;
813314564Sdim    typedef complex<_Tp> _ComplexType;
814314564Sdim};
815227825Stheraven
816314564Sdim// real
817227825Stheraven
818227825Stheraventemplate<class _Tp>
819261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
820314564Sdim_Tp
821314564Sdimreal(const complex<_Tp>& __c)
822227825Stheraven{
823314564Sdim    return __c.real();
824227825Stheraven}
825227825Stheraven
826314564Sdimtemplate <class _Tp>
827261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
828314564Sdimtypename __libcpp_complex_overload_traits<_Tp>::_ValueType
829314564Sdimreal(_Tp __re)
830227825Stheraven{
831227825Stheraven    return __re;
832227825Stheraven}
833227825Stheraven
834227825Stheraven// imag
835227825Stheraven
836227825Stheraventemplate<class _Tp>
837261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
838227825Stheraven_Tp
839227825Stheravenimag(const complex<_Tp>& __c)
840227825Stheraven{
841227825Stheraven    return __c.imag();
842227825Stheraven}
843227825Stheraven
844314564Sdimtemplate <class _Tp>
845261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
846314564Sdimtypename __libcpp_complex_overload_traits<_Tp>::_ValueType
847314564Sdimimag(_Tp)
848227825Stheraven{
849227825Stheraven    return 0;
850227825Stheraven}
851227825Stheraven
852227825Stheraven// abs
853227825Stheraven
854227825Stheraventemplate<class _Tp>
855227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
856227825Stheraven_Tp
857227825Stheravenabs(const complex<_Tp>& __c)
858227825Stheraven{
859227825Stheraven    return hypot(__c.real(), __c.imag());
860227825Stheraven}
861227825Stheraven
862227825Stheraven// arg
863227825Stheraven
864227825Stheraventemplate<class _Tp>
865227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
866227825Stheraven_Tp
867227825Stheravenarg(const complex<_Tp>& __c)
868227825Stheraven{
869227825Stheraven    return atan2(__c.imag(), __c.real());
870227825Stheraven}
871227825Stheraven
872314564Sdimtemplate <class _Tp>
873227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
874314564Sdimtypename enable_if<
875314564Sdim    is_same<_Tp, long double>::value,
876314564Sdim    long double
877314564Sdim>::type
878314564Sdimarg(_Tp __re)
879227825Stheraven{
880227825Stheraven    return atan2l(0.L, __re);
881227825Stheraven}
882227825Stheraven
883227825Stheraventemplate<class _Tp>
884227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
885227825Stheraventypename enable_if
886227825Stheraven<
887314564Sdim    is_integral<_Tp>::value || is_same<_Tp, double>::value,
888227825Stheraven    double
889227825Stheraven>::type
890227825Stheravenarg(_Tp __re)
891227825Stheraven{
892227825Stheraven    return atan2(0., __re);
893227825Stheraven}
894227825Stheraven
895314564Sdimtemplate <class _Tp>
896227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
897314564Sdimtypename enable_if<
898314564Sdim    is_same<_Tp, float>::value,
899314564Sdim    float
900314564Sdim>::type
901314564Sdimarg(_Tp __re)
902227825Stheraven{
903227825Stheraven    return atan2f(0.F, __re);
904227825Stheraven}
905227825Stheraven
906227825Stheraven// norm
907227825Stheraven
908227825Stheraventemplate<class _Tp>
909227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
910227825Stheraven_Tp
911227825Stheravennorm(const complex<_Tp>& __c)
912227825Stheraven{
913321369Sdim    if (__libcpp_isinf_or_builtin(__c.real()))
914227825Stheraven        return abs(__c.real());
915321369Sdim    if (__libcpp_isinf_or_builtin(__c.imag()))
916227825Stheraven        return abs(__c.imag());
917227825Stheraven    return __c.real() * __c.real() + __c.imag() * __c.imag();
918227825Stheraven}
919227825Stheraven
920314564Sdimtemplate <class _Tp>
921227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
922314564Sdimtypename __libcpp_complex_overload_traits<_Tp>::_ValueType
923227825Stheravennorm(_Tp __re)
924227825Stheraven{
925314564Sdim    typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
926314564Sdim    return static_cast<_ValueType>(__re) * __re;
927227825Stheraven}
928227825Stheraven
929227825Stheraven// conj
930227825Stheraven
931227825Stheraventemplate<class _Tp>
932227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
933227825Stheravencomplex<_Tp>
934227825Stheravenconj(const complex<_Tp>& __c)
935227825Stheraven{
936227825Stheraven    return complex<_Tp>(__c.real(), -__c.imag());
937227825Stheraven}
938227825Stheraven
939314564Sdimtemplate <class _Tp>
940227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
941314564Sdimtypename __libcpp_complex_overload_traits<_Tp>::_ComplexType
942314564Sdimconj(_Tp __re)
943227825Stheraven{
944314564Sdim    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
945314564Sdim    return _ComplexType(__re);
946227825Stheraven}
947227825Stheraven
948227825Stheraven
949227825Stheraven
950227825Stheraven// proj
951227825Stheraven
952227825Stheraventemplate<class _Tp>
953227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
954227825Stheravencomplex<_Tp>
955227825Stheravenproj(const complex<_Tp>& __c)
956227825Stheraven{
957227825Stheraven    std::complex<_Tp> __r = __c;
958321369Sdim    if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag()))
959227825Stheraven        __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
960227825Stheraven    return __r;
961227825Stheraven}
962227825Stheraven
963314564Sdimtemplate <class _Tp>
964227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
965314564Sdimtypename enable_if
966314564Sdim<
967314564Sdim    is_floating_point<_Tp>::value,
968314564Sdim    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
969314564Sdim>::type
970314564Sdimproj(_Tp __re)
971227825Stheraven{
972321369Sdim    if (__libcpp_isinf_or_builtin(__re))
973227825Stheraven        __re = abs(__re);
974314564Sdim    return complex<_Tp>(__re);
975227825Stheraven}
976227825Stheraven
977314564Sdimtemplate <class _Tp>
978227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
979227825Stheraventypename enable_if
980227825Stheraven<
981227825Stheraven    is_integral<_Tp>::value,
982314564Sdim    typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
983227825Stheraven>::type
984227825Stheravenproj(_Tp __re)
985227825Stheraven{
986314564Sdim    typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
987314564Sdim    return _ComplexType(__re);
988227825Stheraven}
989227825Stheraven
990227825Stheraven// polar
991227825Stheraven
992227825Stheraventemplate<class _Tp>
993227825Stheravencomplex<_Tp>
994341825Sdimpolar(const _Tp& __rho, const _Tp& __theta = _Tp())
995227825Stheraven{
996321369Sdim    if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho))
997227825Stheraven        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
998321369Sdim    if (__libcpp_isnan_or_builtin(__theta))
999227825Stheraven    {
1000321369Sdim        if (__libcpp_isinf_or_builtin(__rho))
1001227825Stheraven            return complex<_Tp>(__rho, __theta);
1002227825Stheraven        return complex<_Tp>(__theta, __theta);
1003227825Stheraven    }
1004321369Sdim    if (__libcpp_isinf_or_builtin(__theta))
1005227825Stheraven    {
1006321369Sdim        if (__libcpp_isinf_or_builtin(__rho))
1007227825Stheraven            return complex<_Tp>(__rho, _Tp(NAN));
1008227825Stheraven        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1009227825Stheraven    }
1010227825Stheraven    _Tp __x = __rho * cos(__theta);
1011321369Sdim    if (__libcpp_isnan_or_builtin(__x))
1012227825Stheraven        __x = 0;
1013227825Stheraven    _Tp __y = __rho * sin(__theta);
1014321369Sdim    if (__libcpp_isnan_or_builtin(__y))
1015227825Stheraven        __y = 0;
1016227825Stheraven    return complex<_Tp>(__x, __y);
1017227825Stheraven}
1018227825Stheraven
1019227825Stheraven// log
1020227825Stheraven
1021227825Stheraventemplate<class _Tp>
1022227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1023227825Stheravencomplex<_Tp>
1024227825Stheravenlog(const complex<_Tp>& __x)
1025227825Stheraven{
1026227825Stheraven    return complex<_Tp>(log(abs(__x)), arg(__x));
1027227825Stheraven}
1028227825Stheraven
1029227825Stheraven// log10
1030227825Stheraven
1031227825Stheraventemplate<class _Tp>
1032227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1033227825Stheravencomplex<_Tp>
1034227825Stheravenlog10(const complex<_Tp>& __x)
1035227825Stheraven{
1036227825Stheraven    return log(__x) / log(_Tp(10));
1037227825Stheraven}
1038227825Stheraven
1039227825Stheraven// sqrt
1040227825Stheraven
1041227825Stheraventemplate<class _Tp>
1042227825Stheravencomplex<_Tp>
1043227825Stheravensqrt(const complex<_Tp>& __x)
1044227825Stheraven{
1045321369Sdim    if (__libcpp_isinf_or_builtin(__x.imag()))
1046227825Stheraven        return complex<_Tp>(_Tp(INFINITY), __x.imag());
1047321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1048227825Stheraven    {
1049227825Stheraven        if (__x.real() > _Tp(0))
1050321369Sdim            return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1051321369Sdim        return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
1052227825Stheraven    }
1053227825Stheraven    return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
1054227825Stheraven}
1055227825Stheraven
1056227825Stheraven// exp
1057227825Stheraven
1058227825Stheraventemplate<class _Tp>
1059227825Stheravencomplex<_Tp>
1060227825Stheravenexp(const complex<_Tp>& __x)
1061227825Stheraven{
1062227825Stheraven    _Tp __i = __x.imag();
1063321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1064227825Stheraven    {
1065227825Stheraven        if (__x.real() < _Tp(0))
1066227825Stheraven        {
1067321369Sdim            if (!__libcpp_isfinite_or_builtin(__i))
1068227825Stheraven                __i = _Tp(1);
1069227825Stheraven        }
1070321369Sdim        else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i))
1071227825Stheraven        {
1072321369Sdim            if (__libcpp_isinf_or_builtin(__i))
1073227825Stheraven                __i = _Tp(NAN);
1074227825Stheraven            return complex<_Tp>(__x.real(), __i);
1075227825Stheraven        }
1076227825Stheraven    }
1077321369Sdim    else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
1078227825Stheraven        return __x;
1079227825Stheraven    _Tp __e = exp(__x.real());
1080227825Stheraven    return complex<_Tp>(__e * cos(__i), __e * sin(__i));
1081227825Stheraven}
1082227825Stheraven
1083227825Stheraven// pow
1084227825Stheraven
1085227825Stheraventemplate<class _Tp>
1086227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1087227825Stheravencomplex<_Tp>
1088227825Stheravenpow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1089227825Stheraven{
1090227825Stheraven    return exp(__y * log(__x));
1091227825Stheraven}
1092227825Stheraven
1093227825Stheraventemplate<class _Tp, class _Up>
1094227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1095227825Stheravencomplex<typename __promote<_Tp, _Up>::type>
1096227825Stheravenpow(const complex<_Tp>& __x, const complex<_Up>& __y)
1097227825Stheraven{
1098227825Stheraven    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1099227825Stheraven    return _VSTD::pow(result_type(__x), result_type(__y));
1100227825Stheraven}
1101227825Stheraven
1102227825Stheraventemplate<class _Tp, class _Up>
1103227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1104227825Stheraventypename enable_if
1105227825Stheraven<
1106227825Stheraven    is_arithmetic<_Up>::value,
1107227825Stheraven    complex<typename __promote<_Tp, _Up>::type>
1108227825Stheraven>::type
1109227825Stheravenpow(const complex<_Tp>& __x, const _Up& __y)
1110227825Stheraven{
1111227825Stheraven    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1112227825Stheraven    return _VSTD::pow(result_type(__x), result_type(__y));
1113227825Stheraven}
1114227825Stheraven
1115227825Stheraventemplate<class _Tp, class _Up>
1116227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1117227825Stheraventypename enable_if
1118227825Stheraven<
1119227825Stheraven    is_arithmetic<_Tp>::value,
1120227825Stheraven    complex<typename __promote<_Tp, _Up>::type>
1121227825Stheraven>::type
1122227825Stheravenpow(const _Tp& __x, const complex<_Up>& __y)
1123227825Stheraven{
1124227825Stheraven    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
1125227825Stheraven    return _VSTD::pow(result_type(__x), result_type(__y));
1126227825Stheraven}
1127227825Stheraven
1128341825Sdim// __sqr, computes pow(x, 2)
1129341825Sdim
1130341825Sdimtemplate<class _Tp>
1131341825Sdiminline _LIBCPP_INLINE_VISIBILITY
1132341825Sdimcomplex<_Tp>
1133341825Sdim__sqr(const complex<_Tp>& __x)
1134341825Sdim{
1135341825Sdim    return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
1136341825Sdim                        _Tp(2) * __x.real() * __x.imag());
1137341825Sdim}
1138341825Sdim
1139227825Stheraven// asinh
1140227825Stheraven
1141227825Stheraventemplate<class _Tp>
1142227825Stheravencomplex<_Tp>
1143227825Stheravenasinh(const complex<_Tp>& __x)
1144227825Stheraven{
1145227825Stheraven    const _Tp __pi(atan2(+0., -0.));
1146321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1147227825Stheraven    {
1148321369Sdim        if (__libcpp_isnan_or_builtin(__x.imag()))
1149227825Stheraven            return __x;
1150321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1151227825Stheraven            return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1152227825Stheraven        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1153227825Stheraven    }
1154321369Sdim    if (__libcpp_isnan_or_builtin(__x.real()))
1155227825Stheraven    {
1156321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1157227825Stheraven            return complex<_Tp>(__x.imag(), __x.real());
1158227825Stheraven        if (__x.imag() == 0)
1159227825Stheraven            return __x;
1160227825Stheraven        return complex<_Tp>(__x.real(), __x.real());
1161227825Stheraven    }
1162321369Sdim    if (__libcpp_isinf_or_builtin(__x.imag()))
1163227825Stheraven        return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1164341825Sdim    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
1165227825Stheraven    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1166227825Stheraven}
1167227825Stheraven
1168227825Stheraven// acosh
1169227825Stheraven
1170227825Stheraventemplate<class _Tp>
1171227825Stheravencomplex<_Tp>
1172227825Stheravenacosh(const complex<_Tp>& __x)
1173227825Stheraven{
1174227825Stheraven    const _Tp __pi(atan2(+0., -0.));
1175321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1176227825Stheraven    {
1177321369Sdim        if (__libcpp_isnan_or_builtin(__x.imag()))
1178227825Stheraven            return complex<_Tp>(abs(__x.real()), __x.imag());
1179321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1180242939Stheraven        {
1181227825Stheraven            if (__x.real() > 0)
1182227825Stheraven                return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1183227825Stheraven            else
1184227825Stheraven                return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
1185242939Stheraven        }
1186227825Stheraven        if (__x.real() < 0)
1187227825Stheraven            return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
1188227825Stheraven        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1189227825Stheraven    }
1190321369Sdim    if (__libcpp_isnan_or_builtin(__x.real()))
1191227825Stheraven    {
1192321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1193227825Stheraven            return complex<_Tp>(abs(__x.imag()), __x.real());
1194227825Stheraven        return complex<_Tp>(__x.real(), __x.real());
1195227825Stheraven    }
1196321369Sdim    if (__libcpp_isinf_or_builtin(__x.imag()))
1197227825Stheraven        return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
1198341825Sdim    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
1199227825Stheraven    return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
1200227825Stheraven}
1201227825Stheraven
1202227825Stheraven// atanh
1203227825Stheraven
1204227825Stheraventemplate<class _Tp>
1205227825Stheravencomplex<_Tp>
1206227825Stheravenatanh(const complex<_Tp>& __x)
1207227825Stheraven{
1208227825Stheraven    const _Tp __pi(atan2(+0., -0.));
1209321369Sdim    if (__libcpp_isinf_or_builtin(__x.imag()))
1210227825Stheraven    {
1211227825Stheraven        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1212227825Stheraven    }
1213321369Sdim    if (__libcpp_isnan_or_builtin(__x.imag()))
1214227825Stheraven    {
1215321369Sdim        if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0)
1216227825Stheraven            return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
1217227825Stheraven        return complex<_Tp>(__x.imag(), __x.imag());
1218227825Stheraven    }
1219321369Sdim    if (__libcpp_isnan_or_builtin(__x.real()))
1220227825Stheraven    {
1221227825Stheraven        return complex<_Tp>(__x.real(), __x.real());
1222227825Stheraven    }
1223321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1224227825Stheraven    {
1225227825Stheraven        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1226227825Stheraven    }
1227227825Stheraven    if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
1228227825Stheraven    {
1229227825Stheraven        return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
1230227825Stheraven    }
1231227825Stheraven    complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1232227825Stheraven    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1233227825Stheraven}
1234227825Stheraven
1235227825Stheraven// sinh
1236227825Stheraven
1237227825Stheraventemplate<class _Tp>
1238227825Stheravencomplex<_Tp>
1239227825Stheravensinh(const complex<_Tp>& __x)
1240227825Stheraven{
1241321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
1242227825Stheraven        return complex<_Tp>(__x.real(), _Tp(NAN));
1243321369Sdim    if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
1244227825Stheraven        return complex<_Tp>(__x.real(), _Tp(NAN));
1245321369Sdim    if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
1246227825Stheraven        return __x;
1247227825Stheraven    return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
1248227825Stheraven}
1249227825Stheraven
1250227825Stheraven// cosh
1251227825Stheraven
1252227825Stheraventemplate<class _Tp>
1253227825Stheravencomplex<_Tp>
1254227825Stheravencosh(const complex<_Tp>& __x)
1255227825Stheraven{
1256321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
1257227825Stheraven        return complex<_Tp>(abs(__x.real()), _Tp(NAN));
1258321369Sdim    if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
1259227825Stheraven        return complex<_Tp>(_Tp(NAN), __x.real());
1260227825Stheraven    if (__x.real() == 0 && __x.imag() == 0)
1261227825Stheraven        return complex<_Tp>(_Tp(1), __x.imag());
1262321369Sdim    if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
1263227825Stheraven        return complex<_Tp>(abs(__x.real()), __x.imag());
1264227825Stheraven    return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
1265227825Stheraven}
1266227825Stheraven
1267227825Stheraven// tanh
1268227825Stheraven
1269227825Stheraventemplate<class _Tp>
1270227825Stheravencomplex<_Tp>
1271227825Stheraventanh(const complex<_Tp>& __x)
1272227825Stheraven{
1273321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1274227825Stheraven    {
1275321369Sdim        if (!__libcpp_isfinite_or_builtin(__x.imag()))
1276227825Stheraven            return complex<_Tp>(_Tp(1), _Tp(0));
1277227825Stheraven        return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
1278227825Stheraven    }
1279321369Sdim    if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
1280227825Stheraven        return __x;
1281227825Stheraven    _Tp __2r(_Tp(2) * __x.real());
1282227825Stheraven    _Tp __2i(_Tp(2) * __x.imag());
1283227825Stheraven    _Tp __d(cosh(__2r) + cos(__2i));
1284241900Sdim    _Tp __2rsh(sinh(__2r));
1285321369Sdim    if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d))
1286241900Sdim        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
1287241900Sdim                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1288241900Sdim    return  complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
1289227825Stheraven}
1290227825Stheraven
1291227825Stheraven// asin
1292227825Stheraven
1293227825Stheraventemplate<class _Tp>
1294227825Stheravencomplex<_Tp>
1295227825Stheravenasin(const complex<_Tp>& __x)
1296227825Stheraven{
1297227825Stheraven    complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
1298227825Stheraven    return complex<_Tp>(__z.imag(), -__z.real());
1299227825Stheraven}
1300227825Stheraven
1301227825Stheraven// acos
1302227825Stheraven
1303227825Stheraventemplate<class _Tp>
1304227825Stheravencomplex<_Tp>
1305227825Stheravenacos(const complex<_Tp>& __x)
1306227825Stheraven{
1307227825Stheraven    const _Tp __pi(atan2(+0., -0.));
1308321369Sdim    if (__libcpp_isinf_or_builtin(__x.real()))
1309227825Stheraven    {
1310321369Sdim        if (__libcpp_isnan_or_builtin(__x.imag()))
1311227825Stheraven            return complex<_Tp>(__x.imag(), __x.real());
1312321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1313227825Stheraven        {
1314227825Stheraven            if (__x.real() < _Tp(0))
1315227825Stheraven                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
1316227825Stheraven            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
1317227825Stheraven        }
1318227825Stheraven        if (__x.real() < _Tp(0))
1319227825Stheraven            return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
1320227825Stheraven        return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
1321227825Stheraven    }
1322321369Sdim    if (__libcpp_isnan_or_builtin(__x.real()))
1323227825Stheraven    {
1324321369Sdim        if (__libcpp_isinf_or_builtin(__x.imag()))
1325227825Stheraven            return complex<_Tp>(__x.real(), -__x.imag());
1326227825Stheraven        return complex<_Tp>(__x.real(), __x.real());
1327227825Stheraven    }
1328321369Sdim    if (__libcpp_isinf_or_builtin(__x.imag()))
1329227825Stheraven        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1330309124Sdim    if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
1331227825Stheraven        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
1332341825Sdim    complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
1333227825Stheraven    if (signbit(__x.imag()))
1334227825Stheraven        return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
1335227825Stheraven    return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
1336227825Stheraven}
1337227825Stheraven
1338227825Stheraven// atan
1339227825Stheraven
1340227825Stheraventemplate<class _Tp>
1341227825Stheravencomplex<_Tp>
1342227825Stheravenatan(const complex<_Tp>& __x)
1343227825Stheraven{
1344227825Stheraven    complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
1345227825Stheraven    return complex<_Tp>(__z.imag(), -__z.real());
1346227825Stheraven}
1347227825Stheraven
1348227825Stheraven// sin
1349227825Stheraven
1350227825Stheraventemplate<class _Tp>
1351227825Stheravencomplex<_Tp>
1352227825Stheravensin(const complex<_Tp>& __x)
1353227825Stheraven{
1354227825Stheraven    complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
1355227825Stheraven    return complex<_Tp>(__z.imag(), -__z.real());
1356227825Stheraven}
1357227825Stheraven
1358227825Stheraven// cos
1359227825Stheraven
1360227825Stheraventemplate<class _Tp>
1361227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1362227825Stheravencomplex<_Tp>
1363227825Stheravencos(const complex<_Tp>& __x)
1364227825Stheraven{
1365227825Stheraven    return cosh(complex<_Tp>(-__x.imag(), __x.real()));
1366227825Stheraven}
1367227825Stheraven
1368227825Stheraven// tan
1369227825Stheraven
1370227825Stheraventemplate<class _Tp>
1371227825Stheravencomplex<_Tp>
1372227825Stheraventan(const complex<_Tp>& __x)
1373227825Stheraven{
1374227825Stheraven    complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
1375227825Stheraven    return complex<_Tp>(__z.imag(), -__z.real());
1376227825Stheraven}
1377227825Stheraven
1378227825Stheraventemplate<class _Tp, class _CharT, class _Traits>
1379227825Stheravenbasic_istream<_CharT, _Traits>&
1380227825Stheravenoperator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
1381227825Stheraven{
1382227825Stheraven    if (__is.good())
1383227825Stheraven    {
1384227825Stheraven        ws(__is);
1385227825Stheraven        if (__is.peek() == _CharT('('))
1386227825Stheraven        {
1387227825Stheraven            __is.get();
1388227825Stheraven            _Tp __r;
1389227825Stheraven            __is >> __r;
1390227825Stheraven            if (!__is.fail())
1391227825Stheraven            {
1392227825Stheraven                ws(__is);
1393227825Stheraven                _CharT __c = __is.peek();
1394227825Stheraven                if (__c == _CharT(','))
1395227825Stheraven                {
1396227825Stheraven                    __is.get();
1397227825Stheraven                    _Tp __i;
1398227825Stheraven                    __is >> __i;
1399227825Stheraven                    if (!__is.fail())
1400227825Stheraven                    {
1401227825Stheraven                        ws(__is);
1402227825Stheraven                        __c = __is.peek();
1403227825Stheraven                        if (__c == _CharT(')'))
1404227825Stheraven                        {
1405227825Stheraven                            __is.get();
1406227825Stheraven                            __x = complex<_Tp>(__r, __i);
1407227825Stheraven                        }
1408227825Stheraven                        else
1409227825Stheraven                            __is.setstate(ios_base::failbit);
1410227825Stheraven                    }
1411227825Stheraven                    else
1412227825Stheraven                        __is.setstate(ios_base::failbit);
1413227825Stheraven                }
1414227825Stheraven                else if (__c == _CharT(')'))
1415227825Stheraven                {
1416227825Stheraven                    __is.get();
1417227825Stheraven                    __x = complex<_Tp>(__r, _Tp(0));
1418227825Stheraven                }
1419227825Stheraven                else
1420227825Stheraven                    __is.setstate(ios_base::failbit);
1421227825Stheraven            }
1422227825Stheraven            else
1423227825Stheraven                __is.setstate(ios_base::failbit);
1424227825Stheraven        }
1425227825Stheraven        else
1426227825Stheraven        {
1427227825Stheraven            _Tp __r;
1428227825Stheraven            __is >> __r;
1429227825Stheraven            if (!__is.fail())
1430227825Stheraven                __x = complex<_Tp>(__r, _Tp(0));
1431227825Stheraven            else
1432227825Stheraven                __is.setstate(ios_base::failbit);
1433227825Stheraven        }
1434227825Stheraven    }
1435227825Stheraven    else
1436227825Stheraven        __is.setstate(ios_base::failbit);
1437227825Stheraven    return __is;
1438227825Stheraven}
1439227825Stheraven
1440227825Stheraventemplate<class _Tp, class _CharT, class _Traits>
1441227825Stheravenbasic_ostream<_CharT, _Traits>&
1442227825Stheravenoperator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
1443227825Stheraven{
1444227825Stheraven    basic_ostringstream<_CharT, _Traits> __s;
1445227825Stheraven    __s.flags(__os.flags());
1446227825Stheraven    __s.imbue(__os.getloc());
1447227825Stheraven    __s.precision(__os.precision());
1448227825Stheraven    __s << '(' << __x.real() << ',' << __x.imag() << ')';
1449227825Stheraven    return __os << __s.str();
1450227825Stheraven}
1451227825Stheraven
1452353358Sdim#if _LIBCPP_STD_VER > 11
1453261272Sdim// Literal suffix for complex number literals [complex.literals]
1454261272Sdiminline namespace literals
1455353358Sdim{
1456261272Sdim  inline namespace complex_literals
1457261272Sdim  {
1458261272Sdim    constexpr complex<long double> operator""il(long double __im)
1459261272Sdim    {
1460261272Sdim        return { 0.0l, __im };
1461261272Sdim    }
1462261272Sdim
1463261272Sdim    constexpr complex<long double> operator""il(unsigned long long __im)
1464261272Sdim    {
1465261272Sdim        return { 0.0l, static_cast<long double>(__im) };
1466261272Sdim    }
1467261272Sdim
1468261272Sdim
1469261272Sdim    constexpr complex<double> operator""i(long double __im)
1470261272Sdim    {
1471261272Sdim        return { 0.0, static_cast<double>(__im) };
1472261272Sdim    }
1473261272Sdim
1474261272Sdim    constexpr complex<double> operator""i(unsigned long long __im)
1475261272Sdim    {
1476261272Sdim        return { 0.0, static_cast<double>(__im) };
1477261272Sdim    }
1478261272Sdim
1479261272Sdim
1480261272Sdim    constexpr complex<float> operator""if(long double __im)
1481261272Sdim    {
1482261272Sdim        return { 0.0f, static_cast<float>(__im) };
1483261272Sdim    }
1484261272Sdim
1485261272Sdim    constexpr complex<float> operator""if(unsigned long long __im)
1486261272Sdim    {
1487261272Sdim        return { 0.0f, static_cast<float>(__im) };
1488261272Sdim    }
1489261272Sdim  }
1490261272Sdim}
1491261272Sdim#endif
1492261272Sdim
1493227825Stheraven_LIBCPP_END_NAMESPACE_STD
1494227825Stheraven
1495227825Stheraven#endif  // _LIBCPP_COMPLEX
1496