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