diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -178,6 +178,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_concepts`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_complex`` ``201711L`` + ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_misc`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_swap_algorithms`` *unimplemented* 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); @@ -242,6 +242,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 @@ -254,8 +256,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 @@ -281,9 +283,9 @@ _LIBCPP_INLINE_VISIBILITY 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 _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 complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;} template _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c) @@ -292,13 +294,13 @@ __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(); @@ -337,40 +339,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; @@ -395,40 +397,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; @@ -453,40 +455,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; @@ -526,7 +528,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) { @@ -536,7 +538,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const complex<_Tp>& __x, const _Tp& __y) { @@ -546,7 +548,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const _Tp& __x, const complex<_Tp>& __y) { @@ -556,7 +558,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) { @@ -566,7 +568,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const complex<_Tp>& __x, const _Tp& __y) { @@ -576,7 +578,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const _Tp& __x, const complex<_Tp>& __y) { @@ -586,6 +588,7 @@ } template +_LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) { @@ -645,7 +648,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const complex<_Tp>& __x, const _Tp& __y) { @@ -655,7 +658,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator*(const _Tp& __x, const complex<_Tp>& __y) { @@ -664,7 +667,63 @@ return __t; } +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp +__fmax_constexpr(_Tp __lcpp_x, _Tp __lcpp_y) _NOEXCEPT { + // 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; +} + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp +__fabs_constexpr(_Tp __lcpp_x) _NOEXCEPT { + return (__lcpp_x < _Tp{}) ? -__lcpp_x : __lcpp_x; +} + +template +constexpr _Tp __logb_constexpr(_Tp __lcpp_x) { + __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}; +} + +template +constexpr _Tp __scalbn_constexpr(_Tp __lcpp_x, int __lcpp_exp) { + if (!__lcpp_exp) + return __lcpp_x; + + _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; +} + template +_LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) { @@ -673,16 +732,34 @@ _Tp __b = __z.imag(); _Tp __c = __w.real(); _Tp __d = __w.imag(); - _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); + _Tp __logbw{}; + if (__libcpp_is_constant_evaluated()) { + __logbw = __logb_constexpr( + __fmax_constexpr(__fabs_constexpr(__c), __fabs_constexpr(__d))); + } else { + __logbw = logb(fmax(fabs(__c), fabs(__d))); + } if (__libcpp_isfinite_or_builtin(__logbw)) { __ilogbw = static_cast(__logbw); - __c = scalbn(__c, -__ilogbw); - __d = scalbn(__d, -__ilogbw); + if (__libcpp_is_constant_evaluated()) { + __c = __scalbn_constexpr(__c, -__ilogbw); + __d = __scalbn_constexpr(__d, -__ilogbw); + } else { + __c = scalbn(__c, -__ilogbw); + __d = scalbn(__d, -__ilogbw); + } } _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{}; + _Tp __y{}; + if (__libcpp_is_constant_evaluated()) { + __x = __scalbn_constexpr((__a * __c + __b * __d) / __denom, -__ilogbw); + __y = __scalbn_constexpr((__b * __c - __a * __d) / __denom, -__ilogbw); + } else { + __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); + __y = scalbn((__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))) @@ -709,7 +786,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const complex<_Tp>& __x, const _Tp& __y) { @@ -717,7 +794,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator/(const _Tp& __x, const complex<_Tp>& __y) { @@ -727,7 +804,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator+(const complex<_Tp>& __x) { @@ -735,7 +812,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> operator-(const complex<_Tp>& __x) { @@ -906,7 +983,7 @@ // norm template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp norm(const complex<_Tp>& __c) { @@ -918,7 +995,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename __libcpp_complex_overload_traits<_Tp>::_ValueType norm(_Tp __re) { @@ -929,7 +1006,7 @@ // conj template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 complex<_Tp> conj(const complex<_Tp>& __c) { @@ -937,7 +1014,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 @@ -38,6 +38,7 @@ __cpp_lib_clamp 201603L __cpp_lib_complex_udls 201309L __cpp_lib_concepts 201806L +__cpp_lib_constexpr_complex 201711L __cpp_lib_constexpr_misc 201811L __cpp_lib_constexpr_swap_algorithms 201806L @@ -220,6 +221,7 @@ # define __cpp_lib_char8_t 201811L # endif // # define __cpp_lib_concepts 201806L +# define __cpp_lib_constexpr_complex 201711L // # define __cpp_lib_constexpr_misc 201811L // # define __cpp_lib_constexpr_swap_algorithms 201806L # if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L 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 @@ -13,8 +13,9 @@ // Test the feature test macros defined by -/* Constant Value - __cpp_lib_complex_udls 201309L [C++14] +/* Constant Value + __cpp_lib_complex_udls 201309L [C++14] + __cpp_lib_constexpr_complex 201711L [C++2a] */ #include @@ -26,6 +27,10 @@ # error "__cpp_lib_complex_udls should not be defined before c++14" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + #elif TEST_STD_VER == 14 # ifndef __cpp_lib_complex_udls @@ -35,6 +40,10 @@ # error "__cpp_lib_complex_udls should have the value 201309L in c++14" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + #elif TEST_STD_VER == 17 # ifndef __cpp_lib_complex_udls @@ -44,6 +53,10 @@ # error "__cpp_lib_complex_udls should have the value 201309L in c++17" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + #elif TEST_STD_VER > 17 # ifndef __cpp_lib_complex_udls @@ -53,6 +66,13 @@ # error "__cpp_lib_complex_udls should have the value 201309L in c++2a" # endif +#ifndef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should be defined in c++2a" +#endif +#if __cpp_lib_constexpr_complex != 201711L +#error "__cpp_lib_constexpr_complex should have the value 201711L in c++2a" +#endif + #endif // TEST_STD_VER > 17 int main(int, char**) { return 0; } 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 @@ -33,6 +33,7 @@ __cpp_lib_clamp 201603L [C++17] __cpp_lib_complex_udls 201309L [C++14] __cpp_lib_concepts 201806L [C++2a] + __cpp_lib_constexpr_complex 201711L [C++2a] __cpp_lib_constexpr_misc 201811L [C++2a] __cpp_lib_constexpr_swap_algorithms 201806L [C++2a] __cpp_lib_destroying_delete 201806L [C++2a] @@ -183,6 +184,10 @@ # error "__cpp_lib_concepts should not be defined before c++2a" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + # ifdef __cpp_lib_constexpr_misc # error "__cpp_lib_constexpr_misc should not be defined before c++2a" # endif @@ -531,6 +536,10 @@ # error "__cpp_lib_concepts should not be defined before c++2a" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + # ifdef __cpp_lib_constexpr_misc # error "__cpp_lib_constexpr_misc should not be defined before c++2a" # endif @@ -993,6 +1002,10 @@ # error "__cpp_lib_concepts should not be defined before c++2a" # endif +#ifdef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should not be defined before c++2a" +#endif + # ifdef __cpp_lib_constexpr_misc # error "__cpp_lib_constexpr_misc should not be defined before c++2a" # endif @@ -1662,6 +1675,13 @@ # endif # endif +#ifndef __cpp_lib_constexpr_complex +#error "__cpp_lib_constexpr_complex should be defined in c++2a" +#endif +#if __cpp_lib_constexpr_complex != 201711L +#error "__cpp_lib_constexpr_complex should have the value 201711L in c++2a" +#endif + # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_misc # error "__cpp_lib_constexpr_misc should be defined in c++2a" 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,41 @@ #include "../cases.h" template -void -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))); +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(T x, typename std::enable_if::value>::type* = 0) -{ - static_assert((std::is_same >::value), ""); - assert(std::conj(x) == conj(std::complex(x, 0))); +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(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))); +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() -{ - test(0); - test(1); - test(10); +TEST_CONSTEXPR_CXX20 bool test() { + test(0); + test(1); + test(10); + return true; } int main(int, char**) @@ -64,5 +68,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,27 @@ #include "../cases.h" template -void -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))); +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(T x, typename std::enable_if::value>::type* = 0) -{ - static_assert((std::is_same::value), ""); - assert(std::norm(x) == norm(std::complex(x, 0))); +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() -{ - test(0); - test(1); - test(10); +TEST_CONSTEXPR_CXX20 bool test() { + test(0); + test(1); + test(10); + return true; } int main(int, char**) @@ -53,5 +52,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,20 +17,19 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - assert(c.real() == 0); - assert(c.imag() == 0); - std::complex c2(1.5, 2.5); - c = c2; - assert(c.real() == 1.5); - assert(c.imag() == 2.5); - std::complex c3(3.5, -4.5); - c = c3; - assert(c.real() == 3.5); - assert(c.imag() == -4.5); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + assert(c.real() == 0); + assert(c.imag() == 0); + std::complex c2(1.5, 2.5); + c = c2; + assert(c.real() == 1.5); + assert(c.imag() == 2.5); + std::complex c3(3.5, -4.5); + c = c3; + assert(c.real() == 3.5); + assert(c.imag() == -4.5); + return true; } int main(int, char**) @@ -47,5 +46,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,18 +16,17 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - assert(c.real() == 0); - assert(c.imag() == 0); - c = 1.5; - assert(c.real() == 1.5); - assert(c.imag() == 0); - c = -1.5; - assert(c.real() == -1.5); - assert(c.imag() == 0); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + assert(c.real() == 0); + assert(c.imag() == 0); + c = 1.5; + assert(c.real() == 1.5); + assert(c.imag() == 0); + c = -1.5; + assert(c.real() == -1.5); + assert(c.imag() == 0); + return true; } int main(int, char**) @@ -36,5 +35,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,34 +16,32 @@ #include "test_macros.h" template -void -test() -{ - std::complex c(-4, 7.5); - const std::complex c2(1.5, 2.5); - assert(c.real() == -4); - assert(c.imag() == 7.5); - c /= c2; - assert(c.real() == 1.5); - assert(c.imag() == 2.5); - c /= c2; - assert(c.real() == 1); - assert(c.imag() == 0); - - std::complex c3; - - c3 = c; - std::complex ic (1,1); - c3 /= ic; - assert(c3.real() == 0.5); - assert(c3.imag() == -0.5); - - c3 = c; - std::complex fc (1,1); - c3 /= fc; - assert(c3.real() == 0.5); - assert(c3.imag() == -0.5); - +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c(-4, 7.5); + const std::complex c2(1.5, 2.5); + assert(c.real() == -4); + assert(c.imag() == 7.5); + c /= c2; + assert(c.real() == 1.5); + assert(c.imag() == 2.5); + c /= c2; + assert(c.real() == 1); + assert(c.imag() == 0); + + std::complex c3; + + c3 = c; + std::complex ic(1, 1); + c3 /= ic; + assert(c3.real() == 0.5); + assert(c3.imag() == -0.5); + + c3 = c; + std::complex fc(1, 1); + c3 /= fc; + assert(c3.real() == 0.5); + assert(c3.imag() == -0.5); + return true; } int main(int, char**) @@ -52,5 +50,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,25 +16,24 @@ #include "test_macros.h" template -void -test() -{ - std::complex c(1); - assert(c.real() == 1); - assert(c.imag() == 0); - c /= 0.5; - assert(c.real() == 2); - assert(c.imag() == 0); - c /= 0.5; - assert(c.real() == 4); - assert(c.imag() == 0); - c /= -0.5; - assert(c.real() == -8); - assert(c.imag() == 0); - c.imag(2); - c /= 0.5; - assert(c.real() == -16); - assert(c.imag() == 4); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c(1); + assert(c.real() == 1); + assert(c.imag() == 0); + c /= 0.5; + assert(c.real() == 2); + assert(c.imag() == 0); + c /= 0.5; + assert(c.real() == 4); + assert(c.imag() == 0); + c /= -0.5; + assert(c.real() == -8); + assert(c.imag() == 0); + c.imag(2); + c /= 0.5; + assert(c.real() == -16); + assert(c.imag() == 4); + return true; } int main(int, char**) @@ -43,5 +42,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,33 +16,32 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - const std::complex c2(1.5, 2.5); - assert(c.real() == 0); - assert(c.imag() == 0); - c -= c2; - assert(c.real() == -1.5); - assert(c.imag() == -2.5); - c -= c2; - assert(c.real() == -3); - assert(c.imag() == -5); - - std::complex c3; - - c3 = c; - std::complex ic (1,1); - c3 -= ic; - assert(c3.real() == -4); - assert(c3.imag() == -6); - - c3 = c; - std::complex fc (1,1); - c3 -= fc; - assert(c3.real() == -4); - assert(c3.imag() == -6); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + const std::complex c2(1.5, 2.5); + assert(c.real() == 0); + assert(c.imag() == 0); + c -= c2; + assert(c.real() == -1.5); + assert(c.imag() == -2.5); + c -= c2; + assert(c.real() == -3); + assert(c.imag() == -5); + + std::complex c3; + + c3 = c; + std::complex ic(1, 1); + c3 -= ic; + assert(c3.real() == -4); + assert(c3.imag() == -6); + + c3 = c; + std::complex fc(1, 1); + c3 -= fc; + assert(c3.real() == -4); + assert(c3.imag() == -6); + return true; } int main(int, char**) @@ -51,5 +50,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,21 +16,20 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - assert(c.real() == 0); - assert(c.imag() == 0); - c -= 1.5; - assert(c.real() == -1.5); - assert(c.imag() == 0); - c -= 1.5; - assert(c.real() == -3); - assert(c.imag() == 0); - c -= -1.5; - assert(c.real() == -1.5); - assert(c.imag() == 0); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + assert(c.real() == 0); + assert(c.imag() == 0); + c -= 1.5; + assert(c.real() == -1.5); + assert(c.imag() == 0); + c -= 1.5; + assert(c.real() == -3); + assert(c.imag() == 0); + c -= -1.5; + assert(c.real() == -1.5); + assert(c.imag() == 0); + return true; } int main(int, char**) @@ -39,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/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,33 +16,32 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - const std::complex c2(1.5, 2.5); - assert(c.real() == 0); - assert(c.imag() == 0); - c += c2; - assert(c.real() == 1.5); - assert(c.imag() == 2.5); - c += c2; - assert(c.real() == 3); - assert(c.imag() == 5); - - std::complex c3; - - c3 = c; - std::complex ic (1,1); - c3 += ic; - assert(c3.real() == 4); - assert(c3.imag() == 6); - - c3 = c; - std::complex fc (1,1); - c3 += fc; - assert(c3.real() == 4); - assert(c3.imag() == 6); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + const std::complex c2(1.5, 2.5); + assert(c.real() == 0); + assert(c.imag() == 0); + c += c2; + assert(c.real() == 1.5); + assert(c.imag() == 2.5); + c += c2; + assert(c.real() == 3); + assert(c.imag() == 5); + + std::complex c3; + + c3 = c; + std::complex ic(1, 1); + c3 += ic; + assert(c3.real() == 4); + assert(c3.imag() == 6); + + c3 = c; + std::complex fc(1, 1); + c3 += fc; + assert(c3.real() == 4); + assert(c3.imag() == 6); + return true; } int main(int, char**) @@ -51,5 +50,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,21 +16,20 @@ #include "test_macros.h" template -void -test() -{ - std::complex c; - assert(c.real() == 0); - assert(c.imag() == 0); - c += 1.5; - assert(c.real() == 1.5); - assert(c.imag() == 0); - c += 1.5; - assert(c.real() == 3); - assert(c.imag() == 0); - c += -1.5; - assert(c.real() == 1.5); - assert(c.imag() == 0); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + assert(c.real() == 0); + assert(c.imag() == 0); + c += 1.5; + assert(c.real() == 1.5); + assert(c.imag() == 0); + c += 1.5; + assert(c.real() == 3); + assert(c.imag() == 0); + c += -1.5; + assert(c.real() == 1.5); + assert(c.imag() == 0); + return true; } int main(int, char**) @@ -39,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/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,33 +16,32 @@ #include "test_macros.h" template -void -test() -{ - std::complex c(1); - const std::complex c2(1.5, 2.5); - assert(c.real() == 1); - assert(c.imag() == 0); - c *= c2; - assert(c.real() == 1.5); - assert(c.imag() == 2.5); - c *= c2; - assert(c.real() == -4); - assert(c.imag() == 7.5); - - std::complex c3; - - c3 = c; - std::complex ic (1,1); - c3 *= ic; - assert(c3.real() == -11.5); - assert(c3.imag() == 3.5); - - c3 = c; - std::complex fc (1,1); - c3 *= fc; - assert(c3.real() == -11.5); - assert(c3.imag() == 3.5); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c(1); + const std::complex c2(1.5, 2.5); + assert(c.real() == 1); + assert(c.imag() == 0); + c *= c2; + assert(c.real() == 1.5); + assert(c.imag() == 2.5); + c *= c2; + assert(c.real() == -4); + assert(c.imag() == 7.5); + + std::complex c3; + + c3 = c; + std::complex ic(1, 1); + c3 *= ic; + assert(c3.real() == -11.5); + assert(c3.imag() == 3.5); + + c3 = c; + std::complex fc(1, 1); + c3 *= fc; + assert(c3.real() == -11.5); + assert(c3.imag() == 3.5); + return true; } int main(int, char**) @@ -51,5 +50,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,25 +16,24 @@ #include "test_macros.h" template -void -test() -{ - std::complex c(1); - assert(c.real() == 1); - assert(c.imag() == 0); - c *= 1.5; - assert(c.real() == 1.5); - assert(c.imag() == 0); - c *= 1.5; - assert(c.real() == 2.25); - assert(c.imag() == 0); - c *= -1.5; - assert(c.real() == -3.375); - assert(c.imag() == 0); - c.imag(2); - c *= 1.5; - assert(c.real() == -5.0625); - assert(c.imag() == 3); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c(1); + assert(c.real() == 1); + assert(c.imag() == 0); + c *= 1.5; + assert(c.real() == 1.5); + assert(c.imag() == 0); + c *= 1.5; + assert(c.real() == 2.25); + assert(c.imag() == 0); + c *= -1.5; + assert(c.real() == -3.375); + assert(c.imag() == 0); + c.imag(2); + c *= 1.5; + assert(c.real() == -5.0625); + assert(c.imag() == 3); + return true; } int main(int, char**) @@ -43,5 +42,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,9 +17,7 @@ #include "test_macros.h" template -void -test_constexpr() -{ +TEST_CONSTEXPR_CXX20 void test_constexpr() { #if TEST_STD_VER > 11 constexpr std::complex c1; static_assert(c1.real() == 0, ""); @@ -34,34 +32,38 @@ } template -void -test() -{ - std::complex c; - assert(c.real() == 0); - assert(c.imag() == 0); - c.real(3.5); - assert(c.real() == 3.5); - assert(c.imag() == 0); - c.imag(4.5); - assert(c.real() == 3.5); - assert(c.imag() == 4.5); - c.real(-4.5); - assert(c.real() == -4.5); - assert(c.imag() == 4.5); - c.imag(-5.5); - assert(c.real() == -4.5); - assert(c.imag() == -5.5); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex c; + assert(c.real() == 0); + assert(c.imag() == 0); + c.real(3.5); + assert(c.real() == 3.5); + assert(c.imag() == 0); + c.imag(4.5); + assert(c.real() == 3.5); + assert(c.imag() == 4.5); + c.real(-4.5); + assert(c.real() == -4.5); + assert(c.imag() == 4.5); + c.imag(-5.5); + assert(c.real() == -4.5); + assert(c.imag() == -5.5); - test_constexpr (); + test_constexpr(); + return true; } -int main(int, char**) -{ - test(); - test(); - test(); - test_constexpr (); +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_divide_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp --- 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 @@ -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 @@ -19,135 +19,125 @@ #include "../cases.h" template -void -test(const std::complex& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs / rhs == x); +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() -{ - 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); +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; } -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; - } +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**) @@ -157,5 +147,11 @@ test(); test_edges(); - 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.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,27 +18,31 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const T& rhs, std::complex x) -{ - assert(lhs / rhs == x); +TEST_CONSTEXPR_CXX20 bool test(const std::complex& lhs, const T& rhs, + std::complex x) { + assert(lhs / rhs == x); + return true; } template -void -test() -{ - std::complex lhs(-4.0, 7.5); - T rhs(2); - std::complex x(-2, 3.75); - test(lhs, rhs, x); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex lhs(-4.0, 7.5); + T rhs(2); + std::complex x(-2, 3.75); + test(lhs, rhs, x); + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +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/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 @@ -57,7 +57,7 @@ test(); test(); test(); -// test_constexpr (); + test_constexpr(); - return 0; + 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,35 +18,40 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs - rhs == x); +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() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { std::complex lhs(1.5, 2.5); std::complex rhs(3.5, 4.5); std::complex x(-2.0, -2.0); test(lhs, rhs, x); - } + } { std::complex lhs(1.5, -2.5); std::complex rhs(-3.5, 4.5); std::complex x(5.0, -7.0); test(lhs, rhs, x); } + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,35 +18,40 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const T& rhs, std::complex x) -{ - assert(lhs - rhs == x); +TEST_CONSTEXPR_CXX20 bool test(const std::complex& lhs, const T& rhs, + std::complex x) { + assert(lhs - rhs == x); + return true; } template -void -test() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { std::complex lhs(1.5, 2.5); T rhs(3.5); std::complex x(-2.0, 2.5); test(lhs, rhs, x); - } + } { std::complex lhs(1.5, -2.5); T rhs(-3.5); std::complex x(5.0, -2.5); test(lhs, rhs, x); } + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,35 +18,41 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs + rhs == x); +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() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { std::complex lhs(1.5, 2.5); std::complex rhs(3.5, 4.5); std::complex x(5.0, 7.0); test(lhs, rhs, x); - } + } { std::complex lhs(1.5, -2.5); std::complex rhs(-3.5, 4.5); std::complex x(-2.0, 2.0); test(lhs, rhs, x); } + + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,35 +18,41 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const T& rhs, std::complex x) -{ - assert(lhs + rhs == x); +TEST_CONSTEXPR_CXX20 bool test(const std::complex& lhs, const T& rhs, + std::complex x) { + assert(lhs + rhs == x); + return true; } template -void -test() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { std::complex lhs(1.5, 2.5); T rhs(3.5); std::complex x(5.0, 2.5); test(lhs, rhs, x); - } + } { std::complex lhs(1.5, -2.5); T rhs(-3.5); std::complex x(-2.0, -2.5); test(lhs, rhs, x); } + + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.ops/complex_times_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp --- 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.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 @@ -19,20 +19,19 @@ #include "../cases.h" template -void -test(const std::complex& lhs, const std::complex& rhs, std::complex x) -{ - assert(lhs * rhs == x); +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() -{ - std::complex lhs(1.5, 2.5); - std::complex rhs(1.5, 2.5); - std::complex x(-4.0, 7.5); - test(lhs, rhs, x); +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); + test(lhs, rhs, x); + return true; } // test edges @@ -159,5 +158,12 @@ test(); test_edges(); - return 0; +#if TEST_STD_VER > 17 + 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.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,27 +18,32 @@ #include "test_macros.h" template -void -test(const std::complex& lhs, const T& rhs, std::complex x) -{ - assert(lhs * rhs == x); +TEST_CONSTEXPR_CXX20 bool test(const std::complex& lhs, const T& rhs, + std::complex x) { + assert(lhs * rhs == x); + return true; } template -void -test() -{ - std::complex lhs(1.5, 2.5); - T rhs(1.5); - std::complex x(2.25, 3.75); - test(lhs, rhs, x); +TEST_CONSTEXPR_CXX20 bool test() { + std::complex lhs(1.5, 2.5); + T rhs(1.5); + std::complex x(2.25, 3.75); + test(lhs, rhs, x); + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,27 +18,31 @@ #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() -{ - T lhs(-8.5); - std::complex rhs(1.5, 2.5); - std::complex x(-1.5, 2.5); - test(lhs, rhs, x); +TEST_CONSTEXPR_CXX20 bool test() { + T lhs(-8.5); + std::complex rhs(1.5, 2.5); + std::complex x(-1.5, 2.5); + test(lhs, rhs, x); + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +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_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,35 +18,40 @@ #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() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { T lhs(1.5); std::complex rhs(3.5, 4.5); std::complex x(-2.0, -4.5); test(lhs, rhs, x); - } + } { T lhs(1.5); std::complex rhs(-3.5, 4.5); std::complex x(5.0, -4.5); test(lhs, rhs, x); } + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,35 +18,40 @@ #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() -{ - { +TEST_CONSTEXPR_CXX20 bool test() { + { T lhs(1.5); std::complex rhs(3.5, 4.5); std::complex x(5.0, 4.5); test(lhs, rhs, x); - } + } { T lhs(1.5); std::complex rhs(-3.5, 4.5); std::complex x(-2.0, 4.5); test(lhs, rhs, x); } + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,27 +18,32 @@ #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() -{ - T lhs(1.5); - std::complex rhs(1.5, 2.5); - std::complex x(2.25, 3.75); - test(lhs, rhs, x); +TEST_CONSTEXPR_CXX20 bool test() { + T lhs(1.5); + std::complex rhs(1.5, 2.5); + std::complex x(2.25, 3.75); + test(lhs, rhs, x); + return true; } -int main(int, char**) -{ - test(); - test(); - test(); +int main(int, char**) { + test(); + test(); + test(); + +#if TEST_STD_VER > 17 + 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.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,14 @@ #include "test_macros.h" template -void -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); +TEST_CONSTEXPR_CXX20 bool test() { + 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**) @@ -35,5 +34,13 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + // TODO: warnings + 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,15 +18,14 @@ #include "test_macros.h" template -void -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); +TEST_CONSTEXPR_CXX20 bool test() { + 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**) @@ -35,5 +34,13 @@ test(); test(); - return 0; +#if TEST_STD_VER > 17 + static_assert(test()); + static_assert(test()); + static_assert(test()); + // TODO: warnings + 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 @@ -591,6 +591,12 @@ }, "headers": ["array"], }, + {"name": "__cpp_lib_constexpr_complex", + "values": { + "c++2a": int(201711), + }, + "headers": ["complex"], + }, ]], key=lambda tc: tc["name"]) def get_std_dialects(): diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -60,7 +60,7 @@ P0020R6LWGFloating Point AtomicAlbuquerque P0053R7LWGC++ Synchronized Buffered OstreamAlbuquerque P0202R3LWGAdd constexpr modifiers to functions in <algorithm> and <utility> HeadersAlbuquerqueIn Progress7.0 - P0415R1LWGConstexpr for std::complexAlbuquerqueIn Progress7.0 + P0415R1LWGConstexpr for std::complexAlbuquerqueComplete11.0 P0439R0LWGMake std::memory_order a scoped enumerationAlbuquerqueComplete P0457R2LWGString Prefix and Suffix CheckingAlbuquerqueComplete6.0 P0550R2LWGTransformation Trait remove_cvrefAlbuquerqueComplete6.0