<xstd/ints/limits/numeric_limits.hpp>¶
xstd::numeric_limits¶
// (1)
template<class T>
struct numeric_limits {};
// (2)
template<class T>
requires (is_object_v<T> and not is_array_v<T>)
struct numeric_limits<T> : std::numeric_limits<T> {};
// (3)
template<class T>
struct numeric_limits<const T> : numeric_limits<T> {};
// (4)
template<class T>
struct numeric_limits<volatile T> : numeric_limits<T> {};
// (5)
template<class T>
struct numeric_limits<const volatile T> : numeric_limits<T> {};
The standard's limits, asked safely of any type and through any cv-qualification.
- For
void, a reference, an array, a cv-qualified array and a function type it is an empty class, so naming a member is a substitution failure rather than an error insidestd::numeric_limits. - For an object type that is not an array, it derives from
std::numeric_limits<T>and so gives the same answers. - For a cv-qualified type it derives from the specialization for the unqualified type: here a
consttype. - Likewise for a
volatiletype. - Likewise for a
const volatiletype.
Remarks¶
A program may specialize it for a type of its own; the cv-qualified forms then follow.
Notes¶
The cv-qualified specializations forward to a specialization of xstd's own, not only to the standard library's:
bit_int<17> const and signed _BitInt(24) const read the _BitInt digits.
See also¶
| Entity | Relation |
|---|---|
integer_class |
reads is_specialized, is_integer, radix, min() and max() |
std::numeric_limits |
the standard's limits, which (2) derives from |
xstd::numeric_limits<signed _BitInt(N)>, xstd::numeric_limits<unsigned _BitInt(N)>¶
// (1)
template<size_t N>
struct numeric_limits<signed _BitInt(N)> : std::numeric_limits<signed _BitInt(N)> {
static constexpr bool is_specialized = true;
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 int digits = N - 1;
static constexpr int digits10 = see below;
static constexpr int radix = 2;
static constexpr auto min() noexcept -> signed _BitInt(N); // -max() - 1
static constexpr auto max() noexcept -> signed _BitInt(N); // 2^(N-1) - 1
static constexpr auto lowest() noexcept -> signed _BitInt(N); // min()
};
// (2)
template<size_t N>
struct numeric_limits<unsigned _BitInt(N)> : std::numeric_limits<unsigned _BitInt(N)> {
static constexpr bool is_specialized = true;
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 int digits = N;
static constexpr int digits10 = see below;
static constexpr int radix = 2;
static constexpr auto min() noexcept -> unsigned _BitInt(N); // 0
static constexpr auto max() noexcept -> unsigned _BitInt(N); // 2^N - 1
static constexpr auto lowest() noexcept -> unsigned _BitInt(N); // min()
};
The limits of a bit-precise type at its requested width. Here numeric_limits is xstd's, and the base is the standard
library's. Both are declared, where the compiler defines __BITINT_MAXWIDTH__, in the header that declares the
primary template.
- For
signed _BitInt(N):digitsisN - 1,is_moduloisfalse, and the range runs from-max() - 1to 2^(N-1) - 1. - For
unsigned _BitInt(N):digitsisN,is_moduloistrue, and the range runs from 0 to 2^N - 1.
Member constants¶
digits,min()andmax()follow the requested width, not the object's size, and are constant expressions: at 17 bits, 16 and 17 digits, a signed range of −65536 to 65535 and an unsigned maximum of 131071. On libc++, which specializesstd::numeric_limitsfor_BitIntwithdigitstaken fromsizeof, these replace its values.digits10isfloor(digits * log10(2)), the most decimal digits the type represents without change: 7 forunsigned _BitInt(24)and 6 forsigned _BitInt(24), and at 8 and 64 bits the valuestd::numeric_limitsgives the exact-width type of that width. It replaces libstdc++'s zero and libc++'s value for the width of the object.- Remarks:
digits10is computed in 64.64 fixed point, which is exact for everydigitsup to 2^23, and the header is ill-formed where__BITINT_MAXWIDTH__exceeds 8'388'608.
- Remarks:
is_specialized,is_integerandradix == 2hold, asinteger_classrequires.is_signedfollows the type's signedness,is_exactandis_boundedaretrue,is_moduloisfalsefor the signed type andtruefor the unsigned, andlowest()ismin().max_digits10is inherited, and is 0, as for every integer.
Remarks¶
Every other member is inherited from std::numeric_limits<_BitInt(N)>: the primary template's where the standard
library does not specialize it, as libstdc++ does not, and libc++'s where it does.
Notes¶
A translation unit that can name xstd::numeric_limits has them, whatever else it includes: _BitInt is a keyword, so
a program can ask about one with no other xstd header, and gets the answer it would get with every header.
See also¶
| Entity | Relation |
|---|---|
bit_int, bit_uint |
the aliases that name the bit-precise types |
make_signed<unsigned _BitInt(N)> |
the transformations of the same types |
std::numeric_limits |
the base, whose other members it inherits |