From d6606ce8caa677a52062494a79fa188271937913 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 7 Apr 2023 10:54:34 +0800 Subject: [PATCH 1/7] Test coverage for cv-qualified FP types --- .../P0631R8_numbers_math_constants/test.cpp | 229 +++++++++++------- 1 file changed, 144 insertions(+), 85 deletions(-) diff --git a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp index dfd89fd3b1..1e774907af 100644 --- a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp +++ b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp @@ -1,18 +1,130 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include +#pragma warning(disable : 4197) // '%s': top-level volatile in cast is ignored + #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -template +template [[nodiscard]] constexpr bool test_case(T& actual, const U expected) { - STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v, const U>); return actual == expected; } -// N4835 [math.constants]/2: "a program may partially or explicitly specialize a mathematical constant +enum class modify_cv { + type_identity, + add_const, + add_volatile, + add_cv, +}; + +template +struct apply_modify_cv { + using type = T; +}; + +template +struct apply_modify_cv { + using type = const T; +}; + +template +struct apply_modify_cv { + using type = volatile T; +}; + +template +struct apply_modify_cv { + using type = const volatile T; +}; + +template +using apply_modify_cv_t = typename apply_modify_cv::type; + +template +constexpr bool test_cv_floating_point() { + using F = apply_modify_cv_t; + using D = apply_modify_cv_t; + using L = apply_modify_cv_t; + + assert(test_case(std::numbers::e_v, 0x1.5bf0a8p+1f)); + assert(test_case(std::numbers::e_v, 0x1.5bf0a8b145769p+1)); + assert(test_case(std::numbers::e_v, 0x1.5bf0a8b145769p+1L)); + + assert(test_case(std::numbers::log2e_v, 0x1.715476p+0f)); + assert(test_case(std::numbers::log2e_v, 0x1.71547652b82fep+0)); + assert(test_case(std::numbers::log2e_v, 0x1.71547652b82fep+0L)); + + assert(test_case(std::numbers::log10e_v, 0x1.bcb7b2p-2f)); + assert(test_case(std::numbers::log10e_v, 0x1.bcb7b1526e50ep-2)); + assert(test_case(std::numbers::log10e_v, 0x1.bcb7b1526e50ep-2L)); + + assert(test_case(std::numbers::pi_v, 0x1.921fb6p+1f)); + assert(test_case(std::numbers::pi_v, 0x1.921fb54442d18p+1)); + assert(test_case(std::numbers::pi_v, 0x1.921fb54442d18p+1L)); + + assert(test_case(std::numbers::inv_pi_v, 0x1.45f306p-2f)); + assert(test_case(std::numbers::inv_pi_v, 0x1.45f306dc9c883p-2)); + assert(test_case(std::numbers::inv_pi_v, 0x1.45f306dc9c883p-2L)); + + assert(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd76p-1f)); + assert(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd750429b6dp-1)); + assert(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd750429b6dp-1L)); + + assert(test_case(std::numbers::ln2_v, 0x1.62e430p-1f)); + assert(test_case(std::numbers::ln2_v, 0x1.62e42fefa39efp-1)); + assert(test_case(std::numbers::ln2_v, 0x1.62e42fefa39efp-1L)); + + assert(test_case(std::numbers::ln10_v, 0x1.26bb1cp+1f)); + assert(test_case(std::numbers::ln10_v, 0x1.26bb1bbb55516p+1)); + assert(test_case(std::numbers::ln10_v, 0x1.26bb1bbb55516p+1L)); + + assert(test_case(std::numbers::sqrt2_v, 0x1.6a09e6p+0f)); + assert(test_case(std::numbers::sqrt2_v, 0x1.6a09e667f3bcdp+0)); + assert(test_case(std::numbers::sqrt2_v, 0x1.6a09e667f3bcdp+0L)); + + assert(test_case(std::numbers::sqrt3_v, 0x1.bb67aep+0f)); + assert(test_case(std::numbers::sqrt3_v, 0x1.bb67ae8584caap+0)); + assert(test_case(std::numbers::sqrt3_v, 0x1.bb67ae8584caap+0L)); + + assert(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74p-1f)); + assert(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74590331cp-1)); + assert(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74590331cp-1L)); + + assert(test_case(std::numbers::egamma_v, 0x1.2788d0p-1f)); + assert(test_case(std::numbers::egamma_v, 0x1.2788cfc6fb619p-1)); + assert(test_case(std::numbers::egamma_v, 0x1.2788cfc6fb619p-1L)); + + assert(test_case(std::numbers::phi_v, 0x1.9e377ap+0f)); + assert(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0)); + assert(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0L)); + + return true; +} + +constexpr bool test_double() { + assert(test_case(std::numbers::e /**/, 0x1.5bf0a8b145769p+1)); + assert(test_case(std::numbers::log2e /**/, 0x1.71547652b82fep+0)); + assert(test_case(std::numbers::log10e /**/, 0x1.bcb7b1526e50ep-2)); + assert(test_case(std::numbers::pi /**/, 0x1.921fb54442d18p+1)); + assert(test_case(std::numbers::inv_pi /**/, 0x1.45f306dc9c883p-2)); + assert(test_case(std::numbers::inv_sqrtpi /**/, 0x1.20dd750429b6dp-1)); + assert(test_case(std::numbers::ln2 /**/, 0x1.62e42fefa39efp-1)); + assert(test_case(std::numbers::ln10 /**/, 0x1.26bb1bbb55516p+1)); + assert(test_case(std::numbers::sqrt2 /**/, 0x1.6a09e667f3bcdp+0)); + assert(test_case(std::numbers::sqrt3 /**/, 0x1.bb67ae8584caap+0)); + assert(test_case(std::numbers::inv_sqrt3 /**/, 0x1.279a74590331cp-1)); + assert(test_case(std::numbers::egamma /**/, 0x1.2788cfc6fb619p-1)); + assert(test_case(std::numbers::phi /**/, 0x1.9e3779b97f4a8p+0)); + + return true; +} + +// N4944 [math.constants]/2: "a program may partially or explicitly specialize a mathematical constant // variable template provided that the specialization depends on a program-defined type." struct Meow { int val; @@ -45,87 +157,34 @@ inline constexpr Meow std::numbers::egamma_v{-120}; template <> inline constexpr Meow std::numbers::phi_v{-130}; +constexpr bool test_program_defined_specialization() { + assert(test_case(std::numbers::e_v.val, -10)); + assert(test_case(std::numbers::log2e_v.val, -20)); + assert(test_case(std::numbers::log10e_v.val, -30)); + assert(test_case(std::numbers::pi_v.val, -40)); + assert(test_case(std::numbers::inv_pi_v.val, -50)); + assert(test_case(std::numbers::inv_sqrtpi_v.val, -60)); + assert(test_case(std::numbers::ln2_v.val, -70)); + assert(test_case(std::numbers::ln10_v.val, -80)); + assert(test_case(std::numbers::sqrt2_v.val, -90)); + assert(test_case(std::numbers::sqrt3_v.val, -100)); + assert(test_case(std::numbers::inv_sqrt3_v.val, -110)); + assert(test_case(std::numbers::egamma_v.val, -120)); + assert(test_case(std::numbers::phi_v.val, -130)); + + return true; +} + +STATIC_ASSERT(test_cv_floating_point()); +STATIC_ASSERT(test_cv_floating_point()); +STATIC_ASSERT(test_double()); +STATIC_ASSERT(test_program_defined_specialization()); + int main() { - STATIC_ASSERT(test_case(std::numbers::e_v.val, -10)); - STATIC_ASSERT(test_case(std::numbers::log2e_v.val, -20)); - STATIC_ASSERT(test_case(std::numbers::log10e_v.val, -30)); - STATIC_ASSERT(test_case(std::numbers::pi_v.val, -40)); - STATIC_ASSERT(test_case(std::numbers::inv_pi_v.val, -50)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrtpi_v.val, -60)); - STATIC_ASSERT(test_case(std::numbers::ln2_v.val, -70)); - STATIC_ASSERT(test_case(std::numbers::ln10_v.val, -80)); - STATIC_ASSERT(test_case(std::numbers::sqrt2_v.val, -90)); - STATIC_ASSERT(test_case(std::numbers::sqrt3_v.val, -100)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrt3_v.val, -110)); - STATIC_ASSERT(test_case(std::numbers::egamma_v.val, -120)); - STATIC_ASSERT(test_case(std::numbers::phi_v.val, -130)); - - using F = float; - using D = double; - using L = long double; - - STATIC_ASSERT(test_case(std::numbers::e_v, 0x1.5bf0a8p+1f)); - STATIC_ASSERT(test_case(std::numbers::e_v, 0x1.5bf0a8b145769p+1)); - STATIC_ASSERT(test_case(std::numbers::e_v, 0x1.5bf0a8b145769p+1L)); - STATIC_ASSERT(test_case(std::numbers::e /**/, 0x1.5bf0a8b145769p+1)); - - STATIC_ASSERT(test_case(std::numbers::log2e_v, 0x1.715476p+0f)); - STATIC_ASSERT(test_case(std::numbers::log2e_v, 0x1.71547652b82fep+0)); - STATIC_ASSERT(test_case(std::numbers::log2e_v, 0x1.71547652b82fep+0L)); - STATIC_ASSERT(test_case(std::numbers::log2e /**/, 0x1.71547652b82fep+0)); - - STATIC_ASSERT(test_case(std::numbers::log10e_v, 0x1.bcb7b2p-2f)); - STATIC_ASSERT(test_case(std::numbers::log10e_v, 0x1.bcb7b1526e50ep-2)); - STATIC_ASSERT(test_case(std::numbers::log10e_v, 0x1.bcb7b1526e50ep-2L)); - STATIC_ASSERT(test_case(std::numbers::log10e /**/, 0x1.bcb7b1526e50ep-2)); - - STATIC_ASSERT(test_case(std::numbers::pi_v, 0x1.921fb6p+1f)); - STATIC_ASSERT(test_case(std::numbers::pi_v, 0x1.921fb54442d18p+1)); - STATIC_ASSERT(test_case(std::numbers::pi_v, 0x1.921fb54442d18p+1L)); - STATIC_ASSERT(test_case(std::numbers::pi /**/, 0x1.921fb54442d18p+1)); - - STATIC_ASSERT(test_case(std::numbers::inv_pi_v, 0x1.45f306p-2f)); - STATIC_ASSERT(test_case(std::numbers::inv_pi_v, 0x1.45f306dc9c883p-2)); - STATIC_ASSERT(test_case(std::numbers::inv_pi_v, 0x1.45f306dc9c883p-2L)); - STATIC_ASSERT(test_case(std::numbers::inv_pi /**/, 0x1.45f306dc9c883p-2)); - - STATIC_ASSERT(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd76p-1f)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd750429b6dp-1)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrtpi_v, 0x1.20dd750429b6dp-1L)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrtpi /**/, 0x1.20dd750429b6dp-1)); - - STATIC_ASSERT(test_case(std::numbers::ln2_v, 0x1.62e430p-1f)); - STATIC_ASSERT(test_case(std::numbers::ln2_v, 0x1.62e42fefa39efp-1)); - STATIC_ASSERT(test_case(std::numbers::ln2_v, 0x1.62e42fefa39efp-1L)); - STATIC_ASSERT(test_case(std::numbers::ln2 /**/, 0x1.62e42fefa39efp-1)); - - STATIC_ASSERT(test_case(std::numbers::ln10_v, 0x1.26bb1cp+1f)); - STATIC_ASSERT(test_case(std::numbers::ln10_v, 0x1.26bb1bbb55516p+1)); - STATIC_ASSERT(test_case(std::numbers::ln10_v, 0x1.26bb1bbb55516p+1L)); - STATIC_ASSERT(test_case(std::numbers::ln10 /**/, 0x1.26bb1bbb55516p+1)); - - STATIC_ASSERT(test_case(std::numbers::sqrt2_v, 0x1.6a09e6p+0f)); - STATIC_ASSERT(test_case(std::numbers::sqrt2_v, 0x1.6a09e667f3bcdp+0)); - STATIC_ASSERT(test_case(std::numbers::sqrt2_v, 0x1.6a09e667f3bcdp+0L)); - STATIC_ASSERT(test_case(std::numbers::sqrt2 /**/, 0x1.6a09e667f3bcdp+0)); - - STATIC_ASSERT(test_case(std::numbers::sqrt3_v, 0x1.bb67aep+0f)); - STATIC_ASSERT(test_case(std::numbers::sqrt3_v, 0x1.bb67ae8584caap+0)); - STATIC_ASSERT(test_case(std::numbers::sqrt3_v, 0x1.bb67ae8584caap+0L)); - STATIC_ASSERT(test_case(std::numbers::sqrt3 /**/, 0x1.bb67ae8584caap+0)); - - STATIC_ASSERT(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74p-1f)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74590331cp-1)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrt3_v, 0x1.279a74590331cp-1L)); - STATIC_ASSERT(test_case(std::numbers::inv_sqrt3 /**/, 0x1.279a74590331cp-1)); - - STATIC_ASSERT(test_case(std::numbers::egamma_v, 0x1.2788d0p-1f)); - STATIC_ASSERT(test_case(std::numbers::egamma_v, 0x1.2788cfc6fb619p-1)); - STATIC_ASSERT(test_case(std::numbers::egamma_v, 0x1.2788cfc6fb619p-1L)); - STATIC_ASSERT(test_case(std::numbers::egamma /**/, 0x1.2788cfc6fb619p-1)); - - STATIC_ASSERT(test_case(std::numbers::phi_v, 0x1.9e377ap+0f)); - STATIC_ASSERT(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0)); - STATIC_ASSERT(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0L)); - STATIC_ASSERT(test_case(std::numbers::phi /**/, 0x1.9e3779b97f4a8p+0)); + assert(test_cv_floating_point()); + assert(test_cv_floating_point()); + assert(test_cv_floating_point()); // constexpr-incompatible + assert(test_cv_floating_point()); // constexpr-incompatible + assert(test_double()); + assert(test_program_defined_specialization()); } From e0c0cd22bf513f090ea7f816f6de1a9347f8f810 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 7 Apr 2023 10:59:15 +0800 Subject: [PATCH 2/7] Rework implementation of `` when concepts are missing --- stl/inc/numbers | 118 +++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 81 deletions(-) diff --git a/stl/inc/numbers b/stl/inc/numbers index af5d9e4cec..a4131be2cc 100644 --- a/stl/inc/numbers +++ b/stl/inc/numbers @@ -14,7 +14,7 @@ _EMIT_STL_WARNING(STL4038, "The contents of are available only with C+ #ifdef __cpp_lib_concepts #include #else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv -#include +#include #endif // ^^^ !defined(__cpp_lib_concepts) ^^^ #pragma pack(push, _CRT_PACKING) @@ -26,10 +26,11 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN namespace numbers { +#ifdef __cpp_lib_concepts template struct _Invalid { static_assert(_Always_false<_Ty>, "A program that instantiates a primary template of a mathematical constant " - "variable template is ill-formed. (N4835 [math.constants]/3)"); + "variable template is ill-formed. (N4944 [math.constants]/3)"); }; _EXPORT_STD template @@ -59,7 +60,6 @@ namespace numbers { _EXPORT_STD template inline constexpr _Ty phi_v = _Invalid<_Ty>{}; -#ifdef __cpp_lib_concepts template inline constexpr _Floating e_v<_Floating> = static_cast<_Floating>(2.718281828459045); template @@ -87,86 +87,42 @@ namespace numbers { template inline constexpr _Floating phi_v<_Floating> = static_cast<_Floating>(1.618033988749895); #else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv - template <> - inline constexpr double e_v = 2.718281828459045; - template <> - inline constexpr double log2e_v = 1.4426950408889634; - template <> - inline constexpr double log10e_v = 0.4342944819032518; - template <> - inline constexpr double pi_v = 3.141592653589793; - template <> - inline constexpr double inv_pi_v = 0.3183098861837907; - template <> - inline constexpr double inv_sqrtpi_v = 0.5641895835477563; - template <> - inline constexpr double ln2_v = 0.6931471805599453; - template <> - inline constexpr double ln10_v = 2.302585092994046; - template <> - inline constexpr double sqrt2_v = 1.4142135623730951; - template <> - inline constexpr double sqrt3_v = 1.7320508075688772; - template <> - inline constexpr double inv_sqrt3_v = 0.5773502691896257; - template <> - inline constexpr double egamma_v = 0.5772156649015329; - template <> - inline constexpr double phi_v = 1.618033988749895; + template + struct _Reject_primary_template { + static_assert(is_floating_point_v<_Ty>, "A program that instantiates a primary template of a mathematical " + "constant variable template is ill-formed. (N4944 [math.constants]/3)"); + using type = _Ty; + }; - template <> - inline constexpr float e_v = static_cast(e_v); - template <> - inline constexpr float log2e_v = static_cast(log2e_v); - template <> - inline constexpr float log10e_v = static_cast(log10e_v); - template <> - inline constexpr float pi_v = static_cast(pi_v); - template <> - inline constexpr float inv_pi_v = static_cast(inv_pi_v); - template <> - inline constexpr float inv_sqrtpi_v = static_cast(inv_sqrtpi_v); - template <> - inline constexpr float ln2_v = static_cast(ln2_v); - template <> - inline constexpr float ln10_v = static_cast(ln10_v); - template <> - inline constexpr float sqrt2_v = static_cast(sqrt2_v); - template <> - inline constexpr float sqrt3_v = static_cast(sqrt3_v); - template <> - inline constexpr float inv_sqrt3_v = static_cast(inv_sqrt3_v); - template <> - inline constexpr float egamma_v = static_cast(egamma_v); - template <> - inline constexpr float phi_v = static_cast(phi_v); + template + using _Reject_primary_template_t = typename _Reject_primary_template<_Ty>::type; - template <> - inline constexpr long double e_v = e_v; - template <> - inline constexpr long double log2e_v = log2e_v; - template <> - inline constexpr long double log10e_v = log10e_v; - template <> - inline constexpr long double pi_v = pi_v; - template <> - inline constexpr long double inv_pi_v = inv_pi_v; - template <> - inline constexpr long double inv_sqrtpi_v = inv_sqrtpi_v; - template <> - inline constexpr long double ln2_v = ln2_v; - template <> - inline constexpr long double ln10_v = ln10_v; - template <> - inline constexpr long double sqrt2_v = sqrt2_v; - template <> - inline constexpr long double sqrt3_v = sqrt3_v; - template <> - inline constexpr long double inv_sqrt3_v = inv_sqrt3_v; - template <> - inline constexpr long double egamma_v = egamma_v; - template <> - inline constexpr long double phi_v = phi_v; + _EXPORT_STD template + inline constexpr _Ty e_v = static_cast<_Reject_primary_template_t<_Ty>>(2.718281828459045); + _EXPORT_STD template + inline constexpr _Ty log2e_v = static_cast<_Reject_primary_template_t<_Ty>>(1.4426950408889634); + _EXPORT_STD template + inline constexpr _Ty log10e_v = static_cast<_Reject_primary_template_t<_Ty>>(0.4342944819032518); + _EXPORT_STD template + inline constexpr _Ty pi_v = static_cast<_Reject_primary_template_t<_Ty>>(3.141592653589793); + _EXPORT_STD template + inline constexpr _Ty inv_pi_v = static_cast<_Reject_primary_template_t<_Ty>>(0.3183098861837907); + _EXPORT_STD template + inline constexpr _Ty inv_sqrtpi_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5641895835477563); + _EXPORT_STD template + inline constexpr _Ty ln2_v = static_cast<_Reject_primary_template_t<_Ty>>(0.6931471805599453); + _EXPORT_STD template + inline constexpr _Ty ln10_v = static_cast<_Reject_primary_template_t<_Ty>>(2.302585092994046); + _EXPORT_STD template + inline constexpr _Ty sqrt2_v = static_cast<_Reject_primary_template_t<_Ty>>(1.4142135623730951); + _EXPORT_STD template + inline constexpr _Ty sqrt3_v = static_cast<_Reject_primary_template_t<_Ty>>(1.7320508075688772); + _EXPORT_STD template + inline constexpr _Ty inv_sqrt3_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5773502691896257); + _EXPORT_STD template + inline constexpr _Ty egamma_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5772156649015329); + _EXPORT_STD template + inline constexpr _Ty phi_v = static_cast<_Reject_primary_template_t<_Ty>>(1.618033988749895); #endif // ^^^ !defined(__cpp_lib_concepts) ^^^ _EXPORT_STD inline constexpr double e = e_v; From 41d68255dfee61ee93ea740dfeb7bc596cd0e937 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 7 Apr 2023 11:20:00 +0800 Subject: [PATCH 3/7] Missing clang-format --- stl/inc/numbers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/numbers b/stl/inc/numbers index a4131be2cc..5a98b29209 100644 --- a/stl/inc/numbers +++ b/stl/inc/numbers @@ -94,7 +94,7 @@ namespace numbers { using type = _Ty; }; - template + template using _Reject_primary_template_t = typename _Reject_primary_template<_Ty>::type; _EXPORT_STD template From f2fed16f1725a6565f4b510c1ea4bb7273eb9f3a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 8 Apr 2023 13:34:55 +0800 Subject: [PATCH 4/7] Address @strega-nil-ms's review comments Rename `_Reject_primary_template(_t)` to `_Reject_invalid(_t)`. Co-authored-by: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> --- stl/inc/numbers | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/stl/inc/numbers b/stl/inc/numbers index 5a98b29209..783399e52c 100644 --- a/stl/inc/numbers +++ b/stl/inc/numbers @@ -88,41 +88,41 @@ namespace numbers { inline constexpr _Floating phi_v<_Floating> = static_cast<_Floating>(1.618033988749895); #else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv template - struct _Reject_primary_template { + struct _Reject_invalid { static_assert(is_floating_point_v<_Ty>, "A program that instantiates a primary template of a mathematical " "constant variable template is ill-formed. (N4944 [math.constants]/3)"); using type = _Ty; }; template - using _Reject_primary_template_t = typename _Reject_primary_template<_Ty>::type; + using _Reject_invalid_t = typename _Reject_invalid<_Ty>::type; _EXPORT_STD template - inline constexpr _Ty e_v = static_cast<_Reject_primary_template_t<_Ty>>(2.718281828459045); + inline constexpr _Ty e_v = static_cast<_Reject_invalid_t<_Ty>>(2.718281828459045); _EXPORT_STD template - inline constexpr _Ty log2e_v = static_cast<_Reject_primary_template_t<_Ty>>(1.4426950408889634); + inline constexpr _Ty log2e_v = static_cast<_Reject_invalid_t<_Ty>>(1.4426950408889634); _EXPORT_STD template - inline constexpr _Ty log10e_v = static_cast<_Reject_primary_template_t<_Ty>>(0.4342944819032518); + inline constexpr _Ty log10e_v = static_cast<_Reject_invalid_t<_Ty>>(0.4342944819032518); _EXPORT_STD template - inline constexpr _Ty pi_v = static_cast<_Reject_primary_template_t<_Ty>>(3.141592653589793); + inline constexpr _Ty pi_v = static_cast<_Reject_invalid_t<_Ty>>(3.141592653589793); _EXPORT_STD template - inline constexpr _Ty inv_pi_v = static_cast<_Reject_primary_template_t<_Ty>>(0.3183098861837907); + inline constexpr _Ty inv_pi_v = static_cast<_Reject_invalid_t<_Ty>>(0.3183098861837907); _EXPORT_STD template - inline constexpr _Ty inv_sqrtpi_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5641895835477563); + inline constexpr _Ty inv_sqrtpi_v = static_cast<_Reject_invalid_t<_Ty>>(0.5641895835477563); _EXPORT_STD template - inline constexpr _Ty ln2_v = static_cast<_Reject_primary_template_t<_Ty>>(0.6931471805599453); + inline constexpr _Ty ln2_v = static_cast<_Reject_invalid_t<_Ty>>(0.6931471805599453); _EXPORT_STD template - inline constexpr _Ty ln10_v = static_cast<_Reject_primary_template_t<_Ty>>(2.302585092994046); + inline constexpr _Ty ln10_v = static_cast<_Reject_invalid_t<_Ty>>(2.302585092994046); _EXPORT_STD template - inline constexpr _Ty sqrt2_v = static_cast<_Reject_primary_template_t<_Ty>>(1.4142135623730951); + inline constexpr _Ty sqrt2_v = static_cast<_Reject_invalid_t<_Ty>>(1.4142135623730951); _EXPORT_STD template - inline constexpr _Ty sqrt3_v = static_cast<_Reject_primary_template_t<_Ty>>(1.7320508075688772); + inline constexpr _Ty sqrt3_v = static_cast<_Reject_invalid_t<_Ty>>(1.7320508075688772); _EXPORT_STD template - inline constexpr _Ty inv_sqrt3_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5773502691896257); + inline constexpr _Ty inv_sqrt3_v = static_cast<_Reject_invalid_t<_Ty>>(0.5773502691896257); _EXPORT_STD template - inline constexpr _Ty egamma_v = static_cast<_Reject_primary_template_t<_Ty>>(0.5772156649015329); + inline constexpr _Ty egamma_v = static_cast<_Reject_invalid_t<_Ty>>(0.5772156649015329); _EXPORT_STD template - inline constexpr _Ty phi_v = static_cast<_Reject_primary_template_t<_Ty>>(1.618033988749895); + inline constexpr _Ty phi_v = static_cast<_Reject_invalid_t<_Ty>>(1.618033988749895); #endif // ^^^ !defined(__cpp_lib_concepts) ^^^ _EXPORT_STD inline constexpr double e = e_v; From 138898a19f4d1adc840f41b0fa14a4e87303b6ba Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Apr 2023 12:37:19 -0700 Subject: [PATCH 5/7] `Modfication` => `Modification` --- tests/std/tests/P0631R8_numbers_math_constants/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp index 1e774907af..6a1ccd9660 100644 --- a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp +++ b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp @@ -22,7 +22,7 @@ enum class modify_cv { add_cv, }; -template +template struct apply_modify_cv { using type = T; }; @@ -42,8 +42,8 @@ struct apply_modify_cv { using type = const volatile T; }; -template -using apply_modify_cv_t = typename apply_modify_cv::type; +template +using apply_modify_cv_t = typename apply_modify_cv::type; template constexpr bool test_cv_floating_point() { From 233d717b5cb59c80e770d30524e6a49369fd6ce4 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Apr 2023 12:53:53 -0700 Subject: [PATCH 6/7] Drop empty comments. --- .../P0631R8_numbers_math_constants/test.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp index 6a1ccd9660..61d4ee6b9b 100644 --- a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp +++ b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp @@ -107,19 +107,19 @@ constexpr bool test_cv_floating_point() { } constexpr bool test_double() { - assert(test_case(std::numbers::e /**/, 0x1.5bf0a8b145769p+1)); - assert(test_case(std::numbers::log2e /**/, 0x1.71547652b82fep+0)); - assert(test_case(std::numbers::log10e /**/, 0x1.bcb7b1526e50ep-2)); - assert(test_case(std::numbers::pi /**/, 0x1.921fb54442d18p+1)); - assert(test_case(std::numbers::inv_pi /**/, 0x1.45f306dc9c883p-2)); - assert(test_case(std::numbers::inv_sqrtpi /**/, 0x1.20dd750429b6dp-1)); - assert(test_case(std::numbers::ln2 /**/, 0x1.62e42fefa39efp-1)); - assert(test_case(std::numbers::ln10 /**/, 0x1.26bb1bbb55516p+1)); - assert(test_case(std::numbers::sqrt2 /**/, 0x1.6a09e667f3bcdp+0)); - assert(test_case(std::numbers::sqrt3 /**/, 0x1.bb67ae8584caap+0)); - assert(test_case(std::numbers::inv_sqrt3 /**/, 0x1.279a74590331cp-1)); - assert(test_case(std::numbers::egamma /**/, 0x1.2788cfc6fb619p-1)); - assert(test_case(std::numbers::phi /**/, 0x1.9e3779b97f4a8p+0)); + assert(test_case(std::numbers::e, 0x1.5bf0a8b145769p+1)); + assert(test_case(std::numbers::log2e, 0x1.71547652b82fep+0)); + assert(test_case(std::numbers::log10e, 0x1.bcb7b1526e50ep-2)); + assert(test_case(std::numbers::pi, 0x1.921fb54442d18p+1)); + assert(test_case(std::numbers::inv_pi, 0x1.45f306dc9c883p-2)); + assert(test_case(std::numbers::inv_sqrtpi, 0x1.20dd750429b6dp-1)); + assert(test_case(std::numbers::ln2, 0x1.62e42fefa39efp-1)); + assert(test_case(std::numbers::ln10, 0x1.26bb1bbb55516p+1)); + assert(test_case(std::numbers::sqrt2, 0x1.6a09e667f3bcdp+0)); + assert(test_case(std::numbers::sqrt3, 0x1.bb67ae8584caap+0)); + assert(test_case(std::numbers::inv_sqrt3, 0x1.279a74590331cp-1)); + assert(test_case(std::numbers::egamma, 0x1.2788cfc6fb619p-1)); + assert(test_case(std::numbers::phi, 0x1.9e3779b97f4a8p+0)); return true; } From 01eb1dfcc19113a7ca0179b50539aca0df5b4d6b Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Apr 2023 13:07:51 -0700 Subject: [PATCH 7/7] Use `is_constant_evaluated()` to unify runtime and compiletime testing. --- .../P0631R8_numbers_math_constants/test.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp index 61d4ee6b9b..fd265a012c 100644 --- a/tests/std/tests/P0631R8_numbers_math_constants/test.cpp +++ b/tests/std/tests/P0631R8_numbers_math_constants/test.cpp @@ -46,7 +46,7 @@ template using apply_modify_cv_t = typename apply_modify_cv::type; template -constexpr bool test_cv_floating_point() { +constexpr void test_cv_floating_point() { using F = apply_modify_cv_t; using D = apply_modify_cv_t; using L = apply_modify_cv_t; @@ -102,11 +102,9 @@ constexpr bool test_cv_floating_point() { assert(test_case(std::numbers::phi_v, 0x1.9e377ap+0f)); assert(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0)); assert(test_case(std::numbers::phi_v, 0x1.9e3779b97f4a8p+0L)); - - return true; } -constexpr bool test_double() { +constexpr void test_double() { assert(test_case(std::numbers::e, 0x1.5bf0a8b145769p+1)); assert(test_case(std::numbers::log2e, 0x1.71547652b82fep+0)); assert(test_case(std::numbers::log10e, 0x1.bcb7b1526e50ep-2)); @@ -120,8 +118,6 @@ constexpr bool test_double() { assert(test_case(std::numbers::inv_sqrt3, 0x1.279a74590331cp-1)); assert(test_case(std::numbers::egamma, 0x1.2788cfc6fb619p-1)); assert(test_case(std::numbers::phi, 0x1.9e3779b97f4a8p+0)); - - return true; } // N4944 [math.constants]/2: "a program may partially or explicitly specialize a mathematical constant @@ -157,7 +153,7 @@ inline constexpr Meow std::numbers::egamma_v{-120}; template <> inline constexpr Meow std::numbers::phi_v{-130}; -constexpr bool test_program_defined_specialization() { +constexpr void test_program_defined_specialization() { assert(test_case(std::numbers::e_v.val, -10)); assert(test_case(std::numbers::log2e_v.val, -20)); assert(test_case(std::numbers::log10e_v.val, -30)); @@ -171,20 +167,24 @@ constexpr bool test_program_defined_specialization() { assert(test_case(std::numbers::inv_sqrt3_v.val, -110)); assert(test_case(std::numbers::egamma_v.val, -120)); assert(test_case(std::numbers::phi_v.val, -130)); +} + +constexpr bool test_all() { + test_cv_floating_point(); + test_cv_floating_point(); + + if (!std::is_constant_evaluated()) { + test_cv_floating_point(); // constexpr-incompatible + test_cv_floating_point(); // constexpr-incompatible + } + + test_double(); + test_program_defined_specialization(); return true; } -STATIC_ASSERT(test_cv_floating_point()); -STATIC_ASSERT(test_cv_floating_point()); -STATIC_ASSERT(test_double()); -STATIC_ASSERT(test_program_defined_specialization()); - int main() { - assert(test_cv_floating_point()); - assert(test_cv_floating_point()); - assert(test_cv_floating_point()); // constexpr-incompatible - assert(test_cv_floating_point()); // constexpr-incompatible - assert(test_double()); - assert(test_program_defined_specialization()); + assert(test_all()); + STATIC_ASSERT(test_all()); }