blob: ec35f8ab27c348ce1e8ad0a2c1fad0de9effbbc3 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- complex ----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_COMPLEX
11#define _LIBCPP_COMPLEX
12
13/*
14 complex synopsis
15
16namespace std
17{
18
19template<class T>
20class complex
21{
22public:
23 typedef T value_type;
24
Marshall Clowdf7b6942013-07-31 21:02:34 +000025 complex(const T& re = T(), const T& im = T()); // constexpr in C++14
26 complex(const complex&); // constexpr in C++14
27 template<class X> complex(const complex<X>&); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000028
Marshall Clowdf7b6942013-07-31 21:02:34 +000029 T real() const; // constexpr in C++14
30 T imag() const; // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +000031
32 void real(T);
33 void imag(T);
34
35 complex<T>& operator= (const T&);
36 complex<T>& operator+=(const T&);
37 complex<T>& operator-=(const T&);
38 complex<T>& operator*=(const T&);
39 complex<T>& operator/=(const T&);
40
41 complex& operator=(const complex&);
42 template<class X> complex<T>& operator= (const complex<X>&);
43 template<class X> complex<T>& operator+=(const complex<X>&);
44 template<class X> complex<T>& operator-=(const complex<X>&);
45 template<class X> complex<T>& operator*=(const complex<X>&);
46 template<class X> complex<T>& operator/=(const complex<X>&);
47};
48
49template<>
50class complex<float>
Howard Hinnant3b6579a2010-08-22 00:02:43 +000051{
52public:
53 typedef float value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +000054
Howard Hinnant3b6579a2010-08-22 00:02:43 +000055 constexpr complex(float re = 0.0f, float im = 0.0f);
56 explicit constexpr complex(const complex<double>&);
57 explicit constexpr complex(const complex<long double>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +000058
Howard Hinnant3b6579a2010-08-22 00:02:43 +000059 constexpr float real() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +000060 void real(float);
Howard Hinnant3b6579a2010-08-22 00:02:43 +000061 constexpr float imag() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +000062 void imag(float);
63
Howard Hinnant3b6579a2010-08-22 00:02:43 +000064 complex<float>& operator= (float);
65 complex<float>& operator+=(float);
66 complex<float>& operator-=(float);
67 complex<float>& operator*=(float);
68 complex<float>& operator/=(float);
Howard Hinnantc51e1022010-05-11 19:42:16 +000069
Howard Hinnant3b6579a2010-08-22 00:02:43 +000070 complex<float>& operator=(const complex<float>&);
71 template<class X> complex<float>& operator= (const complex<X>&);
72 template<class X> complex<float>& operator+=(const complex<X>&);
73 template<class X> complex<float>& operator-=(const complex<X>&);
74 template<class X> complex<float>& operator*=(const complex<X>&);
75 template<class X> complex<float>& operator/=(const complex<X>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +000076};
77
78template<>
79class complex<double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +000080{
81public:
82 typedef double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +000083
Howard Hinnant3b6579a2010-08-22 00:02:43 +000084 constexpr complex(double re = 0.0, double im = 0.0);
85 constexpr complex(const complex<float>&);
86 explicit constexpr complex(const complex<long double>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +000087
Howard Hinnant3b6579a2010-08-22 00:02:43 +000088 constexpr double real() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +000089 void real(double);
Howard Hinnant3b6579a2010-08-22 00:02:43 +000090 constexpr double imag() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +000091 void imag(double);
92
Howard Hinnant3b6579a2010-08-22 00:02:43 +000093 complex<double>& operator= (double);
94 complex<double>& operator+=(double);
95 complex<double>& operator-=(double);
96 complex<double>& operator*=(double);
97 complex<double>& operator/=(double);
98 complex<double>& operator=(const complex<double>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +000099
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000100 template<class X> complex<double>& operator= (const complex<X>&);
101 template<class X> complex<double>& operator+=(const complex<X>&);
102 template<class X> complex<double>& operator-=(const complex<X>&);
103 template<class X> complex<double>& operator*=(const complex<X>&);
104 template<class X> complex<double>& operator/=(const complex<X>&);
105};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000106
107template<>
108class complex<long double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000109{
110public:
111 typedef long double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000112
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000113 constexpr complex(long double re = 0.0L, long double im = 0.0L);
114 constexpr complex(const complex<float>&);
115 constexpr complex(const complex<double>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000116
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000117 constexpr long double real() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000118 void real(long double);
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000119 constexpr long double imag() const;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000120 void imag(long double);
121
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000122 complex<long double>& operator=(const complex<long double>&);
123 complex<long double>& operator= (long double);
124 complex<long double>& operator+=(long double);
125 complex<long double>& operator-=(long double);
126 complex<long double>& operator*=(long double);
127 complex<long double>& operator/=(long double);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000129 template<class X> complex<long double>& operator= (const complex<X>&);
130 template<class X> complex<long double>& operator+=(const complex<X>&);
131 template<class X> complex<long double>& operator-=(const complex<X>&);
132 template<class X> complex<long double>& operator*=(const complex<X>&);
133 template<class X> complex<long double>& operator/=(const complex<X>&);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000134};
135
136// 26.3.6 operators:
137template<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
138template<class T> complex<T> operator+(const complex<T>&, const T&);
139template<class T> complex<T> operator+(const T&, const complex<T>&);
140template<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
141template<class T> complex<T> operator-(const complex<T>&, const T&);
142template<class T> complex<T> operator-(const T&, const complex<T>&);
143template<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
144template<class T> complex<T> operator*(const complex<T>&, const T&);
145template<class T> complex<T> operator*(const T&, const complex<T>&);
146template<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
147template<class T> complex<T> operator/(const complex<T>&, const T&);
148template<class T> complex<T> operator/(const T&, const complex<T>&);
149template<class T> complex<T> operator+(const complex<T>&);
150template<class T> complex<T> operator-(const complex<T>&);
Marshall Clowdf7b6942013-07-31 21:02:34 +0000151template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
152template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
153template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
154template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
155template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
156template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000157
158template<class T, class charT, class traits>
159 basic_istream<charT, traits>&
160 operator>>(basic_istream<charT, traits>&, complex<T>&);
161template<class T, class charT, class traits>
162 basic_ostream<charT, traits>&
163 operator<<(basic_ostream<charT, traits>&, const complex<T>&);
164
165// 26.3.7 values:
166
Marshall Clowdf7b6942013-07-31 21:02:34 +0000167template<class T> T real(const complex<T>&); // constexpr in C++14
168 long double real(long double); // constexpr in C++14
169 double real(double); // constexpr in C++14
170template<Integral T> double real(T); // constexpr in C++14
171 float real(float); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000172
Marshall Clowdf7b6942013-07-31 21:02:34 +0000173template<class T> T imag(const complex<T>&); // constexpr in C++14
174 long double imag(long double); // constexpr in C++14
175 double imag(double); // constexpr in C++14
176template<Integral T> double imag(T); // constexpr in C++14
177 float imag(float); // constexpr in C++14
Howard Hinnantc51e1022010-05-11 19:42:16 +0000178
179template<class T> T abs(const complex<T>&);
180
181template<class T> T arg(const complex<T>&);
182 long double arg(long double);
183 double arg(double);
184template<Integral T> double arg(T);
185 float arg(float);
186
187template<class T> T norm(const complex<T>&);
188 long double norm(long double);
189 double norm(double);
190template<Integral T> double norm(T);
191 float norm(float);
192
Howard Hinnanta7533562010-11-18 17:34:48 +0000193template<class T> complex<T> conj(const complex<T>&);
194 complex<long double> conj(long double);
195 complex<double> conj(double);
196template<Integral T> complex<double> conj(T);
197 complex<float> conj(float);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000198
Howard Hinnanta7533562010-11-18 17:34:48 +0000199template<class T> complex<T> proj(const complex<T>&);
200 complex<long double> proj(long double);
201 complex<double> proj(double);
202template<Integral T> complex<double> proj(T);
203 complex<float> proj(float);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000204
Marshall Clow2f283732018-01-31 21:42:39 +0000205template<class T> complex<T> polar(const T&, const T& = T());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000206
207// 26.3.8 transcendentals:
208template<class T> complex<T> acos(const complex<T>&);
209template<class T> complex<T> asin(const complex<T>&);
210template<class T> complex<T> atan(const complex<T>&);
211template<class T> complex<T> acosh(const complex<T>&);
212template<class T> complex<T> asinh(const complex<T>&);
213template<class T> complex<T> atanh(const complex<T>&);
214template<class T> complex<T> cos (const complex<T>&);
215template<class T> complex<T> cosh (const complex<T>&);
216template<class T> complex<T> exp (const complex<T>&);
217template<class T> complex<T> log (const complex<T>&);
218template<class T> complex<T> log10(const complex<T>&);
219
220template<class T> complex<T> pow(const complex<T>&, const T&);
221template<class T> complex<T> pow(const complex<T>&, const complex<T>&);
222template<class T> complex<T> pow(const T&, const complex<T>&);
223
224template<class T> complex<T> sin (const complex<T>&);
225template<class T> complex<T> sinh (const complex<T>&);
226template<class T> complex<T> sqrt (const complex<T>&);
227template<class T> complex<T> tan (const complex<T>&);
228template<class T> complex<T> tanh (const complex<T>&);
229
Howard Hinnantc51e1022010-05-11 19:42:16 +0000230} // std
231
232*/
233
234#include <__config>
235#include <type_traits>
236#include <stdexcept>
237#include <cmath>
Louis Dionne2d937822020-02-19 16:09:41 -0500238#include <iosfwd>
Antonio Sanchezd4fb7402020-05-07 13:49:12 -0400239#include <sstream>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000240#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000242#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000243#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000244#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000245
246_LIBCPP_BEGIN_NAMESPACE_STD
247
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000248template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000249
250template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
251template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
252
253template<class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000254class _LIBCPP_TEMPLATE_VIS complex
Howard Hinnantc51e1022010-05-11 19:42:16 +0000255{
256public:
257 typedef _Tp value_type;
258private:
259 value_type __re_;
260 value_type __im_;
261public:
Marshall Clowdf7b6942013-07-31 21:02:34 +0000262 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000263 complex(const value_type& __re = value_type(), const value_type& __im = value_type())
264 : __re_(__re), __im_(__im) {}
Marshall Clowdf7b6942013-07-31 21:02:34 +0000265 template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000266 complex(const complex<_Xp>& __c)
267 : __re_(__c.real()), __im_(__c.imag()) {}
268
Marshall Clowdf7b6942013-07-31 21:02:34 +0000269 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
270 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000271
272 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
273 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
274
Howard Hinnant233b73f2012-01-10 15:15:47 +0000275 _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
276 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000277 _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
278 _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
279 _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
280 _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
281
282 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
283 {
284 __re_ = __c.real();
285 __im_ = __c.imag();
286 return *this;
287 }
288 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
289 {
290 __re_ += __c.real();
291 __im_ += __c.imag();
292 return *this;
293 }
294 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
295 {
296 __re_ -= __c.real();
297 __im_ -= __c.imag();
298 return *this;
299 }
300 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
301 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000302 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000303 return *this;
304 }
305 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
306 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000307 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000308 return *this;
309 }
310};
311
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000312template<> class _LIBCPP_TEMPLATE_VIS complex<double>;
313template<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000314
315template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000316class _LIBCPP_TEMPLATE_VIS complex<float>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000317{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000318 float __re_;
319 float __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000320public:
321 typedef float value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000322
Howard Hinnant8e556b62012-07-20 22:18:27 +0000323 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000324 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000326 explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000328 explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329
Howard Hinnant8e556b62012-07-20 22:18:27 +0000330 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
331 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332
333 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
334 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
335
Howard Hinnant233b73f2012-01-10 15:15:47 +0000336 _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
337 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000338 _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
339 _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
340 _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
341 _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
342
343 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
344 {
345 __re_ = __c.real();
346 __im_ = __c.imag();
347 return *this;
348 }
349 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
350 {
351 __re_ += __c.real();
352 __im_ += __c.imag();
353 return *this;
354 }
355 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
356 {
357 __re_ -= __c.real();
358 __im_ -= __c.imag();
359 return *this;
360 }
361 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
362 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000363 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000364 return *this;
365 }
366 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
367 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000368 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000369 return *this;
370 }
371};
372
373template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000374class _LIBCPP_TEMPLATE_VIS complex<double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000375{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376 double __re_;
377 double __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000378public:
379 typedef double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000380
Howard Hinnant8e556b62012-07-20 22:18:27 +0000381 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000382 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000384 _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000386 explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387
Howard Hinnant8e556b62012-07-20 22:18:27 +0000388 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
389 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390
391 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
392 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
393
Howard Hinnant233b73f2012-01-10 15:15:47 +0000394 _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
395 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000396 _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
397 _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
398 _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
399 _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
400
401 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
402 {
403 __re_ = __c.real();
404 __im_ = __c.imag();
405 return *this;
406 }
407 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
408 {
409 __re_ += __c.real();
410 __im_ += __c.imag();
411 return *this;
412 }
413 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
414 {
415 __re_ -= __c.real();
416 __im_ -= __c.imag();
417 return *this;
418 }
419 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
420 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000421 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000422 return *this;
423 }
424 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
425 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000426 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000427 return *this;
428 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000429};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000430
431template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000432class _LIBCPP_TEMPLATE_VIS complex<long double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000433{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000434 long double __re_;
435 long double __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000436public:
437 typedef long double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000438
Howard Hinnant8e556b62012-07-20 22:18:27 +0000439 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000440 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000441 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000442 _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000444 _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000445
Howard Hinnant8e556b62012-07-20 22:18:27 +0000446 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
447 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000448
449 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
450 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
451
Howard Hinnant233b73f2012-01-10 15:15:47 +0000452 _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
453 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000454 _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
455 _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
456 _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
457 _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
458
459 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
460 {
461 __re_ = __c.real();
462 __im_ = __c.imag();
463 return *this;
464 }
465 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
466 {
467 __re_ += __c.real();
468 __im_ += __c.imag();
469 return *this;
470 }
471 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
472 {
473 __re_ -= __c.real();
474 __im_ -= __c.imag();
475 return *this;
476 }
477 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
478 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000479 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000480 return *this;
481 }
482 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
483 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000484 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000485 return *this;
486 }
487};
488
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000489inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000490_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000491complex<float>::complex(const complex<double>& __c)
492 : __re_(__c.real()), __im_(__c.imag()) {}
493
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000494inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000495_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000496complex<float>::complex(const complex<long double>& __c)
497 : __re_(__c.real()), __im_(__c.imag()) {}
498
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000499inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000500_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000501complex<double>::complex(const complex<float>& __c)
502 : __re_(__c.real()), __im_(__c.imag()) {}
503
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000504inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000505_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000506complex<double>::complex(const complex<long double>& __c)
507 : __re_(__c.real()), __im_(__c.imag()) {}
508
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000509inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000510_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000511complex<long double>::complex(const complex<float>& __c)
512 : __re_(__c.real()), __im_(__c.imag()) {}
513
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000514inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000515_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000516complex<long double>::complex(const complex<double>& __c)
517 : __re_(__c.real()), __im_(__c.imag()) {}
518
519// 26.3.6 operators:
520
521template<class _Tp>
522inline _LIBCPP_INLINE_VISIBILITY
523complex<_Tp>
524operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
525{
526 complex<_Tp> __t(__x);
527 __t += __y;
528 return __t;
529}
530
531template<class _Tp>
532inline _LIBCPP_INLINE_VISIBILITY
533complex<_Tp>
534operator+(const complex<_Tp>& __x, const _Tp& __y)
535{
536 complex<_Tp> __t(__x);
537 __t += __y;
538 return __t;
539}
540
541template<class _Tp>
542inline _LIBCPP_INLINE_VISIBILITY
543complex<_Tp>
544operator+(const _Tp& __x, const complex<_Tp>& __y)
545{
546 complex<_Tp> __t(__y);
547 __t += __x;
548 return __t;
549}
550
551template<class _Tp>
552inline _LIBCPP_INLINE_VISIBILITY
553complex<_Tp>
554operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
555{
556 complex<_Tp> __t(__x);
557 __t -= __y;
558 return __t;
559}
560
561template<class _Tp>
562inline _LIBCPP_INLINE_VISIBILITY
563complex<_Tp>
564operator-(const complex<_Tp>& __x, const _Tp& __y)
565{
566 complex<_Tp> __t(__x);
567 __t -= __y;
568 return __t;
569}
570
571template<class _Tp>
572inline _LIBCPP_INLINE_VISIBILITY
573complex<_Tp>
574operator-(const _Tp& __x, const complex<_Tp>& __y)
575{
576 complex<_Tp> __t(-__y);
577 __t += __x;
578 return __t;
579}
580
581template<class _Tp>
582complex<_Tp>
583operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
584{
585 _Tp __a = __z.real();
586 _Tp __b = __z.imag();
587 _Tp __c = __w.real();
588 _Tp __d = __w.imag();
589 _Tp __ac = __a * __c;
590 _Tp __bd = __b * __d;
591 _Tp __ad = __a * __d;
592 _Tp __bc = __b * __c;
593 _Tp __x = __ac - __bd;
594 _Tp __y = __ad + __bc;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000595 if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000596 {
597 bool __recalc = false;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000598 if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000599 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000600 __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
601 __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
602 if (__libcpp_isnan_or_builtin(__c))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000603 __c = copysign(_Tp(0), __c);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000604 if (__libcpp_isnan_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000605 __d = copysign(_Tp(0), __d);
606 __recalc = true;
607 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000608 if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000609 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000610 __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
611 __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
612 if (__libcpp_isnan_or_builtin(__a))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000613 __a = copysign(_Tp(0), __a);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000614 if (__libcpp_isnan_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000615 __b = copysign(_Tp(0), __b);
616 __recalc = true;
617 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000618 if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) ||
619 __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000620 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000621 if (__libcpp_isnan_or_builtin(__a))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000622 __a = copysign(_Tp(0), __a);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000623 if (__libcpp_isnan_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000624 __b = copysign(_Tp(0), __b);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000625 if (__libcpp_isnan_or_builtin(__c))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000626 __c = copysign(_Tp(0), __c);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000627 if (__libcpp_isnan_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000628 __d = copysign(_Tp(0), __d);
629 __recalc = true;
630 }
631 if (__recalc)
632 {
633 __x = _Tp(INFINITY) * (__a * __c - __b * __d);
634 __y = _Tp(INFINITY) * (__a * __d + __b * __c);
635 }
636 }
637 return complex<_Tp>(__x, __y);
638}
639
640template<class _Tp>
641inline _LIBCPP_INLINE_VISIBILITY
642complex<_Tp>
643operator*(const complex<_Tp>& __x, const _Tp& __y)
644{
645 complex<_Tp> __t(__x);
646 __t *= __y;
647 return __t;
648}
649
650template<class _Tp>
651inline _LIBCPP_INLINE_VISIBILITY
652complex<_Tp>
653operator*(const _Tp& __x, const complex<_Tp>& __y)
654{
655 complex<_Tp> __t(__y);
656 __t *= __x;
657 return __t;
658}
659
660template<class _Tp>
661complex<_Tp>
662operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
663{
664 int __ilogbw = 0;
665 _Tp __a = __z.real();
666 _Tp __b = __z.imag();
667 _Tp __c = __w.real();
668 _Tp __d = __w.imag();
669 _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000670 if (__libcpp_isfinite_or_builtin(__logbw))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000671 {
672 __ilogbw = static_cast<int>(__logbw);
673 __c = scalbn(__c, -__ilogbw);
674 __d = scalbn(__d, -__ilogbw);
675 }
676 _Tp __denom = __c * __c + __d * __d;
677 _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
678 _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000679 if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000680 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000681 if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000682 {
683 __x = copysign(_Tp(INFINITY), __c) * __a;
684 __y = copysign(_Tp(INFINITY), __c) * __b;
685 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000686 else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000687 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000688 __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
689 __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000690 __x = _Tp(INFINITY) * (__a * __c + __b * __d);
691 __y = _Tp(INFINITY) * (__b * __c - __a * __d);
692 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000693 else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000694 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000695 __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
696 __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000697 __x = _Tp(0) * (__a * __c + __b * __d);
698 __y = _Tp(0) * (__b * __c - __a * __d);
699 }
700 }
701 return complex<_Tp>(__x, __y);
702}
703
704template<class _Tp>
705inline _LIBCPP_INLINE_VISIBILITY
706complex<_Tp>
707operator/(const complex<_Tp>& __x, const _Tp& __y)
708{
709 return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
710}
711
712template<class _Tp>
713inline _LIBCPP_INLINE_VISIBILITY
714complex<_Tp>
715operator/(const _Tp& __x, const complex<_Tp>& __y)
716{
717 complex<_Tp> __t(__x);
718 __t /= __y;
719 return __t;
720}
721
722template<class _Tp>
723inline _LIBCPP_INLINE_VISIBILITY
724complex<_Tp>
725operator+(const complex<_Tp>& __x)
726{
727 return __x;
728}
729
730template<class _Tp>
731inline _LIBCPP_INLINE_VISIBILITY
732complex<_Tp>
733operator-(const complex<_Tp>& __x)
734{
735 return complex<_Tp>(-__x.real(), -__x.imag());
736}
737
738template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000739inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000740bool
741operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
742{
743 return __x.real() == __y.real() && __x.imag() == __y.imag();
744}
745
746template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000747inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000748bool
749operator==(const complex<_Tp>& __x, const _Tp& __y)
750{
751 return __x.real() == __y && __x.imag() == 0;
752}
753
754template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000755inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000756bool
757operator==(const _Tp& __x, const complex<_Tp>& __y)
758{
759 return __x == __y.real() && 0 == __y.imag();
760}
761
762template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000763inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000764bool
765operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
766{
767 return !(__x == __y);
768}
769
770template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000771inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000772bool
773operator!=(const complex<_Tp>& __x, const _Tp& __y)
774{
775 return !(__x == __y);
776}
777
778template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000779inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000780bool
781operator!=(const _Tp& __x, const complex<_Tp>& __y)
782{
783 return !(__x == __y);
784}
785
Howard Hinnantc51e1022010-05-11 19:42:16 +0000786// 26.3.7 values:
787
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000788template <class _Tp, bool = is_integral<_Tp>::value,
789 bool = is_floating_point<_Tp>::value
790 >
791struct __libcpp_complex_overload_traits {};
792
793// Integral Types
794template <class _Tp>
795struct __libcpp_complex_overload_traits<_Tp, true, false>
796{
797 typedef double _ValueType;
798 typedef complex<double> _ComplexType;
799};
800
801// Floating point types
802template <class _Tp>
803struct __libcpp_complex_overload_traits<_Tp, false, true>
804{
805 typedef _Tp _ValueType;
806 typedef complex<_Tp> _ComplexType;
807};
808
Howard Hinnantc51e1022010-05-11 19:42:16 +0000809// real
810
811template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000812inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000813_Tp
814real(const complex<_Tp>& __c)
815{
816 return __c.real();
817}
818
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000819template <class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000820inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000821typename __libcpp_complex_overload_traits<_Tp>::_ValueType
822real(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000823{
824 return __re;
825}
826
827// imag
828
829template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000830inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000831_Tp
832imag(const complex<_Tp>& __c)
833{
834 return __c.imag();
835}
836
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000837template <class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000838inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000839typename __libcpp_complex_overload_traits<_Tp>::_ValueType
Eric Fiselier6003c772016-12-23 23:37:52 +0000840imag(_Tp)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000841{
842 return 0;
843}
844
845// abs
846
847template<class _Tp>
848inline _LIBCPP_INLINE_VISIBILITY
849_Tp
850abs(const complex<_Tp>& __c)
851{
852 return hypot(__c.real(), __c.imag());
853}
854
855// arg
856
857template<class _Tp>
858inline _LIBCPP_INLINE_VISIBILITY
859_Tp
860arg(const complex<_Tp>& __c)
861{
862 return atan2(__c.imag(), __c.real());
863}
864
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000865template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000866inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000867typename enable_if<
868 is_same<_Tp, long double>::value,
869 long double
870>::type
871arg(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000872{
873 return atan2l(0.L, __re);
874}
875
Howard Hinnantc51e1022010-05-11 19:42:16 +0000876template<class _Tp>
877inline _LIBCPP_INLINE_VISIBILITY
878typename enable_if
879<
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000880 is_integral<_Tp>::value || is_same<_Tp, double>::value,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000881 double
882>::type
883arg(_Tp __re)
884{
885 return atan2(0., __re);
886}
887
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000888template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000889inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000890typename enable_if<
891 is_same<_Tp, float>::value,
892 float
893>::type
894arg(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000895{
896 return atan2f(0.F, __re);
897}
898
899// norm
900
901template<class _Tp>
902inline _LIBCPP_INLINE_VISIBILITY
903_Tp
904norm(const complex<_Tp>& __c)
905{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000906 if (__libcpp_isinf_or_builtin(__c.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000907 return abs(__c.real());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000908 if (__libcpp_isinf_or_builtin(__c.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000909 return abs(__c.imag());
910 return __c.real() * __c.real() + __c.imag() * __c.imag();
911}
912
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000913template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000914inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000915typename __libcpp_complex_overload_traits<_Tp>::_ValueType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000916norm(_Tp __re)
917{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000918 typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
919 return static_cast<_ValueType>(__re) * __re;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000920}
921
922// conj
923
924template<class _Tp>
925inline _LIBCPP_INLINE_VISIBILITY
926complex<_Tp>
927conj(const complex<_Tp>& __c)
928{
929 return complex<_Tp>(__c.real(), -__c.imag());
930}
931
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000932template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000933inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000934typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000935conj(_Tp __re)
936{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000937 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
938 return _ComplexType(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000939}
940
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000941
Howard Hinnantc51e1022010-05-11 19:42:16 +0000942
943// proj
944
945template<class _Tp>
946inline _LIBCPP_INLINE_VISIBILITY
947complex<_Tp>
948proj(const complex<_Tp>& __c)
949{
950 std::complex<_Tp> __r = __c;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000951 if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000952 __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
953 return __r;
954}
955
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000956template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000957inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000958typename enable_if
959<
960 is_floating_point<_Tp>::value,
961 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
962>::type
963proj(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000964{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000965 if (__libcpp_isinf_or_builtin(__re))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000966 __re = abs(__re);
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000967 return complex<_Tp>(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000968}
969
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000970template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000971inline _LIBCPP_INLINE_VISIBILITY
972typename enable_if
973<
974 is_integral<_Tp>::value,
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000975 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000976>::type
977proj(_Tp __re)
978{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000979 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
980 return _ComplexType(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000981}
982
Howard Hinnantc51e1022010-05-11 19:42:16 +0000983// polar
984
985template<class _Tp>
986complex<_Tp>
Marshall Clow2f283732018-01-31 21:42:39 +0000987polar(const _Tp& __rho, const _Tp& __theta = _Tp())
Howard Hinnantc51e1022010-05-11 19:42:16 +0000988{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000989 if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000990 return complex<_Tp>(_Tp(NAN), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000991 if (__libcpp_isnan_or_builtin(__theta))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000992 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000993 if (__libcpp_isinf_or_builtin(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000994 return complex<_Tp>(__rho, __theta);
995 return complex<_Tp>(__theta, __theta);
996 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000997 if (__libcpp_isinf_or_builtin(__theta))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000998 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000999 if (__libcpp_isinf_or_builtin(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001000 return complex<_Tp>(__rho, _Tp(NAN));
1001 return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1002 }
1003 _Tp __x = __rho * cos(__theta);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001004 if (__libcpp_isnan_or_builtin(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001005 __x = 0;
1006 _Tp __y = __rho * sin(__theta);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001007 if (__libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001008 __y = 0;
1009 return complex<_Tp>(__x, __y);
1010}
1011
1012// log
1013
1014template<class _Tp>
1015inline _LIBCPP_INLINE_VISIBILITY
1016complex<_Tp>
1017log(const complex<_Tp>& __x)
1018{
1019 return complex<_Tp>(log(abs(__x)), arg(__x));
1020}
1021
1022// log10
1023
1024template<class _Tp>
1025inline _LIBCPP_INLINE_VISIBILITY
1026complex<_Tp>
1027log10(const complex<_Tp>& __x)
1028{
1029 return log(__x) / log(_Tp(10));
1030}
1031
1032// sqrt
1033
1034template<class _Tp>
1035complex<_Tp>
1036sqrt(const complex<_Tp>& __x)
1037{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001038 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001039 return complex<_Tp>(_Tp(INFINITY), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001040 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001041 {
1042 if (__x.real() > _Tp(0))
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001043 return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1044 return complex<_Tp>(__libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001045 }
1046 return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
1047}
1048
1049// exp
1050
1051template<class _Tp>
1052complex<_Tp>
1053exp(const complex<_Tp>& __x)
1054{
1055 _Tp __i = __x.imag();
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001056 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001057 {
1058 if (__x.real() < _Tp(0))
1059 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001060 if (!__libcpp_isfinite_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001061 __i = _Tp(1);
1062 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001063 else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001064 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001065 if (__libcpp_isinf_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001066 __i = _Tp(NAN);
1067 return complex<_Tp>(__x.real(), __i);
1068 }
1069 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001070 else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001071 return __x;
1072 _Tp __e = exp(__x.real());
1073 return complex<_Tp>(__e * cos(__i), __e * sin(__i));
1074}
1075
1076// pow
1077
1078template<class _Tp>
1079inline _LIBCPP_INLINE_VISIBILITY
1080complex<_Tp>
1081pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1082{
1083 return exp(__y * log(__x));
1084}
1085
1086template<class _Tp, class _Up>
1087inline _LIBCPP_INLINE_VISIBILITY
1088complex<typename __promote<_Tp, _Up>::type>
1089pow(const complex<_Tp>& __x, const complex<_Up>& __y)
1090{
1091 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001092 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001093}
1094
1095template<class _Tp, class _Up>
1096inline _LIBCPP_INLINE_VISIBILITY
1097typename enable_if
1098<
1099 is_arithmetic<_Up>::value,
1100 complex<typename __promote<_Tp, _Up>::type>
1101>::type
1102pow(const complex<_Tp>& __x, const _Up& __y)
1103{
1104 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001105 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001106}
1107
1108template<class _Tp, class _Up>
1109inline _LIBCPP_INLINE_VISIBILITY
1110typename enable_if
1111<
1112 is_arithmetic<_Tp>::value,
1113 complex<typename __promote<_Tp, _Up>::type>
1114>::type
1115pow(const _Tp& __x, const complex<_Up>& __y)
1116{
1117 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001118 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001119}
1120
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001121// __sqr, computes pow(x, 2)
1122
1123template<class _Tp>
1124inline _LIBCPP_INLINE_VISIBILITY
1125complex<_Tp>
1126__sqr(const complex<_Tp>& __x)
1127{
1128 return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
1129 _Tp(2) * __x.real() * __x.imag());
1130}
1131
Howard Hinnantc51e1022010-05-11 19:42:16 +00001132// asinh
1133
1134template<class _Tp>
1135complex<_Tp>
1136asinh(const complex<_Tp>& __x)
1137{
1138 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001139 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001140 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001141 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001142 return __x;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001143 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001144 return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1145 return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1146 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001147 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001148 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001149 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001150 return complex<_Tp>(__x.imag(), __x.real());
1151 if (__x.imag() == 0)
1152 return __x;
1153 return complex<_Tp>(__x.real(), __x.real());
1154 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001155 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001156 return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001157 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001158 return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1159}
1160
1161// acosh
1162
1163template<class _Tp>
1164complex<_Tp>
1165acosh(const complex<_Tp>& __x)
1166{
1167 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001168 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001169 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001170 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001171 return complex<_Tp>(abs(__x.real()), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001172 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnant3edce762012-11-06 21:55:44 +00001173 {
Howard Hinnantc51e1022010-05-11 19:42:16 +00001174 if (__x.real() > 0)
1175 return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1176 else
1177 return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
Howard Hinnant3edce762012-11-06 21:55:44 +00001178 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001179 if (__x.real() < 0)
1180 return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
1181 return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1182 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001183 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001184 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001185 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001186 return complex<_Tp>(abs(__x.imag()), __x.real());
1187 return complex<_Tp>(__x.real(), __x.real());
1188 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001189 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001190 return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001191 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001192 return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
1193}
1194
1195// atanh
1196
1197template<class _Tp>
1198complex<_Tp>
1199atanh(const complex<_Tp>& __x)
1200{
1201 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001202 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001203 {
1204 return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1205 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001206 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001207 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001208 if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001209 return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
1210 return complex<_Tp>(__x.imag(), __x.imag());
1211 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001212 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001213 {
1214 return complex<_Tp>(__x.real(), __x.real());
1215 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001216 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001217 {
1218 return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1219 }
1220 if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
1221 {
1222 return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
1223 }
1224 complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1225 return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1226}
1227
1228// sinh
1229
1230template<class _Tp>
1231complex<_Tp>
1232sinh(const complex<_Tp>& __x)
1233{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001234 if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001235 return complex<_Tp>(__x.real(), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001236 if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001237 return complex<_Tp>(__x.real(), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001238 if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001239 return __x;
1240 return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
1241}
1242
1243// cosh
1244
1245template<class _Tp>
1246complex<_Tp>
1247cosh(const complex<_Tp>& __x)
1248{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001249 if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001250 return complex<_Tp>(abs(__x.real()), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001251 if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001252 return complex<_Tp>(_Tp(NAN), __x.real());
1253 if (__x.real() == 0 && __x.imag() == 0)
1254 return complex<_Tp>(_Tp(1), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001255 if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001256 return complex<_Tp>(abs(__x.real()), __x.imag());
1257 return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
1258}
1259
1260// tanh
1261
1262template<class _Tp>
1263complex<_Tp>
1264tanh(const complex<_Tp>& __x)
1265{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001266 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001267 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001268 if (!__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001269 return complex<_Tp>(_Tp(1), _Tp(0));
1270 return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
1271 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001272 if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001273 return __x;
1274 _Tp __2r(_Tp(2) * __x.real());
1275 _Tp __2i(_Tp(2) * __x.imag());
1276 _Tp __d(cosh(__2r) + cos(__2i));
Howard Hinnant3e7b3b52012-09-19 23:51:47 +00001277 _Tp __2rsh(sinh(__2r));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001278 if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d))
Howard Hinnant3e7b3b52012-09-19 23:51:47 +00001279 return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
1280 __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1281 return complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001282}
1283
1284// asin
1285
1286template<class _Tp>
1287complex<_Tp>
1288asin(const complex<_Tp>& __x)
1289{
1290 complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
1291 return complex<_Tp>(__z.imag(), -__z.real());
1292}
1293
1294// acos
1295
1296template<class _Tp>
1297complex<_Tp>
1298acos(const complex<_Tp>& __x)
1299{
1300 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001301 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001302 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001303 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001304 return complex<_Tp>(__x.imag(), __x.real());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001305 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001306 {
1307 if (__x.real() < _Tp(0))
1308 return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
1309 return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
1310 }
1311 if (__x.real() < _Tp(0))
1312 return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
1313 return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
1314 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001315 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001316 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001317 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001318 return complex<_Tp>(__x.real(), -__x.imag());
1319 return complex<_Tp>(__x.real(), __x.real());
1320 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001321 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001322 return complex<_Tp>(__pi/_Tp(2), -__x.imag());
Marshall Clow17af7e42016-04-04 16:08:54 +00001323 if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001324 return complex<_Tp>(__pi/_Tp(2), -__x.imag());
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001325 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001326 if (signbit(__x.imag()))
1327 return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
1328 return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
1329}
1330
1331// atan
1332
1333template<class _Tp>
1334complex<_Tp>
1335atan(const complex<_Tp>& __x)
1336{
1337 complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
1338 return complex<_Tp>(__z.imag(), -__z.real());
1339}
1340
1341// sin
1342
1343template<class _Tp>
1344complex<_Tp>
1345sin(const complex<_Tp>& __x)
1346{
1347 complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
1348 return complex<_Tp>(__z.imag(), -__z.real());
1349}
1350
1351// cos
1352
1353template<class _Tp>
1354inline _LIBCPP_INLINE_VISIBILITY
1355complex<_Tp>
1356cos(const complex<_Tp>& __x)
1357{
1358 return cosh(complex<_Tp>(-__x.imag(), __x.real()));
1359}
1360
1361// tan
1362
1363template<class _Tp>
1364complex<_Tp>
1365tan(const complex<_Tp>& __x)
1366{
1367 complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
1368 return complex<_Tp>(__z.imag(), -__z.real());
1369}
1370
1371template<class _Tp, class _CharT, class _Traits>
1372basic_istream<_CharT, _Traits>&
1373operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
1374{
1375 if (__is.good())
1376 {
1377 ws(__is);
1378 if (__is.peek() == _CharT('('))
1379 {
1380 __is.get();
1381 _Tp __r;
1382 __is >> __r;
1383 if (!__is.fail())
1384 {
1385 ws(__is);
1386 _CharT __c = __is.peek();
1387 if (__c == _CharT(','))
1388 {
1389 __is.get();
1390 _Tp __i;
1391 __is >> __i;
1392 if (!__is.fail())
1393 {
1394 ws(__is);
1395 __c = __is.peek();
1396 if (__c == _CharT(')'))
1397 {
1398 __is.get();
1399 __x = complex<_Tp>(__r, __i);
1400 }
1401 else
Louis Dionne2d937822020-02-19 16:09:41 -05001402 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001403 }
1404 else
Louis Dionne2d937822020-02-19 16:09:41 -05001405 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406 }
1407 else if (__c == _CharT(')'))
1408 {
1409 __is.get();
1410 __x = complex<_Tp>(__r, _Tp(0));
1411 }
1412 else
Louis Dionne2d937822020-02-19 16:09:41 -05001413 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001414 }
1415 else
Louis Dionne2d937822020-02-19 16:09:41 -05001416 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001417 }
1418 else
1419 {
1420 _Tp __r;
1421 __is >> __r;
1422 if (!__is.fail())
1423 __x = complex<_Tp>(__r, _Tp(0));
1424 else
Louis Dionne2d937822020-02-19 16:09:41 -05001425 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001426 }
1427 }
1428 else
Louis Dionne2d937822020-02-19 16:09:41 -05001429 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001430 return __is;
1431}
1432
1433template<class _Tp, class _CharT, class _Traits>
1434basic_ostream<_CharT, _Traits>&
1435operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
1436{
Antonio Sanchezd4fb7402020-05-07 13:49:12 -04001437 basic_ostringstream<_CharT, _Traits> __s;
1438 __s.flags(__os.flags());
1439 __s.imbue(__os.getloc());
1440 __s.precision(__os.precision());
1441 __s << '(' << __x.real() << ',' << __x.imag() << ')';
1442 return __os << __s.str();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001443}
1444
Louis Dionne173f29e2019-05-29 16:01:36 +00001445#if _LIBCPP_STD_VER > 11
Marshall Clow35f91142013-10-05 21:19:49 +00001446// Literal suffix for complex number literals [complex.literals]
1447inline namespace literals
Louis Dionne173f29e2019-05-29 16:01:36 +00001448{
Marshall Clow35f91142013-10-05 21:19:49 +00001449 inline namespace complex_literals
1450 {
1451 constexpr complex<long double> operator""il(long double __im)
1452 {
1453 return { 0.0l, __im };
1454 }
1455
1456 constexpr complex<long double> operator""il(unsigned long long __im)
1457 {
1458 return { 0.0l, static_cast<long double>(__im) };
1459 }
1460
1461
1462 constexpr complex<double> operator""i(long double __im)
1463 {
1464 return { 0.0, static_cast<double>(__im) };
1465 }
1466
1467 constexpr complex<double> operator""i(unsigned long long __im)
1468 {
1469 return { 0.0, static_cast<double>(__im) };
1470 }
1471
1472
1473 constexpr complex<float> operator""if(long double __im)
1474 {
1475 return { 0.0f, static_cast<float>(__im) };
1476 }
1477
1478 constexpr complex<float> operator""if(unsigned long long __im)
1479 {
1480 return { 0.0f, static_cast<float>(__im) };
1481 }
1482 }
1483}
1484#endif
1485
Howard Hinnantc51e1022010-05-11 19:42:16 +00001486_LIBCPP_END_NAMESPACE_STD
1487
1488#endif // _LIBCPP_COMPLEX