diff --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv --- a/libcxx/docs/Cxx2aStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv @@ -5,7 +5,7 @@ "`P0020R6 `__","LWG","Floating Point Atomic","Albuquerque","","" "`P0053R7 `__","LWG","C++ Synchronized Buffered Ostream","Albuquerque","","" "`P0202R3 `__","LWG","Add constexpr modifiers to functions in and Headers","Albuquerque","|Complete|","12.0" -"`P0415R1 `__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|In Progress|","7.0" +"`P0415R1 `__","LWG","Constexpr for ``std::complex``\ ","Albuquerque","|Complete|","13.0" "`P0439R0 `__","LWG","Make ``std::memory_order``\ a scoped enumeration","Albuquerque","|Complete|","" "`P0457R2 `__","LWG","String Prefix and Suffix Checking","Albuquerque","|Complete|","6.0" "`P0550R2 `__","LWG","Transformation Trait ``remove_cvref``\ ","Albuquerque","|Complete|","6.0" diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -202,7 +202,7 @@ ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_algorithms`` ``201806L`` ------------------------------------------------- ----------------- - ``__cpp_lib_constexpr_complex`` *unimplemented* + ``__cpp_lib_constexpr_complex`` ``201711L`` ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_dynamic_alloc`` ``201907L`` ------------------------------------------------- ----------------- diff --git a/libcxx/include/complex b/libcxx/include/complex --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -29,21 +29,21 @@ T real() const; // constexpr in C++14 T imag() const; // constexpr in C++14 - void real(T); - void imag(T); - - complex& operator= (const T&); - complex& operator+=(const T&); - complex& operator-=(const T&); - complex& operator*=(const T&); - complex& operator/=(const T&); - - complex& operator=(const complex&); - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + void real(T); // constexpr in C++20 + void imag(T); // constexpr in C++20 + + complex& operator= (const T&); // constexpr in C++20 + complex& operator+=(const T&); // constexpr in C++20 + complex& operator-=(const T&); // constexpr in C++20 + complex& operator*=(const T&); // constexpr in C++20 + complex& operator/=(const T&); // constexpr in C++20 + + complex& operator=(const complex&); // constexpr in C++20 + template complex& operator= (const complex&); // constexpr in C++20 + template complex& operator+=(const complex&); // constexpr in C++20 + template complex& operator-=(const complex&); // constexpr in C++20 + template complex& operator*=(const complex&); // constexpr in C++20 + template complex& operator/=(const complex&); // constexpr in C++20 }; template<> @@ -57,22 +57,22 @@ explicit constexpr complex(const complex&); constexpr float real() const; - void real(float); + void real(float); // constexpr in C++20 constexpr float imag() const; - void imag(float); - - complex& operator= (float); - complex& operator+=(float); - complex& operator-=(float); - complex& operator*=(float); - complex& operator/=(float); - - complex& operator=(const complex&); - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + void imag(float); // constexpr in C++20 + + complex& operator= (float); // constexpr in C++20 + complex& operator+=(float); // constexpr in C++20 + complex& operator-=(float); // constexpr in C++20 + complex& operator*=(float); // constexpr in C++20 + complex& operator/=(float); // constexpr in C++20 + + complex& operator=(const complex&); // constexpr in C++20 + template complex& operator= (const complex&); // constexpr in C++20 + template complex& operator+=(const complex&); // constexpr in C++20 + template complex& operator-=(const complex&); // constexpr in C++20 + template complex& operator*=(const complex&); // constexpr in C++20 + template complex& operator/=(const complex&); // constexpr in C++20 }; template<> @@ -86,22 +86,22 @@ explicit constexpr complex(const complex&); constexpr double real() const; - void real(double); + void real(double); // constexpr in C++20 constexpr double imag() const; - void imag(double); - - complex& operator= (double); - complex& operator+=(double); - complex& operator-=(double); - complex& operator*=(double); - complex& operator/=(double); - complex& operator=(const complex&); - - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + void imag(double); // constexpr in C++20 + + complex& operator= (double); // constexpr in C++20 + complex& operator+=(double); // constexpr in C++20 + complex& operator-=(double); // constexpr in C++20 + complex& operator*=(double); // constexpr in C++20 + complex& operator/=(double); // constexpr in C++20 + complex& operator=(const complex&); // constexpr in C++20 + + template complex& operator= (const complex&); // constexpr in C++20 + template complex& operator+=(const complex&); // constexpr in C++20 + template complex& operator-=(const complex&); // constexpr in C++20 + template complex& operator*=(const complex&); // constexpr in C++20 + template complex& operator/=(const complex&); // constexpr in C++20 }; template<> @@ -115,39 +115,39 @@ constexpr complex(const complex&); constexpr long double real() const; - void real(long double); + void real(long double); // constexpr in C++20 constexpr long double imag() const; - void imag(long double); - - complex& operator=(const complex&); - complex& operator= (long double); - complex& operator+=(long double); - complex& operator-=(long double); - complex& operator*=(long double); - complex& operator/=(long double); - - template complex& operator= (const complex&); - template complex& operator+=(const complex&); - template complex& operator-=(const complex&); - template complex& operator*=(const complex&); - template complex& operator/=(const complex&); + void imag(long double); // constexpr in C++20 + + complex& operator=(const complex&); // constexpr in C++20 + complex& operator= (long double); // constexpr in C++20 + complex& operator+=(long double); // constexpr in C++20 + complex& operator-=(long double); // constexpr in C++20 + complex& operator*=(long double); // constexpr in C++20 + complex& operator/=(long double); // constexpr in C++20 + + template complex& operator= (const complex&); // constexpr in C++20 + template complex& operator+=(const complex&); // constexpr in C++20 + template complex& operator-=(const complex&); // constexpr in C++20 + template complex& operator*=(const complex&); // constexpr in C++20 + template complex& operator/=(const complex&); // constexpr in C++20 }; // 26.3.6 operators: -template complex operator+(const complex&, const complex&); -template complex operator+(const complex&, const T&); -template complex operator+(const T&, const complex&); -template complex operator-(const complex&, const complex&); -template complex operator-(const complex&, const T&); -template complex operator-(const T&, const complex&); -template complex operator*(const complex&, const complex&); -template complex operator*(const complex&, const T&); -template complex operator*(const T&, const complex&); -template complex operator/(const complex&, const complex&); -template complex operator/(const complex&, const T&); -template complex operator/(const T&, const complex&); -template complex operator+(const complex&); -template complex operator-(const complex&); +template complex operator+(const complex&, const complex&); // constexpr in C++20 +template complex operator+(const complex&, const T&); // constexpr in C++20 +template complex operator+(const T&, const complex&); // constexpr in C++20 +template complex operator-(const complex&, const complex&); // constexpr in C++20 +template complex operator-(const complex&, const T&); // constexpr in C++20 +template complex operator-(const T&, const complex&); // constexpr in C++20 +template complex operator*(const complex&, const complex&); // constexpr in C++20 +template complex operator*(const complex&, const T&); // constexpr in C++20 +template complex operator*(const T&, const complex&); // constexpr in C++20 +template complex operator/(const complex&, const complex&); // constexpr in C++20 +template complex operator/(const complex&, const T&); // constexpr in C++20 +template complex operator/(const T&, const complex&); // constexpr in C++20 +template complex operator+(const complex&); // constexpr in C++20 +template complex operator-(const complex&); // constexpr in C++20 template bool operator==(const complex&, const complex&); // constexpr in C++14 template bool operator==(const complex&, const T&); // constexpr in C++14 template bool operator==(const T&, const complex&); // constexpr in C++14 @@ -184,17 +184,17 @@ template double arg(T); float arg(float); -template T norm(const complex&); - long double norm(long double); - double norm(double); -template double norm(T); - float norm(float); +template T norm(const complex&); // constexpr in C++20 + long double norm(long double); // constexpr in C++20 + double norm(double); // constexpr in C++20 +template double norm(T); // constexpr in C++20 + float norm(float); // constexpr in C++20 -template complex conj(const complex&); - complex conj(long double); - complex conj(double); -template complex conj(T); - complex conj(float); +template complex conj(const complex&); // constexpr in C++20 + complex conj(long double); // constexpr in C++20 + complex conj(double); // constexpr in C++20 +template complex conj(T); // constexpr in C++20 + complex conj(float); // constexpr in C++20 template complex proj(const complex&); complex proj(long double); @@ -234,6 +234,8 @@ #include <__config> #include #include +// TODO: Should we use FLT_RADIX from or __FLT_RADIX__ from or numeric_limits::radix from ? +#include #include #include #include @@ -250,8 +252,8 @@ template class _LIBCPP_TEMPLATE_VIS complex; -template complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); -template complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); +template _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w); +template _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y); template class _LIBCPP_TEMPLATE_VIS complex @@ -272,40 +274,40 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;} - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;} - _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (const value_type& __re) {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(const value_type& __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} - template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (const complex<_Xp>& __c) { __re_ = __c.real(); __im_ = __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(const complex<_Xp>& __c) { __re_ += __c.real(); __im_ += __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(const complex<_Xp>& __c) { __re_ -= __c.real(); __im_ -= __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(const complex<_Xp>& __c) { *this = *this * complex(__c.real(), __c.imag()); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(const complex<_Xp>& __c) { *this = *this / complex(__c.real(), __c.imag()); return *this; @@ -333,40 +335,40 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;} - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;} - _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (float __re) {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(float __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(float __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;} - template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (const complex<_Xp>& __c) { __re_ = __c.real(); __im_ = __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(const complex<_Xp>& __c) { __re_ += __c.real(); __im_ += __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(const complex<_Xp>& __c) { __re_ -= __c.real(); __im_ -= __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(const complex<_Xp>& __c) { *this = *this * complex(__c.real(), __c.imag()); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(const complex<_Xp>& __c) { *this = *this / complex(__c.real(), __c.imag()); return *this; @@ -391,40 +393,40 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;} - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;} - _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (double __re) {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;} - template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (const complex<_Xp>& __c) { __re_ = __c.real(); __im_ = __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(const complex<_Xp>& __c) { __re_ += __c.real(); __im_ += __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(const complex<_Xp>& __c) { __re_ -= __c.real(); __im_ -= __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(const complex<_Xp>& __c) { *this = *this * complex(__c.real(), __c.imag()); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(const complex<_Xp>& __c) { *this = *this / complex(__c.real(), __c.imag()); return *this; @@ -449,40 +451,40 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;} - _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;} - _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void real(value_type __re) {__re_ = __re;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void imag(value_type __im) {__im_ = __im;} - _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re) + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (long double __re) {__re_ = __re; __im_ = value_type(); return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} - _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(long double __re) {__re_ += __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(long double __re) {__re_ -= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;} - template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator= (const complex<_Xp>& __c) { __re_ = __c.real(); __im_ = __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator+=(const complex<_Xp>& __c) { __re_ += __c.real(); __im_ += __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator-=(const complex<_Xp>& __c) { __re_ -= __c.real(); __im_ -= __c.imag(); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator*=(const complex<_Xp>& __c) { *this = *this * complex(__c.real(), __c.imag()); return *this; } - template _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c) + template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex& operator/=(const complex<_Xp>& __c) { *this = *this / complex(__c.real(), __c.imag()); return *this; @@ -522,7 +524,7 @@ // 26.3.6 operators: template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) { @@ -532,7 +534,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const complex<_Tp>& __x, const _Tp& __y) { @@ -542,7 +544,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const _Tp& __x, const complex<_Tp>& __y) { @@ -552,7 +554,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) { @@ -562,7 +564,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const complex<_Tp>& __x, const _Tp& __y) { @@ -572,7 +574,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const _Tp& __x, const complex<_Tp>& __y) { @@ -581,7 +583,35 @@ return __t; } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 float +__copysign_constexpr(float __lcpp_x, float __lcpp_y) { +#if _LIBCPP_STD_VER > 17 + return __builtin_copysignf(__lcpp_x, __lcpp_y); +#else + return copysign(__lcpp_x, __lcpp_y); +#endif // _LIBCPP_STD_VER > 17 +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 double +__copysign_constexpr(double __lcpp_x, double __lcpp_y) { +#if _LIBCPP_STD_VER > 17 + return __builtin_copysign(__lcpp_x, __lcpp_y); +#else + return copysign(__lcpp_x, __lcpp_y); +#endif // _LIBCPP_STD_VER > 17 +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 long double +__copysign_constexpr(long double __lcpp_x, long double __lcpp_y) { +#if _LIBCPP_STD_VER > 17 + return __builtin_copysignl(__lcpp_x, __lcpp_y); +#else + return copysign(__lcpp_x, __lcpp_y); +#endif // _LIBCPP_STD_VER > 17 +} + template +_LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) { @@ -589,6 +619,38 @@ _Tp __b = __z.imag(); _Tp __c = __w.real(); _Tp __d = __w.imag(); +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + bool __z_zero = __a == _Tp(0) && __b == _Tp(0); + bool __w_zero = __c == _Tp(0) && __d == _Tp(0); + bool __z_inf = __libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b); + bool __w_inf = __libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d); + bool __z_nan = !__z_inf && ( + (__libcpp_isnan_or_builtin(__a) && __libcpp_isnan_or_builtin(__b)) + || (__libcpp_isnan_or_builtin(__a) && __b == _Tp(0)) + || (__a == _Tp(0) && __libcpp_isnan_or_builtin(__b)) + ); + bool __w_nan = !__w_inf && ( + (__libcpp_isnan_or_builtin(__c) && __libcpp_isnan_or_builtin(__d)) + || (__libcpp_isnan_or_builtin(__c) && __d == _Tp(0)) + || (__c == _Tp(0) && __libcpp_isnan_or_builtin(__d)) + ); + if (__z_nan || __w_nan) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + if (__z_inf || __w_inf) { + if (__z_zero || __w_zero) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + bool __z_nonzero_nan = !__z_inf && !__z_nan && (__libcpp_isnan_or_builtin(__a) || __libcpp_isnan_or_builtin(__b)); + bool __w_nonzero_nan = !__w_inf && !__w_nan && (__libcpp_isnan_or_builtin(__c) || __libcpp_isnan_or_builtin(__d)); + if (__z_nonzero_nan || __w_nonzero_nan) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + } +#endif // _LIBCPP_STD_VER > 17 _Tp __ac = __a * __c; _Tp __bd = __b * __d; _Tp __ad = __a * __d; @@ -600,36 +662,40 @@ bool __recalc = false; if (__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) { - __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); - if (__libcpp_isnan_or_builtin(__c)) - __c = copysign(_Tp(0), __c); - if (__libcpp_isnan_or_builtin(__d)) - __d = copysign(_Tp(0), __d); - __recalc = true; + __a = __copysign_constexpr( + __libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); + __b = __copysign_constexpr( + __libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); + if (__libcpp_isnan_or_builtin(__c)) + __c = __copysign_constexpr(_Tp(0), __c); + if (__libcpp_isnan_or_builtin(__d)) + __d = __copysign_constexpr(_Tp(0), __d); + __recalc = true; } - if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) - { - __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); - if (__libcpp_isnan_or_builtin(__a)) - __a = copysign(_Tp(0), __a); - if (__libcpp_isnan_or_builtin(__b)) - __b = copysign(_Tp(0), __b); - __recalc = true; + if (__libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d)) { + __c = __copysign_constexpr( + __libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); + __d = __copysign_constexpr( + __libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); + if (__libcpp_isnan_or_builtin(__a)) + __a = __copysign_constexpr(_Tp(0), __a); + if (__libcpp_isnan_or_builtin(__b)) + __b = __copysign_constexpr(_Tp(0), __b); + __recalc = true; } - if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || __libcpp_isinf_or_builtin(__bd) || - __libcpp_isinf_or_builtin(__ad) || __libcpp_isinf_or_builtin(__bc))) - { - if (__libcpp_isnan_or_builtin(__a)) - __a = copysign(_Tp(0), __a); - if (__libcpp_isnan_or_builtin(__b)) - __b = copysign(_Tp(0), __b); - if (__libcpp_isnan_or_builtin(__c)) - __c = copysign(_Tp(0), __c); - if (__libcpp_isnan_or_builtin(__d)) - __d = copysign(_Tp(0), __d); - __recalc = true; + if (!__recalc && (__libcpp_isinf_or_builtin(__ac) || + __libcpp_isinf_or_builtin(__bd) || + __libcpp_isinf_or_builtin(__ad) || + __libcpp_isinf_or_builtin(__bc))) { + if (__libcpp_isnan_or_builtin(__a)) + __a = __copysign_constexpr(_Tp(0), __a); + if (__libcpp_isnan_or_builtin(__b)) + __b = __copysign_constexpr(_Tp(0), __b); + if (__libcpp_isnan_or_builtin(__c)) + __c = __copysign_constexpr(_Tp(0), __c); + if (__libcpp_isnan_or_builtin(__d)) + __d = __copysign_constexpr(_Tp(0), __d); + __recalc = true; } if (__recalc) { @@ -641,7 +707,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __x, const _Tp& __y) { @@ -651,7 +717,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const _Tp& __x, const complex<_Tp>& __y) { @@ -660,7 +726,103 @@ return __t; } +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp +__fmax_constexpr(_Tp __lcpp_x, _Tp __lcpp_y) _NOEXCEPT { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + // Treat NaNs as smaller. + if (__libcpp_isnan_or_builtin(__lcpp_x)) + return __lcpp_y; + if (__libcpp_isnan_or_builtin(__lcpp_y)) + return __lcpp_x; + return __lcpp_x < __lcpp_y ? __lcpp_y : __lcpp_x; + } else +#endif // _LIBCPP_STD_VER > 17 + return fmax(__lcpp_x, __lcpp_y); +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp +__fabs_constexpr(_Tp __lcpp_x) _NOEXCEPT { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + return (__lcpp_x < _Tp{}) ? -__lcpp_x : __lcpp_x; + } else +#endif // _LIBCPP_STD_VER > 17 + return fabs(__lcpp_x); +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp __logb_constexpr(_Tp __lcpp_x) { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + if (__lcpp_x == _Tp(0)) { + // raise FE_DIVBYZERO + return -_Tp(INFINITY); + } + + if (__libcpp_isinf_or_builtin(__lcpp_x)) + return _Tp(INFINITY); + + if (__libcpp_isnan_or_builtin(__lcpp_x)) + return _Tp(NAN); + + __lcpp_x = __fabs_constexpr(__lcpp_x); + unsigned long long __exp = 0; + while (__lcpp_x >= __FLT_RADIX__) { + __lcpp_x /= __FLT_RADIX__; + __exp += 1; + } + return _Tp(__exp); + } else +#endif // _LIBCPP_STD_VER > 17 + return logb(__lcpp_x); +} + +template +_LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp __scalbn_constexpr(_Tp __lcpp_x, int __lcpp_exp) { +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + if (__lcpp_x == _Tp(0)) + return __lcpp_x; + + if (__libcpp_isinf_or_builtin(__lcpp_x)) + return __lcpp_x; + + if (__lcpp_exp == _Tp(0)) + return __lcpp_x; + + if (__libcpp_isnan_or_builtin(__lcpp_x)) + return _Tp(NAN); + + _Tp __mult{1}; + if (__lcpp_exp > 0) { + __mult = __FLT_RADIX__; + --__lcpp_exp; + } else { + ++__lcpp_exp; + __lcpp_exp = -__lcpp_exp; + __mult /= __FLT_RADIX__; + } + + while (__lcpp_exp > 0) { + if (!(__lcpp_exp & 1)) { + __mult *= __mult; + __lcpp_exp >>= 1; + } else { + __lcpp_x *= __mult; + --__lcpp_exp; + } + } + return __lcpp_x; + } else +#endif // _LIBCPP_STD_VER > 17 + return scalbn(__lcpp_x, __lcpp_exp); +} + template +_LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) { @@ -669,34 +831,76 @@ _Tp __b = __z.imag(); _Tp __c = __w.real(); _Tp __d = __w.imag(); - _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); + _Tp __logbw = __logb_constexpr( + __fmax_constexpr(__fabs_constexpr(__c), __fabs_constexpr(__d))); if (__libcpp_isfinite_or_builtin(__logbw)) { __ilogbw = static_cast(__logbw); - __c = scalbn(__c, -__ilogbw); - __d = scalbn(__d, -__ilogbw); + __c = __scalbn_constexpr(__c, -__ilogbw); + __d = __scalbn_constexpr(__d, -__ilogbw); + } +#if _LIBCPP_STD_VER > 17 + if (__libcpp_is_constant_evaluated()) { + bool __z_zero = __a == _Tp(0) && __b == _Tp(0); + bool __w_zero = __c == _Tp(0) && __d == _Tp(0); + bool __z_inf = __libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b); + bool __w_inf = __libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d); + bool __z_nan = !__z_inf && ( + (__libcpp_isnan_or_builtin(__a) && __libcpp_isnan_or_builtin(__b)) + || (__libcpp_isnan_or_builtin(__a) && __b == _Tp(0)) + || (__a == _Tp(0) && __libcpp_isnan_or_builtin(__b)) + ); + bool __w_nan = !__w_inf && ( + (__libcpp_isnan_or_builtin(__c) && __libcpp_isnan_or_builtin(__d)) + || (__libcpp_isnan_or_builtin(__c) && __d == _Tp(0)) + || (__c == _Tp(0) && __libcpp_isnan_or_builtin(__d)) + ); + if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + bool __z_nonzero_nan = !__z_inf && !__z_nan && (__libcpp_isnan_or_builtin(__a) || __libcpp_isnan_or_builtin(__b)); + bool __w_nonzero_nan = !__w_inf && !__w_nan && (__libcpp_isnan_or_builtin(__c) || __libcpp_isnan_or_builtin(__d)); + if (__z_nonzero_nan || __w_nonzero_nan) { + if (__w_zero) { + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + if (__w_inf) { + return complex<_Tp>(_Tp(0), _Tp(0)); + } + if (__z_inf) { + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + if (__w_zero) { + if (__z_zero) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } } +#endif // _LIBCPP_STD_VER > 17 _Tp __denom = __c * __c + __d * __d; - _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); - _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); + _Tp __x = __scalbn_constexpr((__a * __c + __b * __d) / __denom, -__ilogbw); + _Tp __y = __scalbn_constexpr((__b * __c - __a * __d) / __denom, -__ilogbw); if (__libcpp_isnan_or_builtin(__x) && __libcpp_isnan_or_builtin(__y)) { if ((__denom == _Tp(0)) && (!__libcpp_isnan_or_builtin(__a) || !__libcpp_isnan_or_builtin(__b))) { - __x = copysign(_Tp(INFINITY), __c) * __a; - __y = copysign(_Tp(INFINITY), __c) * __b; + __x = __copysign_constexpr(_Tp(INFINITY), __c) * __a; + __y = __copysign_constexpr(_Tp(INFINITY), __c) * __b; } else if ((__libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b)) && __libcpp_isfinite_or_builtin(__c) && __libcpp_isfinite_or_builtin(__d)) { - __a = copysign(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); + __a = __copysign_constexpr(__libcpp_isinf_or_builtin(__a) ? _Tp(1) : _Tp(0), __a); + __b = __copysign_constexpr(__libcpp_isinf_or_builtin(__b) ? _Tp(1) : _Tp(0), __b); __x = _Tp(INFINITY) * (__a * __c + __b * __d); __y = _Tp(INFINITY) * (__b * __c - __a * __d); } else if (__libcpp_isinf_or_builtin(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite_or_builtin(__a) && __libcpp_isfinite_or_builtin(__b)) { - __c = copysign(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); + __c = __copysign_constexpr(__libcpp_isinf_or_builtin(__c) ? _Tp(1) : _Tp(0), __c); + __d = __copysign_constexpr(__libcpp_isinf_or_builtin(__d) ? _Tp(1) : _Tp(0), __d); __x = _Tp(0) * (__a * __c + __b * __d); __y = _Tp(0) * (__b * __c - __a * __d); } @@ -705,7 +909,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const complex<_Tp>& __x, const _Tp& __y) { @@ -713,7 +917,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const _Tp& __x, const complex<_Tp>& __y) { @@ -723,7 +927,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const complex<_Tp>& __x) { @@ -731,7 +935,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const complex<_Tp>& __x) { @@ -902,7 +1106,7 @@ // norm template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp norm(const complex<_Tp>& __c) { @@ -914,7 +1118,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename __libcpp_complex_overload_traits<_Tp>::_ValueType norm(_Tp __re) { @@ -925,7 +1129,7 @@ // conj template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> conj(const complex<_Tp>& __c) { @@ -933,7 +1137,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename __libcpp_complex_overload_traits<_Tp>::_ComplexType conj(_Tp __re) { diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -297,7 +297,7 @@ # endif // # define __cpp_lib_concepts 202002L # define __cpp_lib_constexpr_algorithms 201806L -// # define __cpp_lib_constexpr_complex 201711L +# define __cpp_lib_constexpr_complex 201711L # define __cpp_lib_constexpr_dynamic_alloc 201907L # define __cpp_lib_constexpr_functional 201907L // # define __cpp_lib_constexpr_iterator 201811L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/complex.version.pass.cpp @@ -68,17 +68,11 @@ # error "__cpp_lib_complex_udls should have the value 201309L in c++20" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++20" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++20" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" # endif #elif TEST_STD_VER > 20 @@ -90,17 +84,11 @@ # error "__cpp_lib_complex_udls should have the value 201309L in c++2b" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++2b" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++2b" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++2b" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++2b" # endif #endif // TEST_STD_VER > 20 diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -2402,17 +2402,11 @@ # error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++20" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++20" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" # endif # ifndef __cpp_lib_constexpr_dynamic_alloc @@ -3621,17 +3615,11 @@ # error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++2b" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++2b" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++2b" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++2b" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++2b" # endif # ifndef __cpp_lib_constexpr_dynamic_alloc diff --git a/libcxx/test/std/numerics/complex.number/cases.h b/libcxx/test/std/numerics/complex.number/cases.h --- a/libcxx/test/std/numerics/complex.number/cases.h +++ b/libcxx/test/std/numerics/complex.number/cases.h @@ -16,7 +16,7 @@ #include #include -const std::complex testcases[] = +TEST_CONSTEXPR_CXX20 const std::complex testcases[] = { std::complex( 1.e-6, 1.e-6), std::complex(-1.e-6, 1.e-6), @@ -174,22 +174,23 @@ enum {zero, non_zero, inf, NaN, non_zero_nan}; template +TEST_CONSTEXPR_CXX20 int classify(const std::complex& x) { if (x == std::complex()) return zero; - if (std::isinf(x.real()) || std::isinf(x.imag())) + if (__builtin_isinf(x.real()) || __builtin_isinf(x.imag())) return inf; - if (std::isnan(x.real()) && std::isnan(x.imag())) + if (__builtin_isnan(x.real()) && __builtin_isnan(x.imag())) return NaN; - if (std::isnan(x.real())) + if (__builtin_isnan(x.real())) { if (x.imag() == T(0)) return NaN; return non_zero_nan; } - if (std::isnan(x.imag())) + if (__builtin_isnan(x.imag())) { if (x.real() == T(0)) return NaN; diff --git a/libcxx/test/std/numerics/complex.number/cmplx.over/conj.pass.cpp b/libcxx/test/std/numerics/complex.number/cmplx.over/conj.pass.cpp --- a/libcxx/test/std/numerics/complex.number/cmplx.over/conj.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/cmplx.over/conj.pass.cpp @@ -8,11 +8,11 @@ // -// template complex conj(const complex&); -// complex conj(long double); -// complex conj(double); -// template complex conj(T); -// complex conj(float); +// template complex conj(const complex&); // constexpr in C++20 +// complex conj(long double); // constexpr in C++20 +// complex conj(double); // constexpr in C++20 +// template complex conj(T); // constexpr in C++20 +// complex conj(float); // constexpr in C++20 #include #include @@ -22,37 +22,45 @@ #include "../cases.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(T x, typename std::enable_if::value>::type* = 0) { static_assert((std::is_same >::value), ""); assert(std::conj(x) == conj(std::complex(x, 0))); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test(T x, typename std::enable_if::value>::type* = 0) { static_assert((std::is_same >::value), ""); assert(std::conj(x) == conj(std::complex(x, 0))); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test(T x, typename std::enable_if::value && !std::is_floating_point::value>::type* = 0) { static_assert((std::is_same >::value), ""); assert(std::conj(x) == conj(std::complex(x, 0))); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { test(0); test(1); test(10); + return true; } int main(int, char**) @@ -64,5 +72,14 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp b/libcxx/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp --- a/libcxx/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/cmplx.over/norm.pass.cpp @@ -10,7 +10,7 @@ // template // T -// norm(T x); +// norm(T x); // constexpr in C++20 #include #include @@ -20,28 +20,34 @@ #include "../cases.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(T x, typename std::enable_if::value>::type* = 0) { static_assert((std::is_same::value), ""); assert(std::norm(x) == norm(std::complex(static_cast(x), 0))); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test(T x, typename std::enable_if::value>::type* = 0) { static_assert((std::is_same::value), ""); assert(std::norm(x) == norm(std::complex(x, 0))); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { test(0); test(1); test(10); + return true; } int main(int, char**) @@ -53,5 +59,14 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_complex.pass.cpp @@ -9,7 +9,7 @@ // // complex& operator=(const complex&); -// template complex& operator= (const complex&); +// template complex& operator= (const complex&); // constexpr in C++20 #include #include @@ -17,7 +17,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -31,6 +32,7 @@ c = c3; assert(c.real() == 3.5); assert(c.imag() == -4.5); + return true; } int main(int, char**) @@ -47,5 +49,19 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + + static_assert(test()); + static_assert(test()); + static_assert(test()); + + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator= (const T&); +// complex& operator= (const T&); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -28,6 +29,7 @@ c = -1.5; assert(c.real() == -1.5); assert(c.imag() == 0); + return true; } int main(int, char**) @@ -36,5 +38,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_complex.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator/=(const complex& rhs); +// complex& operator/=(const complex& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c(-4, 7.5); @@ -33,17 +34,17 @@ std::complex c3; c3 = c; - std::complex ic (1,1); + std::complex ic(1, 1); c3 /= ic; - assert(c3.real() == 0.5); + assert(c3.real() == 0.5); assert(c3.imag() == -0.5); c3 = c; - std::complex fc (1,1); + std::complex fc(1, 1); c3 /= fc; - assert(c3.real() == 0.5); + assert(c3.real() == 0.5); assert(c3.imag() == -0.5); - + return true; } int main(int, char**) @@ -52,5 +53,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator/=(const T& rhs); +// complex& operator/=(const T& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c(1); @@ -35,6 +36,7 @@ c /= 0.5; assert(c.real() == -16); assert(c.imag() == 4); + return true; } int main(int, char**) @@ -43,5 +45,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_complex.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator-=(const complex& rhs); +// complex& operator-=(const complex& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -33,16 +34,17 @@ std::complex c3; c3 = c; - std::complex ic (1,1); + std::complex ic(1, 1); c3 -= ic; assert(c3.real() == -4); assert(c3.imag() == -6); c3 = c; - std::complex fc (1,1); + std::complex fc(1, 1); c3 -= fc; assert(c3.real() == -4); assert(c3.imag() == -6); + return true; } int main(int, char**) @@ -51,5 +53,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator-=(const T& rhs); +// complex& operator-=(const T& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -31,6 +32,7 @@ c -= -1.5; assert(c.real() == -1.5); assert(c.imag() == 0); + return true; } int main(int, char**) @@ -39,5 +41,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_complex.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator+=(const complex& rhs); +// complex& operator+=(const complex& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -33,16 +34,17 @@ std::complex c3; c3 = c; - std::complex ic (1,1); + std::complex ic(1, 1); c3 += ic; assert(c3.real() == 4); assert(c3.imag() == 6); c3 = c; - std::complex fc (1,1); + std::complex fc(1, 1); c3 += fc; assert(c3.real() == 4); assert(c3.imag() == 6); + return true; } int main(int, char**) @@ -51,5 +53,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator+=(const T& rhs); +// complex& operator+=(const T& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -31,6 +32,7 @@ c += -1.5; assert(c.real() == 1.5); assert(c.imag() == 0); + return true; } int main(int, char**) @@ -39,5 +41,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_complex.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator*=(const complex& rhs); +// complex& operator*=(const complex& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c(1); @@ -33,16 +34,17 @@ std::complex c3; c3 = c; - std::complex ic (1,1); + std::complex ic(1, 1); c3 *= ic; assert(c3.real() == -11.5); - assert(c3.imag() == 3.5); + assert(c3.imag() == 3.5); c3 = c; - std::complex fc (1,1); + std::complex fc(1, 1); c3 *= fc; assert(c3.real() == -11.5); - assert(c3.imag() == 3.5); + assert(c3.imag() == 3.5); + return true; } int main(int, char**) @@ -51,5 +53,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp @@ -8,7 +8,7 @@ // -// complex& operator*=(const T& rhs); +// complex& operator*=(const T& rhs); // constexpr in C++20 #include #include @@ -16,7 +16,8 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c(1); @@ -35,6 +36,7 @@ c *= 1.5; assert(c.real() == -5.0625); assert(c.imag() == 3); + return true; } int main(int, char**) @@ -43,5 +45,11 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.members/real_imag.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.members/real_imag.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.members/real_imag.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.members/real_imag.pass.cpp @@ -8,8 +8,8 @@ // -// void real(T val); -// void imag(T val); +// void real(T val); // constexpr in C++20 +// void imag(T val); // constexpr in C++20 #include #include @@ -17,6 +17,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -34,7 +35,8 @@ } template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex c; @@ -53,15 +55,21 @@ assert(c.real() == -4.5); assert(c.imag() == -5.5); - test_constexpr (); + test_constexpr(); + return true; } -int main(int, char**) -{ +int main(int, char**) { test(); test(); test(); - test_constexpr (); + test_constexpr(); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.clang.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.clang.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.clang.pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: apple-clang || clang + +// ADDITIONAL_COMPILE_FLAGS: -fconstexpr-steps=4500000 + +#include "complex_divide_complex.pass.hpp" diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.not-clang.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.not-clang.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.not-clang.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: apple-clang +// UNSUPPORTED: clang + +#include "complex_divide_complex.pass.hpp" diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.hpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.hpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.hpp @@ -0,0 +1,172 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// complex +// operator/(const complex& lhs, const complex& rhs); // constexpr in C++20 + +#ifndef COMPLEX_DIVIDE_COMPLEX_PASS_HPP +#define COMPLEX_DIVIDE_COMPLEX_PASS_HPP + +#include +#include + +#include "test_macros.h" +#include "../cases.h" + +template +TEST_CONSTEXPR_CXX20 +bool +test(const std::complex& lhs, const std::complex& rhs, std::complex x) +{ + assert(lhs / rhs == x); + return true; +} + +template +TEST_CONSTEXPR_CXX20 +bool +test() +{ + std::complex lhs(-4.0, 7.5); + std::complex rhs(1.5, 2.5); + std::complex x(1.5, 2.5); + test(lhs, rhs, x); + return true; +} + +TEST_CONSTEXPR_CXX20 +bool +test_edges() +{ + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + for (unsigned j = 0; j < N; ++j) { + std::complex r = testcases[i] / testcases[j]; + switch (classify(testcases[i])) { + case zero: + switch (classify(testcases[j])) { + case zero: + assert(classify(r) == NaN); + break; + case non_zero: + assert(classify(r) == zero); + break; + case inf: + assert(classify(r) == zero); + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + case non_zero: + switch (classify(testcases[j])) { + case zero: + assert(classify(r) == inf); + break; + case non_zero: + assert(classify(r) == non_zero); + break; + case inf: + assert(classify(r) == zero); + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + case inf: + switch (classify(testcases[j])) { + case zero: + assert(classify(r) == inf); + break; + case non_zero: + assert(classify(r) == inf); + break; + case inf: + assert(classify(r) == NaN); + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + case NaN: + switch (classify(testcases[j])) { + case zero: + assert(classify(r) == NaN); + break; + case non_zero: + assert(classify(r) == NaN); + break; + case inf: + assert(classify(r) == NaN); + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + case non_zero_nan: + switch (classify(testcases[j])) { + case zero: + assert(classify(r) == inf); + break; + case non_zero: + assert(classify(r) == NaN); + break; + case inf: + assert(classify(r) == NaN); + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + } + } + } + return true; +} + +int main(int, char**) +{ + test(); + test(); + test(); + test_edges(); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test_edges()); +#endif + + return 0; +} + +#endif // COMPLEX_DIVIDE_COMPLEX_PASS_HPP diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp deleted file mode 100644 --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// - -// template -// complex -// operator/(const complex& lhs, const complex& rhs); - -#include -#include - -#include "test_macros.h" -#include "../cases.h" - -template -void -test(const std::complex& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs / rhs == x); -} - -template -void -test() -{ - std::complex lhs(-4.0, 7.5); - std::complex rhs(1.5, 2.5); - std::complex x(1.5, 2.5); - test(lhs, rhs, x); -} - -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - for (unsigned j = 0; j < N; ++j) - { - std::complex r = testcases[i] / testcases[j]; - switch (classify(testcases[i])) - { - case zero: - switch (classify(testcases[j])) - { - case zero: - assert(classify(r) == NaN); - break; - case non_zero: - assert(classify(r) == zero); - break; - case inf: - assert(classify(r) == zero); - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case non_zero: - switch (classify(testcases[j])) - { - case zero: - assert(classify(r) == inf); - break; - case non_zero: - assert(classify(r) == non_zero); - break; - case inf: - assert(classify(r) == zero); - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case inf: - switch (classify(testcases[j])) - { - case zero: - assert(classify(r) == inf); - break; - case non_zero: - assert(classify(r) == inf); - break; - case inf: - assert(classify(r) == NaN); - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case NaN: - switch (classify(testcases[j])) - { - case zero: - assert(classify(r) == NaN); - break; - case non_zero: - assert(classify(r) == NaN); - break; - case inf: - assert(classify(r) == NaN); - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case non_zero_nan: - switch (classify(testcases[j])) - { - case zero: - assert(classify(r) == inf); - break; - case non_zero: - assert(classify(r) == NaN); - break; - case inf: - assert(classify(r) == NaN); - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - } - } - } -} - -int main(int, char**) -{ - test(); - test(); - test(); - test_edges(); - - return 0; -} diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator/(const complex& lhs, const T& rhs); +// operator/(const complex& lhs, const T& rhs); // constexpr in C++20 #include #include @@ -18,20 +18,24 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const T& rhs, std::complex x) { assert(lhs / rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex lhs(-4.0, 7.5); T rhs(2); - std::complex x(-2, 3.75); + std::complex x(-2, 3.75); test(lhs, rhs, x); + return true; } int main(int, char**) @@ -40,5 +44,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_complex.pass.cpp @@ -18,25 +18,8 @@ #include "test_macros.h" template -void -test_constexpr() -{ -#if TEST_STD_VER > 11 - { - constexpr std::complex lhs(1.5, 2.5); - constexpr std::complex rhs(1.5, -2.5); - static_assert( !(lhs == rhs), ""); - } - { - constexpr std::complex lhs(1.5, 2.5); - constexpr std::complex rhs(1.5, 2.5); - static_assert(lhs == rhs, ""); - } -#endif -} - -template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -49,7 +32,7 @@ std::complex rhs(1.5, 2.5); assert(lhs == rhs); } - test_constexpr (); + return true; } int main(int, char**) @@ -57,7 +40,11 @@ test(); test(); test(); -// test_constexpr (); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_equals_scalar.pass.cpp @@ -18,6 +18,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -46,7 +47,8 @@ } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -71,14 +73,20 @@ } test_constexpr (); - } + return true; +} int main(int, char**) { test(); test(); test(); -// test_constexpr (); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator-(const complex& lhs, const complex& rhs); +// operator-(const complex& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const std::complex& rhs, std::complex x) { assert(lhs - rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,6 +43,7 @@ std::complex x(5.0, -7.0); test(lhs, rhs, x); } + return true; } int main(int, char**) @@ -48,5 +52,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_minus_scalar.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator-(const complex& lhs, const T& rhs); +// operator-(const complex& lhs, const T& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const T& rhs, std::complex x) { assert(lhs - rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,6 +43,7 @@ std::complex x(5.0, -2.5); test(lhs, rhs, x); } + return true; } int main(int, char**) @@ -48,5 +52,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_complex.pass.cpp @@ -18,6 +18,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -35,9 +36,9 @@ #endif } - template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -52,14 +53,20 @@ } test_constexpr (); - } + return true; +} int main(int, char**) { test(); test(); test(); -// test_constexpr (); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_not_equals_scalar.pass.cpp @@ -18,6 +18,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -46,7 +47,8 @@ } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -71,6 +73,7 @@ } test_constexpr (); + return true; } int main(int, char**) @@ -78,7 +81,12 @@ test(); test(); test(); -// test_constexpr (); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator+(const complex& lhs, const complex& rhs); +// operator+(const complex& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const std::complex& rhs, std::complex x) { assert(lhs + rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,6 +43,8 @@ std::complex x(-2.0, 2.0); test(lhs, rhs, x); } + + return true; } int main(int, char**) @@ -48,5 +53,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator+(const complex& lhs, const T& rhs); +// operator+(const complex& lhs, const T& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const T& rhs, std::complex x) { assert(lhs + rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,6 +43,8 @@ std::complex x(-2.0, -2.5); test(lhs, rhs, x); } + + return true; } int main(int, char**) @@ -48,5 +53,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.clang.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.clang.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.clang.pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: apple-clang || clang + +// ADDITIONAL_COMPILE_FLAGS: -fconstexpr-steps=4000000 + +#include "complex_times_complex.pass.hpp" diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.not-clang.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.not-clang.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.not-clang.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: apple-clang +// UNSUPPORTED: clang + +#include "complex_times_complex.pass.hpp" diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.hpp rename from libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp rename to libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.hpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.hpp @@ -10,7 +10,10 @@ // template // complex -// operator*(const complex& lhs, const complex& rhs); +// operator*(const complex& lhs, const complex& rhs); // constexpr in C++20 + +#ifndef COMPLEX_TIMES_COMPLEX_PASS_HPP +#define COMPLEX_TIMES_COMPLEX_PASS_HPP #include #include @@ -19,25 +22,29 @@ #include "../cases.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const std::complex& rhs, std::complex x) { assert(lhs * rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex lhs(1.5, 2.5); std::complex rhs(1.5, 2.5); - std::complex x(-4.0, 7.5); + std::complex x(-4.0, 7.5); test(lhs, rhs, x); + return true; } // test edges -void test_edges() +TEST_CONSTEXPR_CXX20 bool test_edges() { const unsigned N = sizeof(testcases) / sizeof(testcases[0]); for (unsigned i = 0; i < N; ++i) @@ -150,6 +157,7 @@ } } } + return true; } int main(int, char**) @@ -159,5 +167,14 @@ test(); test_edges(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + static_assert(test_edges()); +#endif + return 0; } + +#endif // COMPLEX_TIMES_COMPLEX_PASS_HPP diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator*(const complex& lhs, const T& rhs); +// operator*(const complex& lhs, const T& rhs); // constexpr in C++20 #include #include @@ -18,20 +18,24 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const std::complex& lhs, const T& rhs, std::complex x) { assert(lhs * rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex lhs(1.5, 2.5); T rhs(1.5); - std::complex x(2.25, 3.75); + std::complex x(2.25, 3.75); test(lhs, rhs, x); + return true; } int main(int, char**) @@ -40,5 +44,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator/(const T& lhs, const complex& rhs); +// operator/(const T& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,20 +18,24 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const T& lhs, const std::complex& rhs, std::complex x) { assert(lhs / rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { T lhs(-8.5); std::complex rhs(1.5, 2.5); - std::complex x(-1.5, 2.5); + std::complex x(-1.5, 2.5); test(lhs, rhs, x); + return true; } int main(int, char**) @@ -40,5 +44,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_equals_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_equals_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_equals_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_equals_complex.pass.cpp @@ -18,6 +18,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -46,7 +47,8 @@ } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -71,6 +73,7 @@ } test_constexpr (); + return true; } int main(int, char**) @@ -78,7 +81,12 @@ test(); test(); test(); -// test_constexpr(); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator-(const T& lhs, const complex& rhs); +// operator-(const T& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const T& lhs, const std::complex& rhs, std::complex x) { assert(lhs - rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,13 +43,19 @@ std::complex x(5.0, -4.5); test(lhs, rhs, x); } + return true; } -int main(int, char**) -{ +int main(int, char**) { test(); test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_not_equals_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_not_equals_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_not_equals_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_not_equals_complex.pass.cpp @@ -18,6 +18,7 @@ #include "test_macros.h" template +TEST_CONSTEXPR_CXX20 void test_constexpr() { @@ -46,7 +47,8 @@ } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -71,14 +73,20 @@ } test_constexpr (); - } + return true; +} int main(int, char**) { test(); test(); test(); -// test_constexpr(); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator+(const T& lhs, const complex& rhs); +// operator+(const T& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,14 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test(const T& lhs, const std::complex& rhs, std::complex x) { assert(lhs + rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { { @@ -40,6 +43,7 @@ std::complex x(-2.0, 4.5); test(lhs, rhs, x); } + return true; } int main(int, char**) @@ -48,5 +52,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator*(const T& lhs, const complex& rhs); +// operator*(const T& lhs, const complex& rhs); // constexpr in C++20 #include #include @@ -18,20 +18,22 @@ #include "test_macros.h" template -void -test(const T& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs * rhs == x); +TEST_CONSTEXPR_CXX20 bool test(const T& lhs, const std::complex& rhs, + std::complex x) { + assert(lhs * rhs == x); + return true; } template -void +TEST_CONSTEXPR_CXX20 +bool test() { T lhs(1.5); std::complex rhs(1.5, 2.5); - std::complex x(2.25, 3.75); + std::complex x(2.25, 3.75); test(lhs, rhs, x); + return true; } int main(int, char**) @@ -40,5 +42,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator-(const complex& lhs); +// operator-(const complex& lhs); // constexpr in C++20 #include #include @@ -18,15 +18,17 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { std::complex z(1.5, 2.5); - assert(z.real() == 1.5); - assert(z.imag() == 2.5); + assert(z.real() == T(1.5)); + assert(z.imag() == T(2.5)); std::complex c = -z; - assert(c.real() == -1.5); - assert(c.imag() == -2.5); + assert(c.real() == T(-1.5)); + assert(c.imag() == T(-2.5)); + return true; } int main(int, char**) @@ -35,5 +37,11 @@ test(); test(); +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp --- a/libcxx/test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp @@ -10,7 +10,7 @@ // template // complex -// operator+(const complex&); +// operator+(const complex&); // constexpr in C++20 #include #include @@ -18,22 +18,30 @@ #include "test_macros.h" template -void +TEST_CONSTEXPR_CXX20 +bool test() { - std::complex z(1.5, 2.5); - assert(z.real() == 1.5); - assert(z.imag() == 2.5); - std::complex c = +z; - assert(c.real() == 1.5); - assert(c.imag() == 2.5); + std::complex z(1.5, 2.5); + assert(z.real() == T(1.5)); + assert(z.imag() == T(2.5)); + std::complex c = +z; + assert(c.real() == T(1.5)); + assert(c.imag() == T(2.5)); + return true; } int main(int, char**) { - test(); - test(); - test(); + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); +#endif return 0; } diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -186,7 +186,6 @@ "name": "__cpp_lib_constexpr_complex", "values": { "c++20": 201711 }, "headers": ["complex"], - "unimplemented": True, }, { "name": "__cpp_lib_constexpr_dynamic_alloc", "values": { "c++20": 201907 },