// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___CXX03_COMPLEX
#define _LIBCPP___CXX03_COMPLEX

/*
    complex synopsis

namespace std
{

template<class T>
class complex
{
public:
    typedef T value_type;

    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
    complex(const complex&);  // constexpr in C++14
    template<class X> complex(const complex<X>&);  // constexpr in C++14

    T real() const; // constexpr in C++14
    T imag() const; // constexpr in C++14

    void real(T); // constexpr in C++20
    void imag(T); // constexpr in C++20

    complex<T>& operator= (const T&); // constexpr in C++20
    complex<T>& operator+=(const T&); // constexpr in C++20
    complex<T>& operator-=(const T&); // constexpr in C++20
    complex<T>& operator*=(const T&); // constexpr in C++20
    complex<T>& operator/=(const T&); // constexpr in C++20

    complex& operator=(const complex&); // constexpr in C++20
    template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++20
    template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++20
    template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++20
    template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++20
    template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++20
};

template<>
class complex<float>
{
public:
    typedef float value_type;

    constexpr complex(float re = 0.0f, float im = 0.0f);
    explicit constexpr complex(const complex<double>&);
    explicit constexpr complex(const complex<long double>&);

    constexpr float real() const;
    void real(float); // constexpr in C++20
    constexpr float imag() const;
    void imag(float); // constexpr in C++20

    complex<float>& operator= (float); // constexpr in C++20
    complex<float>& operator+=(float); // constexpr in C++20
    complex<float>& operator-=(float); // constexpr in C++20
    complex<float>& operator*=(float); // constexpr in C++20
    complex<float>& operator/=(float); // constexpr in C++20

    complex<float>& operator=(const complex<float>&); // constexpr in C++20
    template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++20
    template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++20
    template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++20
    template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++20
    template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++20
};

template<>
class complex<double>
{
public:
    typedef double value_type;

    constexpr complex(double re = 0.0, double im = 0.0);
    constexpr complex(const complex<float>&);
    explicit constexpr complex(const complex<long double>&);

    constexpr double real() const;
    void real(double); // constexpr in C++20
    constexpr double imag() const;
    void imag(double); // constexpr in C++20

    complex<double>& operator= (double); // constexpr in C++20
    complex<double>& operator+=(double); // constexpr in C++20
    complex<double>& operator-=(double); // constexpr in C++20
    complex<double>& operator*=(double); // constexpr in C++20
    complex<double>& operator/=(double); // constexpr in C++20
    complex<double>& operator=(const complex<double>&); // constexpr in C++20

    template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20
    template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20
    template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20
    template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20
    template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20
};

template<>
class complex<long double>
{
public:
    typedef long double value_type;

    constexpr complex(long double re = 0.0L, long double im = 0.0L);
    constexpr complex(const complex<float>&);
    constexpr complex(const complex<double>&);

    constexpr long double real() const;
    void real(long double); // constexpr in C++20
    constexpr long double imag() const;
    void imag(long double); // constexpr in C++20

    complex<long double>& operator=(const complex<long double>&); // constexpr in C++20
    complex<long double>& operator= (long double); // constexpr in C++20
    complex<long double>& operator+=(long double); // constexpr in C++20
    complex<long double>& operator-=(long double); // constexpr in C++20
    complex<long double>& operator*=(long double); // constexpr in C++20
    complex<long double>& operator/=(long double); // constexpr in C++20

    template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20
    template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20
    template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20
    template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20
    template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20
};

// 26.3.6 operators:
template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20
template<class T> complex<T> operator+(const complex<T>&, const T&);          // constexpr in C++20
template<class T> complex<T> operator+(const T&, const complex<T>&);          // constexpr in C++20
template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20
template<class T> complex<T> operator-(const complex<T>&, const T&);          // constexpr in C++20
template<class T> complex<T> operator-(const T&, const complex<T>&);          // constexpr in C++20
template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20
template<class T> complex<T> operator*(const complex<T>&, const T&);          // constexpr in C++20
template<class T> complex<T> operator*(const T&, const complex<T>&);          // constexpr in C++20
template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20
template<class T> complex<T> operator/(const complex<T>&, const T&);          // constexpr in C++20
template<class T> complex<T> operator/(const T&, const complex<T>&);          // constexpr in C++20
template<class T> complex<T> operator+(const complex<T>&);                    // constexpr in C++20
template<class T> complex<T> operator-(const complex<T>&);                    // constexpr in C++20
template<class T> bool operator==(const complex<T>&, const complex<T>&);      // constexpr in C++14
template<class T> bool operator==(const complex<T>&, const T&);               // constexpr in C++14
template<class T> bool operator==(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20
template<class T> bool operator!=(const complex<T>&, const complex<T>&);      // constexpr in C++14, removed in C++20
template<class T> bool operator!=(const complex<T>&, const T&);               // constexpr in C++14, removed in C++20
template<class T> bool operator!=(const T&, const complex<T>&);               // constexpr in C++14, removed in C++20

template<class T, class charT, class traits>
  basic_istream<charT, traits>&
  operator>>(basic_istream<charT, traits>&, complex<T>&);
template<class T, class charT, class traits>
  basic_ostream<charT, traits>&
  operator<<(basic_ostream<charT, traits>&, const complex<T>&);

// 26.3.7 values:

template<class T>              T real(const complex<T>&); // constexpr in C++14
                     long double real(long double);       // constexpr in C++14
                          double real(double);            // constexpr in C++14
template<Integral T>      double real(T);                 // constexpr in C++14
                          float  real(float);             // constexpr in C++14

template<class T>              T imag(const complex<T>&); // constexpr in C++14
                     long double imag(long double);       // constexpr in C++14
                          double imag(double);            // constexpr in C++14
template<Integral T>      double imag(T);                 // constexpr in C++14
                          float  imag(float);             // constexpr in C++14

template<class T> T abs(const complex<T>&);

template<class T>              T arg(const complex<T>&);
                     long double arg(long double);
                          double arg(double);
template<Integral T>      double arg(T);
                          float  arg(float);

template<class T>              T norm(const complex<T>&); // constexpr in C++20
                     long double norm(long double);       // constexpr in C++20
                          double norm(double);            // constexpr in C++20
template<Integral T>      double norm(T);                 // constexpr in C++20
                          float  norm(float);             // constexpr in C++20

template<class T>      complex<T>           conj(const complex<T>&); // constexpr in C++20
                       complex<long double> conj(long double);       // constexpr in C++20
                       complex<double>      conj(double);            // constexpr in C++20
template<Integral T>   complex<double>      conj(T);                 // constexpr in C++20
                       complex<float>       conj(float);             // constexpr in C++20

template<class T>    complex<T>           proj(const complex<T>&);
                     complex<long double> proj(long double);
                     complex<double>      proj(double);
template<Integral T> complex<double>      proj(T);
                     complex<float>       proj(float);

template<class T> complex<T> polar(const T&, const T& = T());

// 26.3.8 transcendentals:
template<class T> complex<T> acos(const complex<T>&);
template<class T> complex<T> asin(const complex<T>&);
template<class T> complex<T> atan(const complex<T>&);
template<class T> complex<T> acosh(const complex<T>&);
template<class T> complex<T> asinh(const complex<T>&);
template<class T> complex<T> atanh(const complex<T>&);
template<class T> complex<T> cos (const complex<T>&);
template<class T> complex<T> cosh (const complex<T>&);
template<class T> complex<T> exp (const complex<T>&);
template<class T> complex<T> log (const complex<T>&);
template<class T> complex<T> log10(const complex<T>&);

template<class T> complex<T> pow(const complex<T>&, const T&);
template<class T> complex<T> pow(const complex<T>&, const complex<T>&);
template<class T> complex<T> pow(const T&, const complex<T>&);

template<class T> complex<T> sin (const complex<T>&);
template<class T> complex<T> sinh (const complex<T>&);
template<class T> complex<T> sqrt (const complex<T>&);
template<class T> complex<T> tan (const complex<T>&);
template<class T> complex<T> tanh (const complex<T>&);

  // [complex.tuple], tuple interface
  template<class T> struct tuple_size;                               // Since C++26
  template<size_t I, class T> struct tuple_element;                  // Since C++26
  template<class T> struct tuple_size<complex<T>>;                   // Since C++26
  template<size_t I, class T> struct tuple_element<I, complex<T>>;   // Since C++26
  template<size_t I, class T>
    constexpr T& get(complex<T>&) noexcept;                          // Since C++26
  template<size_t I, class T>
    constexpr T&& get(complex<T>&&) noexcept;                        // Since C++26
  template<size_t I, class T>
    constexpr const T& get(const complex<T>&) noexcept;              // Since C++26
  template<size_t I, class T>
    constexpr const T&& get(const complex<T>&&) noexcept;            // Since C++26

  // [complex.literals], complex literals
  inline namespace literals {
  inline namespace complex_literals {
    constexpr complex<long double> operator""il(long double);        // Since C++14
    constexpr complex<long double> operator""il(unsigned long long); // Since C++14
    constexpr complex<double> operator""i(long double);              // Since C++14
    constexpr complex<double> operator""i(unsigned long long);       // Since C++14
    constexpr complex<float> operator""if(long double);              // Since C++14
    constexpr complex<float> operator""if(unsigned long long);       // Since C++14
  }
  }
}  // std

*/

#include <__cxx03/__config>
#include <__cxx03/__fwd/complex.h>
#include <__cxx03/__fwd/tuple.h>
#include <__cxx03/__tuple/tuple_element.h>
#include <__cxx03/__tuple/tuple_size.h>
#include <__cxx03/__type_traits/conditional.h>
#include <__cxx03/__utility/move.h>
#include <__cxx03/cmath>
#include <__cxx03/version>

#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#  include <__cxx03/sstream> // for std::basic_ostringstream
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__cxx03/__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp>
class _LIBCPP_TEMPLATE_VIS complex;

template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);

template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI complex<_Tp> operator*(const complex                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 