-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++][NFC] Simplify the implementation of numeric_limits
#80425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The cv specializations for `numeric_limits` inherited privately for some reason. We can simplify the implementation by inheriting publicly and removing the members that just replicate the values from the base cl ass.
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThe cv specializations for Full diff: https://github.com/llvm/llvm-project/pull/80425.diff 1 Files Affected:
diff --git a/libcxx/include/limits b/libcxx/include/limits
index a240580c0132f..c704b4dddaf8e 100644
--- a/libcxx/include/limits
+++ b/libcxx/include/limits
@@ -436,8 +436,8 @@ protected:
};
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS numeric_limits : private __libcpp_numeric_limits<__remove_cv_t<_Tp> > {
- typedef __libcpp_numeric_limits<__remove_cv_t<_Tp> > __base;
+class _LIBCPP_TEMPLATE_VIS numeric_limits : private __libcpp_numeric_limits<_Tp> {
+ typedef __libcpp_numeric_limits<_Tp> __base;
typedef typename __base::type type;
public:
@@ -530,286 +530,13 @@ template <class _Tp>
_LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style;
template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS numeric_limits<const _Tp> : private numeric_limits<_Tp> {
- typedef numeric_limits<_Tp> __base;
- typedef _Tp type;
-
-public:
- static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type min() _NOEXCEPT { return __base::min(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type max() _NOEXCEPT { return __base::max(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT { return __base::lowest(); }
-
- static _LIBCPP_CONSTEXPR const int digits = __base::digits;
- static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10;
- static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10;
- static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
- static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
- static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
- static _LIBCPP_CONSTEXPR const int radix = __base::radix;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT { return __base::epsilon(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT { return __base::round_error(); }
+class _LIBCPP_TEMPLATE_VIS numeric_limits<const _Tp> : public numeric_limits<_Tp> {};
- static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent;
- static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10;
- static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent;
- static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10;
-
- static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
- static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
- static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
- _LIBCPP_SUPPRESS_DEPRECATED_POP
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT { return __base::infinity(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT { return __base::quiet_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT { return __base::signaling_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT { return __base::denorm_min(); }
-
- static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
- static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
- static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
-
- static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
- static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
- static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
-};
-
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_specialized;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_signed;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_integer;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_exact;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::radix;
template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_infinity;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_quiet_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_signaling_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const _Tp>::has_denorm;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_denorm_loss;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_iec559;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_bounded;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_modulo;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::traps;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::tinyness_before;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const float_round_style numeric_limits<const _Tp>::round_style;
-
-template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS numeric_limits<volatile _Tp> : private numeric_limits<_Tp> {
- typedef numeric_limits<_Tp> __base;
- typedef _Tp type;
-
-public:
- static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type min() _NOEXCEPT { return __base::min(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type max() _NOEXCEPT { return __base::max(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT { return __base::lowest(); }
-
- static _LIBCPP_CONSTEXPR const int digits = __base::digits;
- static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10;
- static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10;
- static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
- static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
- static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
- static _LIBCPP_CONSTEXPR const int radix = __base::radix;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT { return __base::epsilon(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT { return __base::round_error(); }
-
- static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent;
- static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10;
- static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent;
- static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10;
-
- static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
- static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
- static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
- _LIBCPP_SUPPRESS_DEPRECATED_POP
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT { return __base::infinity(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT { return __base::quiet_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT { return __base::signaling_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT { return __base::denorm_min(); }
+class _LIBCPP_TEMPLATE_VIS numeric_limits<volatile _Tp> : public numeric_limits<_Tp> {};
- static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
- static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
- static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
-
- static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
- static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
- static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
-};
-
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_specialized;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_signed;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_integer;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_exact;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::radix;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_infinity;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_quiet_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_signaling_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<volatile _Tp>::has_denorm;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_denorm_loss;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_iec559;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_bounded;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_modulo;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::traps;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::tinyness_before;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const float_round_style numeric_limits<volatile _Tp>::round_style;
-
-template <class _Tp>
-class _LIBCPP_TEMPLATE_VIS numeric_limits<const volatile _Tp> : private numeric_limits<_Tp> {
- typedef numeric_limits<_Tp> __base;
- typedef _Tp type;
-
-public:
- static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type min() _NOEXCEPT { return __base::min(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type max() _NOEXCEPT { return __base::max(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT { return __base::lowest(); }
-
- static _LIBCPP_CONSTEXPR const int digits = __base::digits;
- static _LIBCPP_CONSTEXPR const int digits10 = __base::digits10;
- static _LIBCPP_CONSTEXPR const int max_digits10 = __base::max_digits10;
- static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
- static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
- static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
- static _LIBCPP_CONSTEXPR const int radix = __base::radix;
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT { return __base::epsilon(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT { return __base::round_error(); }
-
- static _LIBCPP_CONSTEXPR const int min_exponent = __base::min_exponent;
- static _LIBCPP_CONSTEXPR const int min_exponent10 = __base::min_exponent10;
- static _LIBCPP_CONSTEXPR const int max_exponent = __base::max_exponent;
- static _LIBCPP_CONSTEXPR const int max_exponent10 = __base::max_exponent10;
-
- static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
- static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
- static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
- _LIBCPP_SUPPRESS_DEPRECATED_PUSH
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
- static _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
- _LIBCPP_SUPPRESS_DEPRECATED_POP
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT { return __base::infinity(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT { return __base::quiet_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT { return __base::signaling_NaN(); }
- _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT { return __base::denorm_min(); }
-
- static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
- static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
- static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
-
- static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
- static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
- static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
-};
-
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_specialized;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_digits10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_signed;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_integer;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_exact;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::radix;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent10;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_infinity;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_quiet_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_signaling_NaN;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const volatile _Tp>::has_denorm;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_denorm_loss;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_iec559;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_bounded;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_modulo;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::traps;
-template <class _Tp>
-_LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::tinyness_before;
template <class _Tp>
-_LIBCPP_CONSTEXPR const float_round_style numeric_limits<const volatile _Tp>::round_style;
+class _LIBCPP_TEMPLATE_VIS numeric_limits<const volatile _Tp> : public numeric_limits<_Tp> {};
_LIBCPP_END_NAMESPACE_STD
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After discussion, we can't think of a case that this refactoring breaks. Regarding the fly-by removal of __remove_cv_t
, it was previously impossible to call __libcpp_numeric_limits
with a cv-qualified type anyway, cause they were stripped by the top-level numeric_limits
templates.
So I think this is fine, however let's monitor this patch in case someone complains, since it's possible the code was written this way for a reason back in the days, and we just can't figure it out right now.
Do we have tests for numeric limits with cv-qualified types? If not, we need to add some before we merge this. |
The cv specializations for
numeric_limits
inherited privately for some reason. We can simplify the implementation by inheriting publicly and removing the members that just replicate the values from the base class.