std::numeric_limits<T>::is_modulo
static const bool is_modulo; |
(until C++11) | |
static constexpr bool is_modulo; |
(since C++11) | |
The value of std::numeric_limits<T>::is_modulo is true for all arithmetic types T
that are possible to (until C++11)handle overflows with modulo arithmetic, that is, if the result of addition, subtraction, multiplication, or division of this type would fall outside the range [min(), max()], the value returned by such operation differs from the expected value by a multiple of max()-min()+1.
|
(since C++11) |
Standard specializations
T
|
value of std::numeric_limits<T>::is_modulo |
/* non-specialized */ | false |
bool | false |
char | implementation-defined |
signed char | implementation-defined |
unsigned char | true |
wchar_t | implementation-defined |
char8_t (C++20) | true |
char16_t (C++11) | true |
char32_t (C++11) | true |
short | implementation-defined |
unsigned short | true |
int | implementation-defined |
unsigned int | true |
long | implementation-defined |
unsigned long | true |
long long (C++11) | implementation-defined |
unsigned long long (C++11) | true |
float | false |
double | false |
long double | false |
Notes
Although the C++11 standard still says "On most machines, this is true for signed integers.", it is a defect and has been corrected. The exact wording changed from C++03 to C++11 in such a way that the true value is no longer compatible with undefined behavior on signed integer overflow. Because of that, the implementations that rely on signed overflow being undefined (for optimization opportunities) now set is_modulo
to false
for signed integers. See for example GCC PR 22200.
Example
Demonstrates the behavior of modulo types
#include <iostream> #include <type_traits> #include <limits> template<class T> typename std::enable_if<std::numeric_limits<T>::is_modulo>::type check_overflow() { std::cout << "\nmax value is " << std::numeric_limits<T>::max() << '\n' << "min value is " << std::numeric_limits<T>::min() << '\n' << "max value + 1 is " << std::numeric_limits<T>::max()+1 << '\n'; } int main() { check_overflow<int>(); check_overflow<unsigned long>(); // check_overflow<float>(); // compile-time error, not a modulo type }
Possible output:
max value is 2147483647 min value is -2147483648 max value + 1 is -2147483648 max value is 18446744073709551615 min value is 0 max value + 1 is 0
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 2422 | C++11 | is_modulo was required to true for signed integer types on most machines |
required to be false for signed integer types unless signed integer overflow is defined to wrap |
See also
[static] |
identifies integer types (public static member constant) |
[static] |
identifies the IEC 559/IEEE 754 floating-point types (public static member constant) |
[static] |
identifies exact types (public static member constant) |