std::numeric_limits::is_modulo (3) Linux Manual Page
std::numeric_limits<T>::is_modulo – std::numeric_limits<T>::is_modulo
Synopsis
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.
is_modulo is false for signed integer types, unless the implementation defines signed integer overflow to wrap. (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 true
char16_t true
char32_t true
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
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
// Run this code
#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:
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 required to be false for signed integer types
See also
is_integer identifies integer types
[static]
is_iec559 identifies the IEC 559/IEEE 754 floating-point types
[static]
is_exact identifies exact types
[static]
