std::numeric_limits::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 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. 
| Contents | 
[edit] 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 | 
| char16_t | implementation-defined | 
| char32_t | implementation-defined | 
| short | implementation-defined | 
| unsigned short | true | 
| int | implementation-defined | 
| unsigned int | true | 
| long | implementation-defined | 
| unsigned long | true | 
| long long | implementation-defined | 
| unsigned long long | true | 
| float | false | 
| double | false | 
| long double | false | 
[edit] Notes
Although the C++11 standard still says "On most machines, this is true for signed integers.", 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 (it changed from "possible" to a strict requirement). 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.
The standard wording is expected to change to "is_modulo is false for signed integer types unless an implementation defines signed integer overflow to wrap" per LWG issue 2422.
[edit] 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
[edit] 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) | 


