#include <ext/numeric_traits.h>
#include <bit> // __bit_width
#include <numbers>
+#include <limits> // __glibcxx_integral_traps
// This header implements unsigned and signed integer-class types (as per
// [iterator.concept.winc]) that are one bit wider than the widest supported
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
+ static constexpr bool is_bounded = true;
+ static constexpr bool is_modulo = true;
+ static constexpr bool traps = __glibcxx_integral_traps;
+ static constexpr int radix = 2;
static constexpr int digits
= __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1;
static constexpr int digits10
= static_cast<int>(digits * numbers::ln2 / numbers::ln10);
+ static constexpr int max_digits10 = 0;
+ static constexpr int min_exponent = 0;
+ static constexpr int min_exponent10 = 0;
+ static constexpr int max_exponent = 0;
+ static constexpr int max_exponent10 = 0;
+ static constexpr bool is_iec559 = false;
+ static constexpr bool has_infinity = false;
+ static constexpr bool has_quiet_NaN = false;
+ static constexpr bool has_signaling_NaN = false;
+ static constexpr bool has_denorm_loss = false;
+ static constexpr bool tinyness_before = false;
+ static constexpr float_denorm_style has_denorm = denorm_absent;
+ static constexpr float_round_style round_style = round_toward_zero;
static constexpr _Sp
min() noexcept
static constexpr _Sp
lowest() noexcept
{ return min(); }
+
+ static constexpr _Sp
+ denorm_min() noexcept
+ { return 0; }
+
+ static constexpr _Sp
+ epsilon() noexcept
+ { return 0; }
+
+ static constexpr _Sp
+ round_error() noexcept
+ { return 0; }
+
+ static constexpr _Sp
+ infinity() noexcept
+ { return 0; }
+
+ static constexpr _Sp
+ quiet_NaN() noexcept
+ { return 0; }
+
+ static constexpr _Sp
+ signaling_NaN() noexcept
+ { return 0; }
};
template<>
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
+ static constexpr bool is_bounded = true;
+ static constexpr bool is_modulo = false;
+ static constexpr bool traps = __glibcxx_integral_traps;
+ static constexpr int radix = 2;
static constexpr int digits = numeric_limits<_Sp>::digits - 1;
static constexpr int digits10
= static_cast<int>(digits * numbers::ln2 / numbers::ln10);
+ static constexpr int max_digits10 = 0;
+ static constexpr int min_exponent = 0;
+ static constexpr int min_exponent10 = 0;
+ static constexpr int max_exponent = 0;
+ static constexpr int max_exponent10 = 0;
+ static constexpr bool is_iec559 = false;
+ static constexpr bool has_infinity = false;
+ static constexpr bool has_quiet_NaN = false;
+ static constexpr bool has_signaling_NaN = false;
+ static constexpr bool has_denorm_loss = false;
+ static constexpr bool tinyness_before = false;
+ static constexpr float_denorm_style has_denorm = denorm_absent;
+ static constexpr float_round_style round_style = round_toward_zero;
static constexpr _Dp
min() noexcept
static constexpr _Dp
lowest() noexcept
{ return min(); }
+
+ static constexpr _Dp
+ denorm_min() noexcept
+ { return 0; }
+
+ static constexpr _Dp
+ epsilon() noexcept
+ { return 0; }
+
+ static constexpr _Dp
+ round_error() noexcept
+ { return 0; }
+
+ static constexpr _Dp
+ infinity() noexcept
+ { return 0; }
+
+ static constexpr _Dp
+ quiet_NaN() noexcept
+ { return 0; }
+
+ static constexpr _Dp
+ signaling_NaN() noexcept
+ { return 0; }
};
template<>
static_assert(!numeric_limits<max_size_t>::is_signed);
static_assert(numeric_limits<max_size_t>::is_integer);
static_assert(numeric_limits<max_size_t>::is_exact);
+static_assert(numeric_limits<max_size_t>::is_bounded);
+static_assert(numeric_limits<max_size_t>::is_modulo);
+static_assert(numeric_limits<max_size_t>::radix == 2);
// We can't unconditionally use numeric_limits here because __int128 is an
// integral type only in GNU mode.
#if __SIZEOF_INT128__
static_assert(numeric_limits<max_diff_t>::is_signed);
static_assert(numeric_limits<max_diff_t>::is_integer);
static_assert(numeric_limits<max_diff_t>::is_exact);
+static_assert(numeric_limits<max_diff_t>::is_bounded);
+static_assert(!numeric_limits<max_diff_t>::is_modulo);
+static_assert(numeric_limits<max_diff_t>::radix == 2);
static_assert(numeric_limits<max_diff_t>::digits
== numeric_limits<max_size_t>::digits - 1);
static_assert(numeric_limits<max_diff_t>::digits10
<< (numeric_limits<max_size_t>::digits-1))
== numeric_limits<max_diff_t>::min());
+template <typename integer_class>
+constexpr bool verify_numeric_limits_values_not_meaningful_for = true
+ && (numeric_limits<integer_class>::max_digits10 == 0)
+ && (numeric_limits<integer_class>::min_exponent == 0)
+ && (numeric_limits<integer_class>::min_exponent10 == 0)
+ && (numeric_limits<integer_class>::max_exponent == 0)
+ && (numeric_limits<integer_class>::max_exponent10 == 0)
+ && !numeric_limits<integer_class>::is_iec559
+ && !numeric_limits<integer_class>::has_infinity
+ && !numeric_limits<integer_class>::has_quiet_NaN
+ && !numeric_limits<integer_class>::has_signaling_NaN
+ && !numeric_limits<integer_class>::has_denorm_loss
+ && !numeric_limits<integer_class>::tinyness_before
+ && (numeric_limits<integer_class>::has_denorm == std::denorm_absent)
+ && (numeric_limits<integer_class>::round_style == std::round_toward_zero)
+ && (numeric_limits<integer_class>::denorm_min() == 0)
+ && (numeric_limits<integer_class>::epsilon() == 0)
+ && (numeric_limits<integer_class>::round_error() == 0)
+ && (numeric_limits<integer_class>::infinity() == 0)
+ && (numeric_limits<integer_class>::quiet_NaN() == 0)
+ && (numeric_limits<integer_class>::signaling_NaN() == 0);
+
+static_assert(verify_numeric_limits_values_not_meaningful_for<max_size_t>);
+static_assert(verify_numeric_limits_values_not_meaningful_for<max_diff_t>);
+
// Verify that the types are structural types and can therefore be used
// as NTTP types.
template<max_size_t V> struct Su { static_assert(V*V == V+132); };