Skip to content

Commit

Permalink
<numbers>: Rework the implementation when concepts are missing (#3633)
Browse files Browse the repository at this point in the history
Co-authored-by: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com>
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
3 people committed Apr 14, 2023
1 parent ca5833c commit fc480dd
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 166 deletions.
118 changes: 37 additions & 81 deletions stl/inc/numbers
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ _EMIT_STL_WARNING(STL4038, "The contents of <numbers> are available only with C+
#ifdef __cpp_lib_concepts
#include <concepts>
#else // ^^^ defined(__cpp_lib_concepts) / !defined(__cpp_lib_concepts) vvv
#include <xstddef>
#include <xtr1common>
#endif // ^^^ !defined(__cpp_lib_concepts) ^^^

#pragma pack(push, _CRT_PACKING)
Expand All @@ -26,10 +26,11 @@ _STL_DISABLE_CLANG_WARNINGS

_STD_BEGIN
namespace numbers {
#ifdef __cpp_lib_concepts
template <class _Ty>
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 <class _Ty>
Expand Down Expand Up @@ -59,7 +60,6 @@ namespace numbers {
_EXPORT_STD template <class _Ty>
inline constexpr _Ty phi_v = _Invalid<_Ty>{};

#ifdef __cpp_lib_concepts
template <floating_point _Floating>
inline constexpr _Floating e_v<_Floating> = static_cast<_Floating>(2.718281828459045);
template <floating_point _Floating>
Expand Down Expand Up @@ -87,86 +87,42 @@ namespace numbers {
template <floating_point _Floating>
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<double> = 2.718281828459045;
template <>
inline constexpr double log2e_v<double> = 1.4426950408889634;
template <>
inline constexpr double log10e_v<double> = 0.4342944819032518;
template <>
inline constexpr double pi_v<double> = 3.141592653589793;
template <>
inline constexpr double inv_pi_v<double> = 0.3183098861837907;
template <>
inline constexpr double inv_sqrtpi_v<double> = 0.5641895835477563;
template <>
inline constexpr double ln2_v<double> = 0.6931471805599453;
template <>
inline constexpr double ln10_v<double> = 2.302585092994046;
template <>
inline constexpr double sqrt2_v<double> = 1.4142135623730951;
template <>
inline constexpr double sqrt3_v<double> = 1.7320508075688772;
template <>
inline constexpr double inv_sqrt3_v<double> = 0.5773502691896257;
template <>
inline constexpr double egamma_v<double> = 0.5772156649015329;
template <>
inline constexpr double phi_v<double> = 1.618033988749895;
template <class _Ty>
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 <>
inline constexpr float e_v<float> = static_cast<float>(e_v<double>);
template <>
inline constexpr float log2e_v<float> = static_cast<float>(log2e_v<double>);
template <>
inline constexpr float log10e_v<float> = static_cast<float>(log10e_v<double>);
template <>
inline constexpr float pi_v<float> = static_cast<float>(pi_v<double>);
template <>
inline constexpr float inv_pi_v<float> = static_cast<float>(inv_pi_v<double>);
template <>
inline constexpr float inv_sqrtpi_v<float> = static_cast<float>(inv_sqrtpi_v<double>);
template <>
inline constexpr float ln2_v<float> = static_cast<float>(ln2_v<double>);
template <>
inline constexpr float ln10_v<float> = static_cast<float>(ln10_v<double>);
template <>
inline constexpr float sqrt2_v<float> = static_cast<float>(sqrt2_v<double>);
template <>
inline constexpr float sqrt3_v<float> = static_cast<float>(sqrt3_v<double>);
template <>
inline constexpr float inv_sqrt3_v<float> = static_cast<float>(inv_sqrt3_v<double>);
template <>
inline constexpr float egamma_v<float> = static_cast<float>(egamma_v<double>);
template <>
inline constexpr float phi_v<float> = static_cast<float>(phi_v<double>);
template <class _Ty>
using _Reject_invalid_t = typename _Reject_invalid<_Ty>::type;

template <>
inline constexpr long double e_v<long double> = e_v<double>;
template <>
inline constexpr long double log2e_v<long double> = log2e_v<double>;
template <>
inline constexpr long double log10e_v<long double> = log10e_v<double>;
template <>
inline constexpr long double pi_v<long double> = pi_v<double>;
template <>
inline constexpr long double inv_pi_v<long double> = inv_pi_v<double>;
template <>
inline constexpr long double inv_sqrtpi_v<long double> = inv_sqrtpi_v<double>;
template <>
inline constexpr long double ln2_v<long double> = ln2_v<double>;
template <>
inline constexpr long double ln10_v<long double> = ln10_v<double>;
template <>
inline constexpr long double sqrt2_v<long double> = sqrt2_v<double>;
template <>
inline constexpr long double sqrt3_v<long double> = sqrt3_v<double>;
template <>
inline constexpr long double inv_sqrt3_v<long double> = inv_sqrt3_v<double>;
template <>
inline constexpr long double egamma_v<long double> = egamma_v<double>;
template <>
inline constexpr long double phi_v<long double> = phi_v<double>;
_EXPORT_STD template <class _Ty>
inline constexpr _Ty e_v = static_cast<_Reject_invalid_t<_Ty>>(2.718281828459045);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty log2e_v = static_cast<_Reject_invalid_t<_Ty>>(1.4426950408889634);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty log10e_v = static_cast<_Reject_invalid_t<_Ty>>(0.4342944819032518);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty pi_v = static_cast<_Reject_invalid_t<_Ty>>(3.141592653589793);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty inv_pi_v = static_cast<_Reject_invalid_t<_Ty>>(0.3183098861837907);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty inv_sqrtpi_v = static_cast<_Reject_invalid_t<_Ty>>(0.5641895835477563);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty ln2_v = static_cast<_Reject_invalid_t<_Ty>>(0.6931471805599453);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty ln10_v = static_cast<_Reject_invalid_t<_Ty>>(2.302585092994046);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty sqrt2_v = static_cast<_Reject_invalid_t<_Ty>>(1.4142135623730951);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty sqrt3_v = static_cast<_Reject_invalid_t<_Ty>>(1.7320508075688772);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty inv_sqrt3_v = static_cast<_Reject_invalid_t<_Ty>>(0.5773502691896257);
_EXPORT_STD template <class _Ty>
inline constexpr _Ty egamma_v = static_cast<_Reject_invalid_t<_Ty>>(0.5772156649015329);
_EXPORT_STD template <class _Ty>
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<double>;
Expand Down
Loading

0 comments on commit fc480dd

Please sign in to comment.