10 #if __cpp_lib_saturation_arithmetic >= 202311L
18 #else // __cpp_lib_saturation_arithmetic
30 static_assert(std::is_integral<T>::value,
"Saturating arithmetic is only allowed on integral types");
31 static_assert(std::is_unsigned<T>::value,
"Saturating arithmetic is not tested for signed types");
33 constexpr T maximum = std::numeric_limits<T>::max();
34 constexpr T minimum = std::numeric_limits<T>::min();
36 if constexpr(std::is_unsigned<T>::value)
38 return ((x + y) >= x) ? (x + y) : maximum;
45 return (maximum - x <= y) ? (x+y) : maximum;
54 return (minimum - x <= y) ? (x+y) : minimum;
64 static_assert(std::is_integral<T>::value,
"Saturating arithmetic is only allowed on integral types");
65 static_assert(std::is_unsigned<T>::value,
"Saturating arithmetic is not tested for signed types");
67 constexpr T maximum = std::numeric_limits<T>::max();
68 constexpr T minimum = std::numeric_limits<T>::min();
70 if constexpr(std::is_unsigned<T>::value)
72 return (x > y) ? (x-y) : 0u;
81 return (-y >= maximum - x) ? (x - y) : maximum;
86 return (y <= minimum - x) ? (x - y) : minimum;
105 template<
class T,
class U>
108 static_assert(std::is_integral<T>::value,
"T must be an integral type");
109 static_assert(std::is_integral<U>::value,
"U must be an integral type");
122 if constexpr(std::is_signed<T>::value == std::is_signed<U>::value)
125 if constexpr(std::numeric_limits<T>::digits >= std::numeric_limits<U>::digits)
129 constexpr T minimum = std::numeric_limits<T>::min();
130 constexpr T maximum = std::numeric_limits<T>::max();
132 if(x >
static_cast<U
>(maximum))
136 if constexpr(std::is_signed<U>::value)
138 if(x <
static_cast<U
>(minimum))
146 else if constexpr(std::is_unsigned<T>::value)
148 static_assert(std::is_signed<U>::value);
149 using unsigned_U =
typename std::make_unsigned<U>::type;
151 constexpr T maximum = std::numeric_limits<T>::max();
158 else if(
static_cast<unsigned_U
>(x) > maximum)
165 static_assert(std::is_signed<T>::value);
166 static_assert(std::is_unsigned<U>::value);
168 using unsigned_T =
typename std::make_unsigned<T>::type;
171 constexpr unsigned_T maximum = std::numeric_limits<T>::max();
182 #endif // __cpp_lib_saturation_arithmetic
193 template<
class T,
class U>
196 destination = saturate_cast<T>(value);
209 template<
class T,
class U>
212 return counter = add_sat<T>(counter, amount);
225 template<
class T,
class U>
228 return counter = sub_sat<T>(counter, amount);
240 static_assert(std::is_integral<T>::value(),
"SaturatingInteger type must be integral");
245 operator T()
const {
return m_value; }
247 SaturatingInt& operator++() {
if(m_value < std::numeric_limits<T>::max()) ++m_value;
return *
this; }
250 SaturatingInt& operator--() {
if(m_value > std::numeric_limits<T>::min()) --m_value;
return *
this; }