codekingpro/portable-devtools
114k
1// -*- C++ -*-2//===--------------------------- complex ----------------------------------===//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-exception7// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.8//9//===----------------------------------------------------------------------===//10 11#ifndef _LIBCUDACXX_COMPLEX12#define _LIBCUDACXX_COMPLEX13 14/*15 complex synopsis16 17namespace std18{19 20template<class T>21class complex22{23public:24 typedef T value_type;25 26 complex(const T& re = T(), const T& im = T()); // constexpr in C++1427 complex(const complex&); // constexpr in C++1428 template<class X> complex(const complex<X>&); // constexpr in C++1429 30 T real() const; // constexpr in C++1431 T imag() const; // constexpr in C++1432 33 void real(T); // constexpr in C++2034 void imag(T); // constexpr in C++2035 36 complex<T>& operator= (const T&); // constexpr in C++2037 complex<T>& operator+=(const T&); // constexpr in C++2038 complex<T>& operator-=(const T&); // constexpr in C++2039 complex<T>& operator*=(const T&); // constexpr in C++2040 complex<T>& operator/=(const T&); // constexpr in C++2041 42 complex& operator=(const complex&); // constexpr in C++2043 template<class X> complex<T>& operator= (const complex<X>&); // constexpr in C++2044 template<class X> complex<T>& operator+=(const complex<X>&); // constexpr in C++2045 template<class X> complex<T>& operator-=(const complex<X>&); // constexpr in C++2046 template<class X> complex<T>& operator*=(const complex<X>&); // constexpr in C++2047 template<class X> complex<T>& operator/=(const complex<X>&); // constexpr in C++2048};49 50template<>51class complex<float>52{53public:54 typedef float value_type;55 56 constexpr complex(float re = 0.0f, float im = 0.0f);57 explicit constexpr complex(const complex<double>&);58 explicit constexpr complex(const complex<long double>&);59 60 constexpr float real() const;61 void real(float); // constexpr in C++2062 constexpr float imag() const;63 void imag(float); // constexpr in C++2064 65 complex<float>& operator= (float); // constexpr in C++2066 complex<float>& operator+=(float); // constexpr in C++2067 complex<float>& operator-=(float); // constexpr in C++2068 complex<float>& operator*=(float); // constexpr in C++2069 complex<float>& operator/=(float); // constexpr in C++2070 71 complex<float>& operator=(const complex<float>&); // constexpr in C++2072 template<class X> complex<float>& operator= (const complex<X>&); // constexpr in C++2073 template<class X> complex<float>& operator+=(const complex<X>&); // constexpr in C++2074 template<class X> complex<float>& operator-=(const complex<X>&); // constexpr in C++2075 template<class X> complex<float>& operator*=(const complex<X>&); // constexpr in C++2076 template<class X> complex<float>& operator/=(const complex<X>&); // constexpr in C++2077};78 79template<>80class complex<double>81{82public:83 typedef double value_type;84 85 constexpr complex(double re = 0.0, double im = 0.0);86 constexpr complex(const complex<float>&);87 explicit constexpr complex(const complex<long double>&);88 89 constexpr double real() const;90 void real(double); // constexpr in C++2091 constexpr double imag() const;92 void imag(double); // constexpr in C++2093 94 complex<double>& operator= (double); // constexpr in C++2095 complex<double>& operator+=(double); // constexpr in C++2096 complex<double>& operator-=(double); // constexpr in C++2097 complex<double>& operator*=(double); // constexpr in C++2098 complex<double>& operator/=(double); // constexpr in C++2099 complex<double>& operator=(const complex<double>&); // constexpr in C++20100 101 template<class X> complex<double>& operator= (const complex<X>&); // constexpr in C++20102 template<class X> complex<double>& operator+=(const complex<X>&); // constexpr in C++20103 template<class X> complex<double>& operator-=(const complex<X>&); // constexpr in C++20104 template<class X> complex<double>& operator*=(const complex<X>&); // constexpr in C++20105 template<class X> complex<double>& operator/=(const complex<X>&); // constexpr in C++20106};107 108template<>109class complex<long double>110{111public:112 typedef long double value_type;113 114 constexpr complex(long double re = 0.0L, long double im = 0.0L);115 constexpr complex(const complex<float>&);116 constexpr complex(const complex<double>&);117 118 constexpr long double real() const;119 void real(long double); // constexpr in C++20120 constexpr long double imag() const;121 void imag(long double); // constexpr in C++20122 123 complex<long double>& operator=(const complex<long double>&); // constexpr in C++20124 complex<long double>& operator= (long double); // constexpr in C++20125 complex<long double>& operator+=(long double); // constexpr in C++20126 complex<long double>& operator-=(long double); // constexpr in C++20127 complex<long double>& operator*=(long double); // constexpr in C++20128 complex<long double>& operator/=(long double); // constexpr in C++20129 130 template<class X> complex<long double>& operator= (const complex<X>&); // constexpr in C++20131 template<class X> complex<long double>& operator+=(const complex<X>&); // constexpr in C++20132 template<class X> complex<long double>& operator-=(const complex<X>&); // constexpr in C++20133 template<class X> complex<long double>& operator*=(const complex<X>&); // constexpr in C++20134 template<class X> complex<long double>& operator/=(const complex<X>&); // constexpr in C++20135};136 137// 26.3.6 operators:138template<class T> complex<T> operator+(const complex<T>&, const complex<T>&); // constexpr in C++20139template<class T> complex<T> operator+(const complex<T>&, const T&); // constexpr in C++20140template<class T> complex<T> operator+(const T&, const complex<T>&); // constexpr in C++20141template<class T> complex<T> operator-(const complex<T>&, const complex<T>&); // constexpr in C++20142template<class T> complex<T> operator-(const complex<T>&, const T&); // constexpr in C++20143template<class T> complex<T> operator-(const T&, const complex<T>&); // constexpr in C++20144template<class T> complex<T> operator*(const complex<T>&, const complex<T>&); // constexpr in C++20145template<class T> complex<T> operator*(const complex<T>&, const T&); // constexpr in C++20146template<class T> complex<T> operator*(const T&, const complex<T>&); // constexpr in C++20147template<class T> complex<T> operator/(const complex<T>&, const complex<T>&); // constexpr in C++20148template<class T> complex<T> operator/(const complex<T>&, const T&); // constexpr in C++20149template<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++20150template<class T> complex<T> operator+(const complex<T>&); // constexpr in C++20151template<class T> complex<T> operator-(const complex<T>&); // constexpr in C++20152template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14153template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14154template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14155template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14156template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14157template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14158 159template<class T, class charT, class traits>160 basic_istream<charT, traits>&161 operator>>(basic_istream<charT, traits>&, complex<T>&);162template<class T, class charT, class traits>163 basic_ostream<charT, traits>&164 operator<<(basic_ostream<charT, traits>&, const complex<T>&);165 166// 26.3.7 values:167 168template<class T> T real(const complex<T>&); // constexpr in C++14169 long double real(long double); // constexpr in C++14170 double real(double); // constexpr in C++14171template<Integral T> double real(T); // constexpr in C++14172 float real(float); // constexpr in C++14173 174template<class T> T imag(const complex<T>&); // constexpr in C++14175 long double imag(long double); // constexpr in C++14176 double imag(double); // constexpr in C++14177template<Integral T> double imag(T); // constexpr in C++14178 float imag(float); // constexpr in C++14179 180template<class T> T abs(const complex<T>&);181 182template<class T> T arg(const complex<T>&);183 long double arg(long double);184 double arg(double);185template<Integral T> double arg(T);186 float arg(float);187 188template<class T> T norm(const complex<T>&); // constexpr in C++20189 long double norm(long double); // constexpr in C++20190 double norm(double); // constexpr in C++20191template<Integral T> double norm(T); // constexpr in C++20192 float norm(float); // constexpr in C++20193 194template<class T> complex<T> conj(const complex<T>&); // constexpr in C++20195 complex<long double> conj(long double); // constexpr in C++20196 complex<double> conj(double); // constexpr in C++20197template<Integral T> complex<double> conj(T); // constexpr in C++20198 complex<float> conj(float); // constexpr in C++20199 200template<class T> complex<T> proj(const complex<T>&);201 complex<long double> proj(long double);202 complex<double> proj(double);203template<Integral T> complex<double> proj(T);204 complex<float> proj(float);205 206template<class T> complex<T> polar(const T&, const T& = T());207 208// 26.3.8 transcendentals:209template<class T> complex<T> acos(const complex<T>&);210template<class T> complex<T> asin(const complex<T>&);211template<class T> complex<T> atan(const complex<T>&);212template<class T> complex<T> acosh(const complex<T>&);213template<class T> complex<T> asinh(const complex<T>&);214template<class T> complex<T> atanh(const complex<T>&);215template<class T> complex<T> cos (const complex<T>&);216template<class T> complex<T> cosh (const complex<T>&);217template<class T> complex<T> exp (const complex<T>&);218template<class T> complex<T> log (const complex<T>&);219template<class T> complex<T> log10(const complex<T>&);220 221template<class T> complex<T> pow(const complex<T>&, const T&);222template<class T> complex<T> pow(const complex<T>&, const complex<T>&);223template<class T> complex<T> pow(const T&, const complex<T>&);224 225template<class T> complex<T> sin (const complex<T>&);226template<class T> complex<T> sinh (const complex<T>&);227template<class T> complex<T> sqrt (const complex<T>&);228template<class T> complex<T> tan (const complex<T>&);229template<class T> complex<T> tanh (const complex<T>&);230 231} // std232 233*/234 235#ifndef __cuda_std__236#include <__config>237#include <stdexcept>238#endif // __cuda_std__239 240#include "__assert" // all public C++ headers provide the assertion handler241#include "__type_traits/enable_if.h"242#include "__type_traits/is_arithmetic.h"243#include "__type_traits/is_floating_point.h"244#include "__type_traits/is_integral.h"245#include "__type_traits/is_same.h"246#include "__type_traits/promote.h"247#include "climits"248#include "cmath"249#include "cstdint"250#include "type_traits"251#include "version"252 253#if !defined(_LIBCUDACXX_HAS_NO_LOCALIZATION) \254 && !defined(_LIBCUDACXX_COMPILER_NVRTC)255#include <sstream> // for std::basic_ostringstream256#endif // !_LIBCUDACXX_HAS_NO_LOCALIZATION && !_LIBCUDACXX_COMPILER_NVRTC257 258// Compatability helpers for thrust to convert between `std::complex` and `cuda::std::complex`259#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)260#include <complex>261 262#define _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__c) reinterpret_cast<const _Up (&)[2]>(__c)[0]263#define _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__c) reinterpret_cast<const _Up (&)[2]>(__c)[1]264#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)265 266#ifndef __cuda_std__267#include <__pragma_push>268#endif // __cuda_std__269 270#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)271# pragma GCC system_header272#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)273# pragma clang system_header274#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)275# pragma system_header276#endif // no system header277 278# if _LIBCUDACXX_CUDA_ABI_VERSION > 3279# define _LIBCUDACXX_COMPLEX_ALIGNAS(V) _ALIGNAS(V)280# else281# define _LIBCUDACXX_COMPLEX_ALIGNAS(V)282# endif283 284#ifdef LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_OPERATIONS285# ifndef LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_MULTIPLICATION286# define LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_MULTIPLICATION287# endif // LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_MULTIPLICATION288# ifndef LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_DIVISION289# define LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_DIVISION290# endif // LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_DIVISION291#endif // LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_OPERATIONS292 293_LIBCUDACXX_BEGIN_NAMESPACE_STD294 295template<class _Tp> class _LIBCUDACXX_TEMPLATE_VIS _LIBCUDACXX_COMPLEX_ALIGNAS(2*sizeof(_Tp)) complex;296 297template<class _Tp> _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11_COMPLEX298complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);299 300template<class _Tp> _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11_COMPLEX301complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);302 303template<class _Tp>304class _LIBCUDACXX_TEMPLATE_VIS _LIBCUDACXX_COMPLEX_ALIGNAS(2*sizeof(_Tp)) complex305{306public:307 typedef _Tp value_type;308private:309 value_type __re_;310 value_type __im_;311public:312 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11313 complex(const value_type& __re = value_type(), const value_type& __im = value_type())314 : __re_(__re), __im_(__im) {}315 template<class _Xp> _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11316 complex(const complex<_Xp>& __c)317 : __re_(__c.real()), __im_(__c.imag()) {}318 319#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)320 template <class _Up>321 _LIBCUDACXX_INLINE_VISIBILITY322 complex(const ::std::complex<_Up>& __other)323 : __re_(_LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other)), __im_(_LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other))324 {}325 326 template <class _Up>327 _LIBCUDACXX_INLINE_VISIBILITY328 complex& operator=(const ::std::complex<_Up>& __other) {329 __re_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other);330 __im_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other);331 return *this;332 }333 334 _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11335 operator ::std::complex<_Tp>() const { return { __re_, __im_ }; }336#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)337 338 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}339 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}340 341 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void real(value_type __re) {__re_ = __re;}342 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void imag(value_type __im) {__im_ = __im;}343 344#if defined(__cuda_std__)345 // Those additional volatile overloads are meant to help with reductions in thrust346 _LIBCUDACXX_INLINE_VISIBILITY value_type real() const volatile {return __re_;}347 _LIBCUDACXX_INLINE_VISIBILITY value_type imag() const volatile {return __im_;}348 349 _LIBCUDACXX_INLINE_VISIBILITY void real(value_type __re) volatile {__re_ = __re;}350 _LIBCUDACXX_INLINE_VISIBILITY void imag(value_type __im) volatile {__im_ = __im;}351#endif // defined(__cuda_std__)352 353 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11354 complex& operator= (const value_type& __re) {__re_ = __re; __im_ = value_type(); return *this;}355 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11356 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}357 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11358 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}359 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11360 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}361 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11362 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}363 364 template<class _Xp>365 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator= (const complex<_Xp>& __c)366 {367 __re_ = __c.real();368 __im_ = __c.imag();369 return *this;370 }371 template<class _Xp>372 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator+=(const complex<_Xp>& __c)373 {374 __re_ += __c.real();375 __im_ += __c.imag();376 return *this;377 }378 template<class _Xp>379 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator-=(const complex<_Xp>& __c)380 {381 __re_ -= __c.real();382 __im_ -= __c.imag();383 return *this;384 }385 template<class _Xp>386 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator*=(const complex<_Xp>& __c)387 {388 *this = *this * complex(__c.real(), __c.imag());389 return *this;390 }391 template<class _Xp>392 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator/=(const complex<_Xp>& __c)393 {394 *this = *this / complex(__c.real(), __c.imag());395 return *this;396 }397};398 399template<> class complex<double>;400#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE401template<> class complex<long double>;402#endif // _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE403 404template<>405class _LIBCUDACXX_TEMPLATE_VIS _LIBCUDACXX_COMPLEX_ALIGNAS(2*sizeof(float)) complex<float>406{407 float __re_;408 float __im_;409public:410 typedef float value_type;411 412 _LIBCUDACXX_INLINE_VISIBILITY constexpr complex(float __re = 0.0f, float __im = 0.0f)413 : __re_(__re), __im_(__im) {}414 _LIBCUDACXX_INLINE_VISIBILITY415 explicit constexpr complex(const complex<double>& __c);416#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE417 _LIBCUDACXX_INLINE_VISIBILITY418 explicit constexpr complex(const complex<long double>& __c);419#endif // _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE420 421#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)422 template <class _Up>423 _LIBCUDACXX_INLINE_VISIBILITY424 complex(const ::std::complex<_Up>& __other)425 : __re_(_LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other)), __im_(_LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other))426 {}427 428 template <class _Up>429 _LIBCUDACXX_INLINE_VISIBILITY430 complex& operator=(const ::std::complex<_Up>& __other) {431 __re_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other);432 __im_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other);433 return *this;434 }435 436 _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11437 operator ::std::complex<float>() const { return { __re_, __im_ }; }438#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)439 440 _LIBCUDACXX_INLINE_VISIBILITY constexpr float real() const {return __re_;}441 _LIBCUDACXX_INLINE_VISIBILITY constexpr float imag() const {return __im_;}442 443 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void real(value_type __re) {__re_ = __re;}444 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void imag(value_type __im) {__im_ = __im;}445 446#if defined(__cuda_std__)447 // Those additional volatile overloads are meant to help with reductions in thrust448 _LIBCUDACXX_INLINE_VISIBILITY float real() const volatile {return __re_;}449 _LIBCUDACXX_INLINE_VISIBILITY float imag() const volatile {return __im_;}450 451 _LIBCUDACXX_INLINE_VISIBILITY void real(value_type __re) volatile {__re_ = __re;}452 _LIBCUDACXX_INLINE_VISIBILITY void imag(value_type __im) volatile {__im_ = __im;}453#endif // defined(__cuda_std__)454 455 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11456 complex& operator= (float __re) { __re_ = __re; __im_ = value_type(); return *this;}457 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11458 complex& operator+=(float __re) {__re_ += __re; return *this;}459 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11460 complex& operator-=(float __re) {__re_ -= __re; return *this;}461 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11462 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}463 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11464 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}465 466 template<class _Xp>467 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator= (const complex<_Xp>& __c)468 {469 __re_ = __c.real();470 __im_ = __c.imag();471 return *this;472 }473 template<class _Xp>474 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator+=(const complex<_Xp>& __c)475 {476 __re_ += __c.real();477 __im_ += __c.imag();478 return *this;479 }480 template<class _Xp>481 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator-=(const complex<_Xp>& __c)482 {483 __re_ -= __c.real();484 __im_ -= __c.imag();485 return *this;486 }487 template<class _Xp>488 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator*=(const complex<_Xp>& __c)489 {490 *this = *this * complex(__c.real(), __c.imag());491 return *this;492 }493 template<class _Xp>494 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator/=(const complex<_Xp>& __c)495 {496 *this = *this / complex(__c.real(), __c.imag());497 return *this;498 }499};500 501template<>502class _LIBCUDACXX_TEMPLATE_VIS _LIBCUDACXX_COMPLEX_ALIGNAS(2*sizeof(double)) complex<double>503{504 double __re_;505 double __im_;506public:507 typedef double value_type;508 509 _LIBCUDACXX_INLINE_VISIBILITY constexpr complex(double __re = 0.0, double __im = 0.0)510 : __re_(__re), __im_(__im) {}511 _LIBCUDACXX_INLINE_VISIBILITY512 constexpr complex(const complex<float>& __c);513 514#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE515 _LIBCUDACXX_INLINE_VISIBILITY516 explicit constexpr complex(const complex<long double>& __c);517#endif //_LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE518 519#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)520 template <class _Up>521 _LIBCUDACXX_INLINE_VISIBILITY522 complex(const ::std::complex<_Up>& __other)523 : __re_(_LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other)), __im_(_LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other))524 {}525 526 template <class _Up>527 _LIBCUDACXX_INLINE_VISIBILITY528 complex& operator=(const ::std::complex<_Up>& __other) {529 __re_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other);530 __im_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other);531 return *this;532 }533 534 _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11535 operator ::std::complex<double>() const { return { __re_, __im_ }; }536#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)537 538 _LIBCUDACXX_INLINE_VISIBILITY constexpr double real() const {return __re_;}539 _LIBCUDACXX_INLINE_VISIBILITY constexpr double imag() const {return __im_;}540 541 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void real(value_type __re) {__re_ = __re;}542 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void imag(value_type __im) {__im_ = __im;}543 544#if defined(__cuda_std__)545 // Those additional volatile overloads are meant to help with reductions in thrust546 _LIBCUDACXX_INLINE_VISIBILITY double real() const volatile {return __re_;}547 _LIBCUDACXX_INLINE_VISIBILITY double imag() const volatile {return __im_;}548 549 _LIBCUDACXX_INLINE_VISIBILITY void real(value_type __re) volatile {__re_ = __re;}550 _LIBCUDACXX_INLINE_VISIBILITY void imag(value_type __im) volatile {__im_ = __im;}551#endif // defined(__cuda_std__)552 553 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11554 complex& operator= (double __re) {__re_ = __re; __im_ = value_type(); return *this;}555 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11556 complex& operator+=(double __re) {__re_ += __re; return *this;}557 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11558 complex& operator-=(double __re) {__re_ -= __re; return *this;}559 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11560 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}561 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11562 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}563 564 template<class _Xp>565 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator= (const complex<_Xp>& __c)566 {567 __re_ = __c.real();568 __im_ = __c.imag();569 return *this;570 }571 template<class _Xp>572 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator+=(const complex<_Xp>& __c)573 {574 __re_ += __c.real();575 __im_ += __c.imag();576 return *this;577 }578 template<class _Xp>579 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator-=(const complex<_Xp>& __c)580 {581 __re_ -= __c.real();582 __im_ -= __c.imag();583 return *this;584 }585 template<class _Xp>586 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator*=(const complex<_Xp>& __c)587 {588 *this = *this * complex(__c.real(), __c.imag());589 return *this;590 }591 template<class _Xp>592 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator/=(const complex<_Xp>& __c)593 {594 *this = *this / complex(__c.real(), __c.imag());595 return *this;596 }597};598 599#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE600template<>601class _LIBCUDACXX_TEMPLATE_VIS _LIBCUDACXX_COMPLEX_ALIGNAS(2*sizeof(long double)) complex<long double>602{603 long double __re_;604 long double __im_;605public:606 typedef long double value_type;607 608 _LIBCUDACXX_INLINE_VISIBILITY constexpr complex(long double __re = 0.0L, long double __im = 0.0L)609 : __re_(__re), __im_(__im) {}610 _LIBCUDACXX_INLINE_VISIBILITY611 constexpr complex(const complex<float>& __c);612 _LIBCUDACXX_INLINE_VISIBILITY613 constexpr complex(const complex<double>& __c);614 615#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)616 template <class _Up>617 _LIBCUDACXX_INLINE_VISIBILITY618 complex(const ::std::complex<_Up>& __other)619 : __re_(_LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other)), __im_(_LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other))620 {}621 622 template <class _Up>623 _LIBCUDACXX_INLINE_VISIBILITY624 complex& operator=(const ::std::complex<_Up>& __other) {625 __re_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__other);626 __im_ = _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__other);627 return *this;628 }629 630 _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11631 operator ::std::complex<long double>() const { return { __re_, __im_ }; }632#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)633 634 _LIBCUDACXX_INLINE_VISIBILITY constexpr long double real() const {return __re_;}635 _LIBCUDACXX_INLINE_VISIBILITY constexpr long double imag() const {return __im_;}636 637 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void real(value_type __re) {__re_ = __re;}638 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 void imag(value_type __im) {__im_ = __im;}639 640#if defined(__cuda_std__)641 // Those additional volatile overloads are meant to help with reductions in thrust642 _LIBCUDACXX_INLINE_VISIBILITY long double real() const volatile {return __re_;}643 _LIBCUDACXX_INLINE_VISIBILITY long double imag() const volatile {return __im_;}644 645 _LIBCUDACXX_INLINE_VISIBILITY void real(value_type __re) volatile {__re_ = __re;}646 _LIBCUDACXX_INLINE_VISIBILITY void imag(value_type __im) volatile {__im_ = __im;}647#endif // defined(__cuda_std__)648 649 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11650 complex& operator= (long double __re) {__re_ = __re; __im_ = value_type(); return *this;}651 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11652 complex& operator+=(long double __re) {__re_ += __re; return *this;}653 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11654 complex& operator-=(long double __re) {__re_ -= __re; return *this;}655 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11656 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}657 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11658 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}659 660 template<class _Xp>661 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator= (const complex<_Xp>& __c)662 {663 __re_ = __c.real();664 __im_ = __c.imag();665 return *this;666 }667 template<class _Xp>668 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator+=(const complex<_Xp>& __c)669 {670 __re_ += __c.real();671 __im_ += __c.imag();672 return *this;673 }674 template<class _Xp>675 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator-=(const complex<_Xp>& __c)676 {677 __re_ -= __c.real();678 __im_ -= __c.imag();679 return *this;680 }681 template<class _Xp>682 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator*=(const complex<_Xp>& __c)683 {684 *this = *this * complex(__c.real(), __c.imag());685 return *this;686 }687 template<class _Xp>688 _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 complex& operator/=(const complex<_Xp>& __c)689 {690 *this = *this / complex(__c.real(), __c.imag());691 return *this;692 }693};694#endif // _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE695 696#if defined(_LIBCUDACXX_USE_PRAGMA_MSVC_WARNING)697 // MSVC complains about narrowing conversions on these copy constructors regardless if they are used698 #pragma warning(push)699 #pragma warning(disable : 4244)700#endif701 702inline constexpr703complex<float>::complex(const complex<double>& __c)704 : __re_(__c.real()), __im_(__c.imag()) {}705 706inline constexpr707complex<double>::complex(const complex<float>& __c)708 : __re_(__c.real()), __im_(__c.imag()) {}709 710#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE711inline constexpr712complex<float>::complex(const complex<long double>& __c)713 : __re_(__c.real()), __im_(__c.imag()) {}714 715inline constexpr716complex<double>::complex(const complex<long double>& __c)717 : __re_(__c.real()), __im_(__c.imag()) {}718 719inline constexpr720complex<long double>::complex(const complex<float>& __c)721 : __re_(__c.real()), __im_(__c.imag()) {}722 723inline constexpr724complex<long double>::complex(const complex<double>& __c)725 : __re_(__c.real()), __im_(__c.imag()) {}726#endif // _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE727 728#if defined(_LIBCUDACXX_USE_PRAGMA_MSVC_WARNING)729 #pragma warning(pop)730#endif731 732// 26.3.6 operators:733 734template<class _Tp>735inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11736complex<_Tp>737operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)738{739 complex<_Tp> __t(__x);740 __t += __y;741 return __t;742}743 744template<class _Tp>745inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11746complex<_Tp>747operator+(const complex<_Tp>& __x, const _Tp& __y)748{749 complex<_Tp> __t(__x);750 __t += __y;751 return __t;752}753 754template<class _Tp>755inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11756complex<_Tp>757operator+(const _Tp& __x, const complex<_Tp>& __y)758{759 complex<_Tp> __t(__y);760 __t += __x;761 return __t;762}763 764template<class _Tp>765inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11766complex<_Tp>767operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)768{769 complex<_Tp> __t(__x);770 __t -= __y;771 return __t;772}773 774template<class _Tp>775inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11776complex<_Tp>777operator-(const complex<_Tp>& __x, const _Tp& __y)778{779 complex<_Tp> __t(__x);780 __t -= __y;781 return __t;782}783 784template<class _Tp>785inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11786complex<_Tp>787operator-(const _Tp& __x, const complex<_Tp>& __y)788{789 complex<_Tp> __t(-__y);790 __t += __x;791 return __t;792}793 794template<class _Tp>795inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11_COMPLEX796complex<_Tp>797operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)798{799 _Tp __a = __z.real();800 _Tp __b = __z.imag();801 _Tp __c = __w.real();802 _Tp __d = __w.imag();803 804#if _LIBCUDACXX_STD_VER > 11 && defined(_LIBCUDACXX_IS_CONSTANT_EVALUATED)805 // Avoid floating point operations that are invalid during constant evaluation806 if (__libcpp_is_constant_evaluated()) {807 bool __z_zero = __a == _Tp(0) && __b == _Tp(0);808 bool __w_zero = __c == _Tp(0) && __d == _Tp(0);809 bool __z_inf = _CUDA_VSTD::__constexpr_isinf(__a) || _CUDA_VSTD::__constexpr_isinf(__b);810 bool __w_inf = _CUDA_VSTD::__constexpr_isinf(__c) || _CUDA_VSTD::__constexpr_isinf(__d);811 bool __z_nan = !__z_inf && (812 (_CUDA_VSTD::__constexpr_isnan(__a) && _CUDA_VSTD::__constexpr_isnan(__b))813 || (_CUDA_VSTD::__constexpr_isnan(__a) && __b == _Tp(0))814 || (__a == _Tp(0) && _CUDA_VSTD::__constexpr_isnan(__b))815 );816 bool __w_nan = !__w_inf && (817 (_CUDA_VSTD::__constexpr_isnan(__c) && _CUDA_VSTD::__constexpr_isnan(__d))818 || (_CUDA_VSTD::__constexpr_isnan(__c) && __d == _Tp(0))819 || (__c == _Tp(0) && _CUDA_VSTD::__constexpr_isnan(__d))820 );821 if (__z_nan || __w_nan) {822 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));823 }824 if (__z_inf || __w_inf) {825 if (__z_zero || __w_zero) {826 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));827 }828 return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));829 }830 bool __z_nonzero_nan = !__z_inf && !__z_nan && (_CUDA_VSTD::__constexpr_isnan(__a) || _CUDA_VSTD::__constexpr_isnan(__b));831 bool __w_nonzero_nan = !__w_inf && !__w_nan && (_CUDA_VSTD::__constexpr_isnan(__c) || _CUDA_VSTD::__constexpr_isnan(__d));832 if (__z_nonzero_nan || __w_nonzero_nan) {833 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));834 }835 }836#endif // _LIBCUDACXX_STD_VER > 11 && defined(_LIBCUDACXX_IS_CONSTANT_EVALUATED)837 838 _Tp __ac = __a * __c;839 _Tp __bd = __b * __d;840 _Tp __ad = __a * __d;841 _Tp __bc = __b * __c;842 _Tp __x = __ac - __bd;843 _Tp __y = __ad + __bc;844#ifndef LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_MULTIPLICATION845 if (_CUDA_VSTD::__constexpr_isnan(__x) && _CUDA_VSTD::__constexpr_isnan(__y))846 {847 bool __recalc = false;848 if (_CUDA_VSTD::__constexpr_isinf(__a) || _CUDA_VSTD::__constexpr_isinf(__b))849 {850 __a = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);851 __b = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);852 if (_CUDA_VSTD::__constexpr_isnan(__c))853 __c = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __c);854 if (_CUDA_VSTD::__constexpr_isnan(__d))855 __d = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __d);856 __recalc = true;857 }858 if (_CUDA_VSTD::__constexpr_isinf(__c) || _CUDA_VSTD::__constexpr_isinf(__d))859 {860 __c = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);861 __d = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);862 if (_CUDA_VSTD::__constexpr_isnan(__a))863 __a = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __a);864 if (_CUDA_VSTD::__constexpr_isnan(__b))865 __b = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __b);866 __recalc = true;867 }868 if (!__recalc && (_CUDA_VSTD::__constexpr_isinf(__ac) || _CUDA_VSTD::__constexpr_isinf(__bd) ||869 _CUDA_VSTD::__constexpr_isinf(__ad) || _CUDA_VSTD::__constexpr_isinf(__bc)))870 {871 if (_CUDA_VSTD::__constexpr_isnan(__a))872 __a = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __a);873 if (_CUDA_VSTD::__constexpr_isnan(__b))874 __b = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __b);875 if (_CUDA_VSTD::__constexpr_isnan(__c))876 __c = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __c);877 if (_CUDA_VSTD::__constexpr_isnan(__d))878 __d = _CUDA_VSTD::__constexpr_copysign(_Tp(0), __d);879 __recalc = true;880 }881 if (__recalc)882 {883 __x = _Tp(INFINITY) * (__a * __c - __b * __d);884 __y = _Tp(INFINITY) * (__a * __d + __b * __c);885 }886 }887#endif // LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_MULTIPLICATION888 return complex<_Tp>(__x, __y);889}890 891template<class _Tp>892inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11893complex<_Tp>894operator*(const complex<_Tp>& __x, const _Tp& __y)895{896 complex<_Tp> __t(__x);897 __t *= __y;898 return __t;899}900 901template<class _Tp>902inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11903complex<_Tp>904operator*(const _Tp& __x, const complex<_Tp>& __y)905{906 complex<_Tp> __t(__y);907 __t *= __x;908 return __t;909}910 911template<class _Tp>912inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11_COMPLEX913complex<_Tp>914operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)915{916 int __ilogbw = 0;917 _Tp __a = __z.real();918 _Tp __b = __z.imag();919 _Tp __c = __w.real();920 _Tp __d = __w.imag();921 _Tp __logbw = _CUDA_VSTD::__constexpr_logb(_CUDA_VSTD::__constexpr_fmax(_CUDA_VSTD::__constexpr_fabs(__c), _CUDA_VSTD::__constexpr_fabs(__d)));922 if (_CUDA_VSTD::__constexpr_isfinite(__logbw))923 {924 __ilogbw = static_cast<int>(__logbw);925 __c = _CUDA_VSTD::__constexpr_scalbn(__c, -__ilogbw);926 __d = _CUDA_VSTD::__constexpr_scalbn(__d, -__ilogbw);927 }928 929#if _LIBCUDACXX_STD_VER > 11 && defined(_LIBCUDACXX_IS_CONSTANT_EVALUATED)930 // Avoid floating point operations that are invalid during constant evaluation931 if (__libcpp_is_constant_evaluated()) {932 bool __z_zero = __a == _Tp(0) && __b == _Tp(0);933 bool __w_zero = __c == _Tp(0) && __d == _Tp(0);934 bool __z_inf = _CUDA_VSTD::__constexpr_isinf(__a) || _CUDA_VSTD::__constexpr_isinf(__b);935 bool __w_inf = _CUDA_VSTD::__constexpr_isinf(__c) || _CUDA_VSTD::__constexpr_isinf(__d);936 bool __z_nan = !__z_inf && (937 (_CUDA_VSTD::__constexpr_isnan(__a) && _CUDA_VSTD::__constexpr_isnan(__b))938 || (_CUDA_VSTD::__constexpr_isnan(__a) && __b == _Tp(0))939 || (__a == _Tp(0) && _CUDA_VSTD::__constexpr_isnan(__b))940 );941 bool __w_nan = !__w_inf && (942 (_CUDA_VSTD::__constexpr_isnan(__c) && _CUDA_VSTD::__constexpr_isnan(__d))943 || (_CUDA_VSTD::__constexpr_isnan(__c) && __d == _Tp(0))944 || (__c == _Tp(0) && _CUDA_VSTD::__constexpr_isnan(__d))945 );946 if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) {947 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));948 }949 bool __z_nonzero_nan = !__z_inf && !__z_nan && (_CUDA_VSTD::__constexpr_isnan(__a) || _CUDA_VSTD::__constexpr_isnan(__b));950 bool __w_nonzero_nan = !__w_inf && !__w_nan && (_CUDA_VSTD::__constexpr_isnan(__c) || _CUDA_VSTD::__constexpr_isnan(__d));951 if (__z_nonzero_nan || __w_nonzero_nan) {952 if (__w_zero) {953 return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));954 }955 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));956 }957 if (__w_inf) {958 return complex<_Tp>(_Tp(0), _Tp(0));959 }960 if (__z_inf) {961 return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));962 }963 if (__w_zero) {964 if (__z_zero) {965 return complex<_Tp>(_Tp(numeric_limits<_Tp>::quiet_NaN()), _Tp(0));966 }967 return complex<_Tp>(_Tp(numeric_limits<_Tp>::infinity()), _Tp(numeric_limits<_Tp>::infinity()));968 }969 }970#endif // _LIBCUDACXX_STD_VER > 11 && defined(_LIBCUDACXX_IS_CONSTANT_EVALUATED)971 972 _Tp __denom = __c * __c + __d * __d;973 _Tp __x = _CUDA_VSTD::__constexpr_scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);974 _Tp __y = _CUDA_VSTD::__constexpr_scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);975#ifndef LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_DIVISION976 if (_CUDA_VSTD::__constexpr_isnan(__x) && _CUDA_VSTD::__constexpr_isnan(__y))977 {978 if ((__denom == _Tp(0)) && (!_CUDA_VSTD::__constexpr_isnan(__a) || !_CUDA_VSTD::__constexpr_isnan(__b)))979 {980 __x = _CUDA_VSTD::__constexpr_copysign(_Tp(INFINITY), __c) * __a;981 __y = _CUDA_VSTD::__constexpr_copysign(_Tp(INFINITY), __c) * __b;982 } else if ((_CUDA_VSTD::__constexpr_isinf(__a) || _CUDA_VSTD::__constexpr_isinf(__b)) && _CUDA_VSTD::__constexpr_isfinite(__c) &&983 _CUDA_VSTD::__constexpr_isfinite(__d)) {984 __a = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__a) ? _Tp(1) : _Tp(0), __a);985 __b = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__b) ? _Tp(1) : _Tp(0), __b);986 __x = _Tp(INFINITY) * (__a * __c + __b * __d);987 __y = _Tp(INFINITY) * (__b * __c - __a * __d);988 } else if (_CUDA_VSTD::__constexpr_isinf(__logbw) && __logbw > _Tp(0) && _CUDA_VSTD::__constexpr_isfinite(__a) &&989 _CUDA_VSTD::__constexpr_isfinite(__b)) {990 __c = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__c) ? _Tp(1) : _Tp(0), __c);991 __d = _CUDA_VSTD::__constexpr_copysign(_CUDA_VSTD::__constexpr_isinf(__d) ? _Tp(1) : _Tp(0), __d);992 __x = _Tp(0) * (__a * __c + __b * __d);993 __y = _Tp(0) * (__b * __c - __a * __d);994 }995 }996#endif // LIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_DIVISION997 return complex<_Tp>(__x, __y);998}999 1000template<class _Tp>1001inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111002complex<_Tp>1003operator/(const complex<_Tp>& __x, const _Tp& __y)1004{1005 return complex<_Tp>(__x.real() / __y, __x.imag() / __y);1006}1007 1008template<class _Tp>1009inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111010complex<_Tp>1011operator/(const _Tp& __x, const complex<_Tp>& __y)1012{1013 complex<_Tp> __t(__x);1014 __t /= __y;1015 return __t;1016}1017 1018template<class _Tp>1019inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111020complex<_Tp>1021operator+(const complex<_Tp>& __x)1022{1023 return __x;1024}1025 1026template<class _Tp>1027inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111028complex<_Tp>1029operator-(const complex<_Tp>& __x)1030{1031 return complex<_Tp>(-__x.real(), -__x.imag());1032}1033 1034template<class _Tp>1035inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111036bool1037operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)1038{1039 return __x.real() == __y.real() && __x.imag() == __y.imag();1040}1041 1042template<class _Tp>1043inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111044bool1045operator==(const complex<_Tp>& __x, const _Tp& __y)1046{1047 return __x.real() == __y && __x.imag() == 0;1048}1049 1050template<class _Tp>1051inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111052bool1053operator==(const _Tp& __x, const complex<_Tp>& __y)1054{1055 return __x == __y.real() && 0 == __y.imag();1056}1057 1058#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)1059template <class _Tp, class _Up>1060inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111061bool1062operator==(const complex<_Tp>& __x, const ::std::complex<_Up>& __y) {1063 return __x.real() == _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__y)1064 && __x.imag() == _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__y);1065}1066 1067template <class _Tp, class _Up>1068inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111069bool1070operator==(const ::std::complex<_Up>& __x, const complex<_Tp>& __y) {1071 return __y.real() == _LIBCUDACXX_ACCESS_STD_COMPLEX_REAL(__x)1072 && __y.imag() == _LIBCUDACXX_ACCESS_STD_COMPLEX_IMAG(__x);1073}1074#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)1075 1076template<class _Tp>1077inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111078bool1079operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)1080{1081 return !(__x == __y);1082}1083 1084template<class _Tp>1085inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111086bool1087operator!=(const complex<_Tp>& __x, const _Tp& __y)1088{1089 return !(__x == __y);1090}1091 1092template<class _Tp>1093inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111094bool1095operator!=(const _Tp& __x, const complex<_Tp>& __y)1096{1097 return !(__x == __y);1098}1099 1100#if defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)1101template <class _Tp, class _Up>1102inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111103bool1104operator!=(const complex<_Tp>& __x, const ::std::complex<_Up>& __y) {1105 return !(__x == __y);1106}1107 1108template <class _Tp, class _Up>1109inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111110bool1111operator!=(const ::std::complex<_Up>& __x, const complex<_Tp>& __y) {1112 return !(__x == __y);1113}1114#endif // defined(__cuda_std__) && !defined(_LIBCUDACXX_COMPILER_NVRTC)1115 1116// 26.3.7 values:1117 1118template <class _Tp, bool = is_integral<_Tp>::value,1119 bool = is_floating_point<_Tp>::value1120 >1121struct __libcpp_complex_overload_traits {};1122 1123// Integral Types1124template <class _Tp>1125struct __libcpp_complex_overload_traits<_Tp, true, false>1126{1127 typedef double _ValueType;1128 typedef complex<double> _ComplexType;1129};1130 1131// Floating point types1132template <class _Tp>1133struct __libcpp_complex_overload_traits<_Tp, false, true>1134{1135 typedef _Tp _ValueType;1136 typedef complex<_Tp> _ComplexType;1137};1138 1139// real1140 1141template<class _Tp>1142inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111143_Tp1144real(const complex<_Tp>& __c)1145{1146 return __c.real();1147}1148 1149template <class _Tp>1150inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111151typename __libcpp_complex_overload_traits<_Tp>::_ValueType1152real(_Tp __re)1153{1154 return __re;1155}1156 1157// imag1158 1159template<class _Tp>1160inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111161_Tp1162imag(const complex<_Tp>& __c)1163{1164 return __c.imag();1165}1166 1167template <class _Tp>1168inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX111169typename __libcpp_complex_overload_traits<_Tp>::_ValueType1170imag(_Tp)1171{1172 return 0;1173}1174 1175// abs1176 1177template<class _Tp>1178inline _LIBCUDACXX_INLINE_VISIBILITY1179_Tp1180abs(const complex<_Tp>& __c)1181{1182 return _CUDA_VSTD::hypot(__c.real(), __c.imag());1183}1184 1185// arg1186 1187template<class _Tp>1188inline _LIBCUDACXX_INLINE_VISIBILITY1189_Tp1190arg(const complex<_Tp>& __c)1191{1192 return _CUDA_VSTD::atan2(__c.imag(), __c.real());1193}1194 1195#ifdef _LIBCUDACXX_HAS_COMPLEX_LONG_DOUBLE1196template <class _Tp>1197inline _LIBCUDACXX_INLINE_VISIBILITY1198__enable_if_t<1199 is_same<_Tp, long double>::value,1200 long double