blob: fc52697f7749b8e0918785e0312e6a762ed10c4a [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>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235#include <cmath>
Louis Dionne2d937822020-02-19 16:09:41 -0500236#include <iosfwd>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400237#include <stdexcept>
238#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000239#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240
Louis Dionne8d053eb2020-10-09 15:31:05 -0400241#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
242# include <sstream> // for std::basic_ostringstream
243#endif
244
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000245#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000247#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000248
249_LIBCPP_BEGIN_NAMESPACE_STD
250
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000251template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000252
253template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
254template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
255
256template<class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000257class _LIBCPP_TEMPLATE_VIS complex
Howard Hinnantc51e1022010-05-11 19:42:16 +0000258{
259public:
260 typedef _Tp value_type;
261private:
262 value_type __re_;
263 value_type __im_;
264public:
Marshall Clowdf7b6942013-07-31 21:02:34 +0000265 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000266 complex(const value_type& __re = value_type(), const value_type& __im = value_type())
267 : __re_(__re), __im_(__im) {}
Marshall Clowdf7b6942013-07-31 21:02:34 +0000268 template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000269 complex(const complex<_Xp>& __c)
270 : __re_(__c.real()), __im_(__c.imag()) {}
271
Marshall Clowdf7b6942013-07-31 21:02:34 +0000272 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
273 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
276 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
277
Howard Hinnant233b73f2012-01-10 15:15:47 +0000278 _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
279 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000280 _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
281 _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
282 _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
283 _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
284
285 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
286 {
287 __re_ = __c.real();
288 __im_ = __c.imag();
289 return *this;
290 }
291 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
292 {
293 __re_ += __c.real();
294 __im_ += __c.imag();
295 return *this;
296 }
297 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
298 {
299 __re_ -= __c.real();
300 __im_ -= __c.imag();
301 return *this;
302 }
303 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
304 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000305 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000306 return *this;
307 }
308 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
309 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000310 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311 return *this;
312 }
313};
314
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000315template<> class _LIBCPP_TEMPLATE_VIS complex<double>;
316template<> class _LIBCPP_TEMPLATE_VIS complex<long double>;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317
318template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000319class _LIBCPP_TEMPLATE_VIS complex<float>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000320{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000321 float __re_;
322 float __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000323public:
324 typedef float value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
Howard Hinnant8e556b62012-07-20 22:18:27 +0000326 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000327 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000329 explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000331 explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332
Howard Hinnant8e556b62012-07-20 22:18:27 +0000333 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
334 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000335
336 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
337 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
338
Howard Hinnant233b73f2012-01-10 15:15:47 +0000339 _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
340 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341 _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
342 _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
343 _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
344 _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
345
346 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
347 {
348 __re_ = __c.real();
349 __im_ = __c.imag();
350 return *this;
351 }
352 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
353 {
354 __re_ += __c.real();
355 __im_ += __c.imag();
356 return *this;
357 }
358 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
359 {
360 __re_ -= __c.real();
361 __im_ -= __c.imag();
362 return *this;
363 }
364 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
365 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000366 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000367 return *this;
368 }
369 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
370 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000371 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372 return *this;
373 }
374};
375
376template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000377class _LIBCPP_TEMPLATE_VIS complex<double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000378{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000379 double __re_;
380 double __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000381public:
382 typedef double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383
Howard Hinnant8e556b62012-07-20 22:18:27 +0000384 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000386 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000387 _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000389 explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390
Howard Hinnant8e556b62012-07-20 22:18:27 +0000391 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
392 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000393
394 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
395 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
396
Howard Hinnant233b73f2012-01-10 15:15:47 +0000397 _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
398 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000399 _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
400 _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
401 _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
402 _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
403
404 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
405 {
406 __re_ = __c.real();
407 __im_ = __c.imag();
408 return *this;
409 }
410 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
411 {
412 __re_ += __c.real();
413 __im_ += __c.imag();
414 return *this;
415 }
416 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
417 {
418 __re_ -= __c.real();
419 __im_ -= __c.imag();
420 return *this;
421 }
422 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
423 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000424 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000425 return *this;
426 }
427 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
428 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000429 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000430 return *this;
431 }
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000432};
Howard Hinnantc51e1022010-05-11 19:42:16 +0000433
434template<>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000435class _LIBCPP_TEMPLATE_VIS complex<long double>
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000436{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000437 long double __re_;
438 long double __im_;
Howard Hinnant3b6579a2010-08-22 00:02:43 +0000439public:
440 typedef long double value_type;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000441
Howard Hinnant8e556b62012-07-20 22:18:27 +0000442 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000443 : __re_(__re), __im_(__im) {}
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000444 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000445 _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8e556b62012-07-20 22:18:27 +0000447 _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000448
Howard Hinnant8e556b62012-07-20 22:18:27 +0000449 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
450 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000451
452 _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
453 _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
454
Howard Hinnant233b73f2012-01-10 15:15:47 +0000455 _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
456 {__re_ = __re; __im_ = value_type(); return *this;}
Howard Hinnantc51e1022010-05-11 19:42:16 +0000457 _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
458 _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
459 _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
460 _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
461
462 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
463 {
464 __re_ = __c.real();
465 __im_ = __c.imag();
466 return *this;
467 }
468 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
469 {
470 __re_ += __c.real();
471 __im_ += __c.imag();
472 return *this;
473 }
474 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
475 {
476 __re_ -= __c.real();
477 __im_ -= __c.imag();
478 return *this;
479 }
480 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
481 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000482 *this = *this * complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000483 return *this;
484 }
485 template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
486 {
Marshall Clowdf7b6942013-07-31 21:02:34 +0000487 *this = *this / complex(__c.real(), __c.imag());
Howard Hinnantc51e1022010-05-11 19:42:16 +0000488 return *this;
489 }
490};
491
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000492inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000493_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000494complex<float>::complex(const complex<double>& __c)
495 : __re_(__c.real()), __im_(__c.imag()) {}
496
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000497inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000498_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000499complex<float>::complex(const complex<long double>& __c)
500 : __re_(__c.real()), __im_(__c.imag()) {}
501
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000502inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000503_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000504complex<double>::complex(const complex<float>& __c)
505 : __re_(__c.real()), __im_(__c.imag()) {}
506
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000507inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000508_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000509complex<double>::complex(const complex<long double>& __c)
510 : __re_(__c.real()), __im_(__c.imag()) {}
511
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000512inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000513_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000514complex<long double>::complex(const complex<float>& __c)
515 : __re_(__c.real()), __im_(__c.imag()) {}
516
Evgeniy Stepanov3b68ae52016-04-22 01:04:55 +0000517inline
Howard Hinnant8e556b62012-07-20 22:18:27 +0000518_LIBCPP_CONSTEXPR
Howard Hinnantc51e1022010-05-11 19:42:16 +0000519complex<long double>::complex(const complex<double>& __c)
520 : __re_(__c.real()), __im_(__c.imag()) {}
521
522// 26.3.6 operators:
523
524template<class _Tp>
525inline _LIBCPP_INLINE_VISIBILITY
526complex<_Tp>
527operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
528{
529 complex<_Tp> __t(__x);
530 __t += __y;
531 return __t;
532}
533
534template<class _Tp>
535inline _LIBCPP_INLINE_VISIBILITY
536complex<_Tp>
537operator+(const complex<_Tp>& __x, const _Tp& __y)
538{
539 complex<_Tp> __t(__x);
540 __t += __y;
541 return __t;
542}
543
544template<class _Tp>
545inline _LIBCPP_INLINE_VISIBILITY
546complex<_Tp>
547operator+(const _Tp& __x, const complex<_Tp>& __y)
548{
549 complex<_Tp> __t(__y);
550 __t += __x;
551 return __t;
552}
553
554template<class _Tp>
555inline _LIBCPP_INLINE_VISIBILITY
556complex<_Tp>
557operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
558{
559 complex<_Tp> __t(__x);
560 __t -= __y;
561 return __t;
562}
563
564template<class _Tp>
565inline _LIBCPP_INLINE_VISIBILITY
566complex<_Tp>
567operator-(const complex<_Tp>& __x, const _Tp& __y)
568{
569 complex<_Tp> __t(__x);
570 __t -= __y;
571 return __t;
572}
573
574template<class _Tp>
575inline _LIBCPP_INLINE_VISIBILITY
576complex<_Tp>
577operator-(const _Tp& __x, const complex<_Tp>& __y)
578{
579 complex<_Tp> __t(-__y);
580 __t += __x;
581 return __t;
582}
583
584template<class _Tp>
585complex<_Tp>
586operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
587{
588 _Tp __a = __z.real();
589 _Tp __b = __z.imag();
590 _Tp __c = __w.real();
591 _Tp __d = __w.imag();
592 _Tp __ac = __a * __c;
593 _Tp __bd = __b * __d;
594 _Tp __ad = __a * __d;
595 _Tp __bc = __b * __c;
596 _Tp __x = __ac - __bd;
597 _Tp __y = __ad + __bc;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000598 if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000599 {
600 bool __recalc = false;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000601 if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000602 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000603 __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
604 __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
605 if (__libcpp_isnan_or_builtin(__c))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000606 __c = copysign(_Tp(0), __c);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000607 if (__libcpp_isnan_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000608 __d = copysign(_Tp(0), __d);
609 __recalc = true;
610 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000611 if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000612 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000613 __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
614 __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
615 if (__libcpp_isnan_or_builtin(__a))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000616 __a = copysign(_Tp(0), __a);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000617 if (__libcpp_isnan_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000618 __b = copysign(_Tp(0), __b);
619 __recalc = true;
620 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000621 if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) ||
622 __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000623 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000624 if (__libcpp_isnan_or_builtin(__a))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000625 __a = copysign(_Tp(0), __a);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000626 if (__libcpp_isnan_or_builtin(__b))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000627 __b = copysign(_Tp(0), __b);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000628 if (__libcpp_isnan_or_builtin(__c))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000629 __c = copysign(_Tp(0), __c);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000630 if (__libcpp_isnan_or_builtin(__d))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000631 __d = copysign(_Tp(0), __d);
632 __recalc = true;
633 }
634 if (__recalc)
635 {
636 __x = _Tp(INFINITY) * (__a * __c - __b * __d);
637 __y = _Tp(INFINITY) * (__a * __d + __b * __c);
638 }
639 }
640 return complex<_Tp>(__x, __y);
641}
642
643template<class _Tp>
644inline _LIBCPP_INLINE_VISIBILITY
645complex<_Tp>
646operator*(const complex<_Tp>& __x, const _Tp& __y)
647{
648 complex<_Tp> __t(__x);
649 __t *= __y;
650 return __t;
651}
652
653template<class _Tp>
654inline _LIBCPP_INLINE_VISIBILITY
655complex<_Tp>
656operator*(const _Tp& __x, const complex<_Tp>& __y)
657{
658 complex<_Tp> __t(__y);
659 __t *= __x;
660 return __t;
661}
662
663template<class _Tp>
664complex<_Tp>
665operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
666{
667 int __ilogbw = 0;
668 _Tp __a = __z.real();
669 _Tp __b = __z.imag();
670 _Tp __c = __w.real();
671 _Tp __d = __w.imag();
672 _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000673 if (__libcpp_isfinite_or_builtin(__logbw))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000674 {
675 __ilogbw = static_cast<int>(__logbw);
676 __c = scalbn(__c, -__ilogbw);
677 __d = scalbn(__d, -__ilogbw);
678 }
679 _Tp __denom = __c * __c + __d * __d;
680 _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
681 _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000682 if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000683 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000684 if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b)))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000685 {
686 __x = copysign(_Tp(INFINITY), __c) * __a;
687 __y = copysign(_Tp(INFINITY), __c) * __b;
688 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000689 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 +0000690 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000691 __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a);
692 __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000693 __x = _Tp(INFINITY) * (__a * __c + __b * __d);
694 __y = _Tp(INFINITY) * (__b * __c - __a * __d);
695 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000696 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 +0000697 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000698 __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c);
699 __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000700 __x = _Tp(0) * (__a * __c + __b * __d);
701 __y = _Tp(0) * (__b * __c - __a * __d);
702 }
703 }
704 return complex<_Tp>(__x, __y);
705}
706
707template<class _Tp>
708inline _LIBCPP_INLINE_VISIBILITY
709complex<_Tp>
710operator/(const complex<_Tp>& __x, const _Tp& __y)
711{
712 return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
713}
714
715template<class _Tp>
716inline _LIBCPP_INLINE_VISIBILITY
717complex<_Tp>
718operator/(const _Tp& __x, const complex<_Tp>& __y)
719{
720 complex<_Tp> __t(__x);
721 __t /= __y;
722 return __t;
723}
724
725template<class _Tp>
726inline _LIBCPP_INLINE_VISIBILITY
727complex<_Tp>
728operator+(const complex<_Tp>& __x)
729{
730 return __x;
731}
732
733template<class _Tp>
734inline _LIBCPP_INLINE_VISIBILITY
735complex<_Tp>
736operator-(const complex<_Tp>& __x)
737{
738 return complex<_Tp>(-__x.real(), -__x.imag());
739}
740
741template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000742inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000743bool
744operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
745{
746 return __x.real() == __y.real() && __x.imag() == __y.imag();
747}
748
749template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000750inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000751bool
752operator==(const complex<_Tp>& __x, const _Tp& __y)
753{
754 return __x.real() == __y && __x.imag() == 0;
755}
756
757template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000758inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000759bool
760operator==(const _Tp& __x, const complex<_Tp>& __y)
761{
762 return __x == __y.real() && 0 == __y.imag();
763}
764
765template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000766inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000767bool
768operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
769{
770 return !(__x == __y);
771}
772
773template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000774inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000775bool
776operator!=(const complex<_Tp>& __x, const _Tp& __y)
777{
778 return !(__x == __y);
779}
780
781template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000782inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000783bool
784operator!=(const _Tp& __x, const complex<_Tp>& __y)
785{
786 return !(__x == __y);
787}
788
Howard Hinnantc51e1022010-05-11 19:42:16 +0000789// 26.3.7 values:
790
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000791template <class _Tp, bool = is_integral<_Tp>::value,
792 bool = is_floating_point<_Tp>::value
793 >
794struct __libcpp_complex_overload_traits {};
795
796// Integral Types
797template <class _Tp>
798struct __libcpp_complex_overload_traits<_Tp, true, false>
799{
800 typedef double _ValueType;
801 typedef complex<double> _ComplexType;
802};
803
804// Floating point types
805template <class _Tp>
806struct __libcpp_complex_overload_traits<_Tp, false, true>
807{
808 typedef _Tp _ValueType;
809 typedef complex<_Tp> _ComplexType;
810};
811
Howard Hinnantc51e1022010-05-11 19:42:16 +0000812// real
813
814template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000815inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000816_Tp
817real(const complex<_Tp>& __c)
818{
819 return __c.real();
820}
821
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000822template <class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000823inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000824typename __libcpp_complex_overload_traits<_Tp>::_ValueType
825real(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000826{
827 return __re;
828}
829
830// imag
831
832template<class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000833inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Howard Hinnantc51e1022010-05-11 19:42:16 +0000834_Tp
835imag(const complex<_Tp>& __c)
836{
837 return __c.imag();
838}
839
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000840template <class _Tp>
Marshall Clowdf7b6942013-07-31 21:02:34 +0000841inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000842typename __libcpp_complex_overload_traits<_Tp>::_ValueType
Eric Fiselier6003c772016-12-23 23:37:52 +0000843imag(_Tp)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000844{
845 return 0;
846}
847
848// abs
849
850template<class _Tp>
851inline _LIBCPP_INLINE_VISIBILITY
852_Tp
853abs(const complex<_Tp>& __c)
854{
855 return hypot(__c.real(), __c.imag());
856}
857
858// arg
859
860template<class _Tp>
861inline _LIBCPP_INLINE_VISIBILITY
862_Tp
863arg(const complex<_Tp>& __c)
864{
865 return atan2(__c.imag(), __c.real());
866}
867
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000868template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000869inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000870typename enable_if<
871 is_same<_Tp, long double>::value,
872 long double
873>::type
874arg(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000875{
876 return atan2l(0.L, __re);
877}
878
Howard Hinnantc51e1022010-05-11 19:42:16 +0000879template<class _Tp>
880inline _LIBCPP_INLINE_VISIBILITY
881typename enable_if
882<
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000883 is_integral<_Tp>::value || is_same<_Tp, double>::value,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000884 double
885>::type
886arg(_Tp __re)
887{
888 return atan2(0., __re);
889}
890
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000891template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000892inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000893typename enable_if<
894 is_same<_Tp, float>::value,
895 float
896>::type
897arg(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000898{
899 return atan2f(0.F, __re);
900}
901
902// norm
903
904template<class _Tp>
905inline _LIBCPP_INLINE_VISIBILITY
906_Tp
907norm(const complex<_Tp>& __c)
908{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000909 if (__libcpp_isinf_or_builtin(__c.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000910 return abs(__c.real());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000911 if (__libcpp_isinf_or_builtin(__c.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000912 return abs(__c.imag());
913 return __c.real() * __c.real() + __c.imag() * __c.imag();
914}
915
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000916template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000917inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000918typename __libcpp_complex_overload_traits<_Tp>::_ValueType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000919norm(_Tp __re)
920{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000921 typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType;
922 return static_cast<_ValueType>(__re) * __re;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000923}
924
925// conj
926
927template<class _Tp>
928inline _LIBCPP_INLINE_VISIBILITY
929complex<_Tp>
930conj(const complex<_Tp>& __c)
931{
932 return complex<_Tp>(__c.real(), -__c.imag());
933}
934
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000935template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000936inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000937typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000938conj(_Tp __re)
939{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000940 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
941 return _ComplexType(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000942}
943
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000944
Howard Hinnantc51e1022010-05-11 19:42:16 +0000945
946// proj
947
948template<class _Tp>
949inline _LIBCPP_INLINE_VISIBILITY
950complex<_Tp>
951proj(const complex<_Tp>& __c)
952{
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500953 complex<_Tp> __r = __c;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000954 if (__libcpp_isinf_or_builtin(__c.real()) || __libcpp_isinf_or_builtin(__c.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000955 __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
956 return __r;
957}
958
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000959template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000960inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000961typename enable_if
962<
963 is_floating_point<_Tp>::value,
964 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
965>::type
966proj(_Tp __re)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000967{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000968 if (__libcpp_isinf_or_builtin(__re))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000969 __re = abs(__re);
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000970 return complex<_Tp>(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000971}
972
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000973template <class _Tp>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000974inline _LIBCPP_INLINE_VISIBILITY
975typename enable_if
976<
977 is_integral<_Tp>::value,
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000978 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType
Howard Hinnantc51e1022010-05-11 19:42:16 +0000979>::type
980proj(_Tp __re)
981{
Eric Fiselierf8b772b2016-07-20 00:14:10 +0000982 typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType;
983 return _ComplexType(__re);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000984}
985
Howard Hinnantc51e1022010-05-11 19:42:16 +0000986// polar
987
988template<class _Tp>
989complex<_Tp>
Marshall Clow2f283732018-01-31 21:42:39 +0000990polar(const _Tp& __rho, const _Tp& __theta = _Tp())
Howard Hinnantc51e1022010-05-11 19:42:16 +0000991{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000992 if (__libcpp_isnan_or_builtin(__rho) || signbit(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000993 return complex<_Tp>(_Tp(NAN), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000994 if (__libcpp_isnan_or_builtin(__theta))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000995 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +0000996 if (__libcpp_isinf_or_builtin(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +0000997 return complex<_Tp>(__rho, __theta);
998 return complex<_Tp>(__theta, __theta);
999 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001000 if (__libcpp_isinf_or_builtin(__theta))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001001 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001002 if (__libcpp_isinf_or_builtin(__rho))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001003 return complex<_Tp>(__rho, _Tp(NAN));
1004 return complex<_Tp>(_Tp(NAN), _Tp(NAN));
1005 }
1006 _Tp __x = __rho * cos(__theta);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001007 if (__libcpp_isnan_or_builtin(__x))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001008 __x = 0;
1009 _Tp __y = __rho * sin(__theta);
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001010 if (__libcpp_isnan_or_builtin(__y))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001011 __y = 0;
1012 return complex<_Tp>(__x, __y);
1013}
1014
1015// log
1016
1017template<class _Tp>
1018inline _LIBCPP_INLINE_VISIBILITY
1019complex<_Tp>
1020log(const complex<_Tp>& __x)
1021{
1022 return complex<_Tp>(log(abs(__x)), arg(__x));
1023}
1024
1025// log10
1026
1027template<class _Tp>
1028inline _LIBCPP_INLINE_VISIBILITY
1029complex<_Tp>
1030log10(const complex<_Tp>& __x)
1031{
1032 return log(__x) / log(_Tp(10));
1033}
1034
1035// sqrt
1036
1037template<class _Tp>
1038complex<_Tp>
1039sqrt(const complex<_Tp>& __x)
1040{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001041 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001042 return complex<_Tp>(_Tp(INFINITY), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001043 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001044 {
1045 if (__x.real() > _Tp(0))
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001046 return complex<_Tp>(__x.real(), __libcpp_isnan_or_builtin(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
1047 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 +00001048 }
1049 return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
1050}
1051
1052// exp
1053
1054template<class _Tp>
1055complex<_Tp>
1056exp(const complex<_Tp>& __x)
1057{
1058 _Tp __i = __x.imag();
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001059 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001060 {
1061 if (__x.real() < _Tp(0))
1062 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001063 if (!__libcpp_isfinite_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001064 __i = _Tp(1);
1065 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001066 else if (__i == 0 || !__libcpp_isfinite_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001067 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001068 if (__libcpp_isinf_or_builtin(__i))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001069 __i = _Tp(NAN);
1070 return complex<_Tp>(__x.real(), __i);
1071 }
1072 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001073 else if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001074 return __x;
1075 _Tp __e = exp(__x.real());
1076 return complex<_Tp>(__e * cos(__i), __e * sin(__i));
1077}
1078
1079// pow
1080
1081template<class _Tp>
1082inline _LIBCPP_INLINE_VISIBILITY
1083complex<_Tp>
1084pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
1085{
1086 return exp(__y * log(__x));
1087}
1088
1089template<class _Tp, class _Up>
1090inline _LIBCPP_INLINE_VISIBILITY
1091complex<typename __promote<_Tp, _Up>::type>
1092pow(const complex<_Tp>& __x, const complex<_Up>& __y)
1093{
1094 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001095 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001096}
1097
1098template<class _Tp, class _Up>
1099inline _LIBCPP_INLINE_VISIBILITY
1100typename enable_if
1101<
1102 is_arithmetic<_Up>::value,
1103 complex<typename __promote<_Tp, _Up>::type>
1104>::type
1105pow(const complex<_Tp>& __x, const _Up& __y)
1106{
1107 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001108 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001109}
1110
1111template<class _Tp, class _Up>
1112inline _LIBCPP_INLINE_VISIBILITY
1113typename enable_if
1114<
1115 is_arithmetic<_Tp>::value,
1116 complex<typename __promote<_Tp, _Up>::type>
1117>::type
1118pow(const _Tp& __x, const complex<_Up>& __y)
1119{
1120 typedef complex<typename __promote<_Tp, _Up>::type> result_type;
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001121 return _VSTD::pow(result_type(__x), result_type(__y));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001122}
1123
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001124// __sqr, computes pow(x, 2)
1125
1126template<class _Tp>
1127inline _LIBCPP_INLINE_VISIBILITY
1128complex<_Tp>
1129__sqr(const complex<_Tp>& __x)
1130{
1131 return complex<_Tp>((__x.real() - __x.imag()) * (__x.real() + __x.imag()),
1132 _Tp(2) * __x.real() * __x.imag());
1133}
1134
Howard Hinnantc51e1022010-05-11 19:42:16 +00001135// asinh
1136
1137template<class _Tp>
1138complex<_Tp>
1139asinh(const complex<_Tp>& __x)
1140{
1141 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001142 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001143 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001144 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001145 return __x;
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001146 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001147 return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1148 return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1149 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001150 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001151 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001152 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001153 return complex<_Tp>(__x.imag(), __x.real());
1154 if (__x.imag() == 0)
1155 return __x;
1156 return complex<_Tp>(__x.real(), __x.real());
1157 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001158 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001159 return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001160 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) + _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001161 return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1162}
1163
1164// acosh
1165
1166template<class _Tp>
1167complex<_Tp>
1168acosh(const complex<_Tp>& __x)
1169{
1170 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001171 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001172 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001173 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001174 return complex<_Tp>(abs(__x.real()), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001175 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnant3edce762012-11-06 21:55:44 +00001176 {
Howard Hinnantc51e1022010-05-11 19:42:16 +00001177 if (__x.real() > 0)
1178 return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
1179 else
1180 return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
Howard Hinnant3edce762012-11-06 21:55:44 +00001181 }
Howard Hinnantc51e1022010-05-11 19:42:16 +00001182 if (__x.real() < 0)
1183 return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
1184 return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
1185 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001186 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001187 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001188 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001189 return complex<_Tp>(abs(__x.imag()), __x.real());
1190 return complex<_Tp>(__x.real(), __x.real());
1191 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001192 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001193 return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001194 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001195 return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
1196}
1197
1198// atanh
1199
1200template<class _Tp>
1201complex<_Tp>
1202atanh(const complex<_Tp>& __x)
1203{
1204 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001205 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001206 {
1207 return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1208 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001209 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001210 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001211 if (__libcpp_isinf_or_builtin(__x.real()) || __x.real() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001212 return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
1213 return complex<_Tp>(__x.imag(), __x.imag());
1214 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001215 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001216 {
1217 return complex<_Tp>(__x.real(), __x.real());
1218 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001219 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001220 {
1221 return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
1222 }
1223 if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
1224 {
1225 return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
1226 }
1227 complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
1228 return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
1229}
1230
1231// sinh
1232
1233template<class _Tp>
1234complex<_Tp>
1235sinh(const complex<_Tp>& __x)
1236{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001237 if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001238 return complex<_Tp>(__x.real(), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001239 if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001240 return complex<_Tp>(__x.real(), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001241 if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001242 return __x;
1243 return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
1244}
1245
1246// cosh
1247
1248template<class _Tp>
1249complex<_Tp>
1250cosh(const complex<_Tp>& __x)
1251{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001252 if (__libcpp_isinf_or_builtin(__x.real()) && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001253 return complex<_Tp>(abs(__x.real()), _Tp(NAN));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001254 if (__x.real() == 0 && !__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001255 return complex<_Tp>(_Tp(NAN), __x.real());
1256 if (__x.real() == 0 && __x.imag() == 0)
1257 return complex<_Tp>(_Tp(1), __x.imag());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001258 if (__x.imag() == 0 && !__libcpp_isfinite_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001259 return complex<_Tp>(abs(__x.real()), __x.imag());
1260 return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
1261}
1262
1263// tanh
1264
1265template<class _Tp>
1266complex<_Tp>
1267tanh(const complex<_Tp>& __x)
1268{
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001269 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001270 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001271 if (!__libcpp_isfinite_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001272 return complex<_Tp>(_Tp(1), _Tp(0));
1273 return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
1274 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001275 if (__libcpp_isnan_or_builtin(__x.real()) && __x.imag() == 0)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001276 return __x;
1277 _Tp __2r(_Tp(2) * __x.real());
1278 _Tp __2i(_Tp(2) * __x.imag());
1279 _Tp __d(cosh(__2r) + cos(__2i));
Howard Hinnant3e7b3b52012-09-19 23:51:47 +00001280 _Tp __2rsh(sinh(__2r));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001281 if (__libcpp_isinf_or_builtin(__2rsh) && __libcpp_isinf_or_builtin(__d))
Howard Hinnant3e7b3b52012-09-19 23:51:47 +00001282 return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
1283 __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
1284 return complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001285}
1286
1287// asin
1288
1289template<class _Tp>
1290complex<_Tp>
1291asin(const complex<_Tp>& __x)
1292{
1293 complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
1294 return complex<_Tp>(__z.imag(), -__z.real());
1295}
1296
1297// acos
1298
1299template<class _Tp>
1300complex<_Tp>
1301acos(const complex<_Tp>& __x)
1302{
1303 const _Tp __pi(atan2(+0., -0.));
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001304 if (__libcpp_isinf_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001305 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001306 if (__libcpp_isnan_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001307 return complex<_Tp>(__x.imag(), __x.real());
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001308 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001309 {
1310 if (__x.real() < _Tp(0))
1311 return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
1312 return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
1313 }
1314 if (__x.real() < _Tp(0))
1315 return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
1316 return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
1317 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001318 if (__libcpp_isnan_or_builtin(__x.real()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001319 {
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001320 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001321 return complex<_Tp>(__x.real(), -__x.imag());
1322 return complex<_Tp>(__x.real(), __x.real());
1323 }
Duncan P. N. Exon Smith4a297202017-07-07 05:13:36 +00001324 if (__libcpp_isinf_or_builtin(__x.imag()))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001325 return complex<_Tp>(__pi/_Tp(2), -__x.imag());
Marshall Clow17af7e42016-04-04 16:08:54 +00001326 if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag())))
Howard Hinnantc51e1022010-05-11 19:42:16 +00001327 return complex<_Tp>(__pi/_Tp(2), -__x.imag());
Mikhail Maltsevfa9a85e2018-02-19 15:41:36 +00001328 complex<_Tp> __z = log(__x + sqrt(__sqr(__x) - _Tp(1)));
Howard Hinnantc51e1022010-05-11 19:42:16 +00001329 if (signbit(__x.imag()))
1330 return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
1331 return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
1332}
1333
1334// atan
1335
1336template<class _Tp>
1337complex<_Tp>
1338atan(const complex<_Tp>& __x)
1339{
1340 complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
1341 return complex<_Tp>(__z.imag(), -__z.real());
1342}
1343
1344// sin
1345
1346template<class _Tp>
1347complex<_Tp>
1348sin(const complex<_Tp>& __x)
1349{
1350 complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
1351 return complex<_Tp>(__z.imag(), -__z.real());
1352}
1353
1354// cos
1355
1356template<class _Tp>
1357inline _LIBCPP_INLINE_VISIBILITY
1358complex<_Tp>
1359cos(const complex<_Tp>& __x)
1360{
1361 return cosh(complex<_Tp>(-__x.imag(), __x.real()));
1362}
1363
1364// tan
1365
1366template<class _Tp>
1367complex<_Tp>
1368tan(const complex<_Tp>& __x)
1369{
1370 complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
1371 return complex<_Tp>(__z.imag(), -__z.real());
1372}
1373
1374template<class _Tp, class _CharT, class _Traits>
1375basic_istream<_CharT, _Traits>&
1376operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
1377{
1378 if (__is.good())
1379 {
1380 ws(__is);
1381 if (__is.peek() == _CharT('('))
1382 {
1383 __is.get();
1384 _Tp __r;
1385 __is >> __r;
1386 if (!__is.fail())
1387 {
1388 ws(__is);
1389 _CharT __c = __is.peek();
1390 if (__c == _CharT(','))
1391 {
1392 __is.get();
1393 _Tp __i;
1394 __is >> __i;
1395 if (!__is.fail())
1396 {
1397 ws(__is);
1398 __c = __is.peek();
1399 if (__c == _CharT(')'))
1400 {
1401 __is.get();
1402 __x = complex<_Tp>(__r, __i);
1403 }
1404 else
Louis Dionne2d937822020-02-19 16:09:41 -05001405 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001406 }
1407 else
Louis Dionne2d937822020-02-19 16:09:41 -05001408 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001409 }
1410 else if (__c == _CharT(')'))
1411 {
1412 __is.get();
1413 __x = complex<_Tp>(__r, _Tp(0));
1414 }
1415 else
Louis Dionne2d937822020-02-19 16:09:41 -05001416 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001417 }
1418 else
Louis Dionne2d937822020-02-19 16:09:41 -05001419 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001420 }
1421 else
1422 {
1423 _Tp __r;
1424 __is >> __r;
1425 if (!__is.fail())
1426 __x = complex<_Tp>(__r, _Tp(0));
1427 else
Louis Dionne2d937822020-02-19 16:09:41 -05001428 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001429 }
1430 }
1431 else
Louis Dionne2d937822020-02-19 16:09:41 -05001432 __is.setstate(__is.failbit);
Howard Hinnantc51e1022010-05-11 19:42:16 +00001433 return __is;
1434}
1435
Louis Dionne8d053eb2020-10-09 15:31:05 -04001436#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
Howard Hinnantc51e1022010-05-11 19:42:16 +00001437template<class _Tp, class _CharT, class _Traits>
1438basic_ostream<_CharT, _Traits>&
1439operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
1440{
Antonio Sanchezd4fb7402020-05-07 13:49:12 -04001441 basic_ostringstream<_CharT, _Traits> __s;
1442 __s.flags(__os.flags());
1443 __s.imbue(__os.getloc());
1444 __s.precision(__os.precision());
1445 __s << '(' << __x.real() << ',' << __x.imag() << ')';
1446 return __os << __s.str();
Howard Hinnantc51e1022010-05-11 19:42:16 +00001447}
Louis Dionne8d053eb2020-10-09 15:31:05 -04001448#endif // !_LIBCPP_HAS_NO_LOCALIZATION
Howard Hinnantc51e1022010-05-11 19:42:16 +00001449
Louis Dionne173f29e2019-05-29 16:01:36 +00001450#if _LIBCPP_STD_VER > 11
Marshall Clow35f91142013-10-05 21:19:49 +00001451// Literal suffix for complex number literals [complex.literals]
1452inline namespace literals
Louis Dionne173f29e2019-05-29 16:01:36 +00001453{
Marshall Clow35f91142013-10-05 21:19:49 +00001454 inline namespace complex_literals
1455 {
1456 constexpr complex<long double> operator""il(long double __im)
1457 {
1458 return { 0.0l, __im };
1459 }
1460
1461 constexpr complex<long double> operator""il(unsigned long long __im)
1462 {
1463 return { 0.0l, static_cast<long double>(__im) };
1464 }
1465
1466
1467 constexpr complex<double> operator""i(long double __im)
1468 {
1469 return { 0.0, static_cast<double>(__im) };
1470 }
1471
1472 constexpr complex<double> operator""i(unsigned long long __im)
1473 {
1474 return { 0.0, static_cast<double>(__im) };
1475 }
1476
1477
1478 constexpr complex<float> operator""if(long double __im)
1479 {
1480 return { 0.0f, static_cast<float>(__im) };
1481 }
1482
1483 constexpr complex<float> operator""if(unsigned long long __im)
1484 {
1485 return { 0.0f, static_cast<float>(__im) };
1486 }
1487 }
1488}
1489#endif
1490
Howard Hinnantc51e1022010-05-11 19:42:16 +00001491_LIBCPP_END_NAMESPACE_STD
1492
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001493#endif // _LIBCPP_COMPLEX