Here’s a macro I came up with today using the C11 _Generic
feature that I’m quite pleased with:
#define TYPE_MAX(x) \ _Generic((x), \ uint64_t: UINT64_MAX, \ int64_t: INT64_MAX, \ uint32_t: UINT32_MAX, \ int32_t: INT32_MAX, \ uint16_t: UINT16_MAX, \ int16_t: INT16_MAX, \ uint8_t: UINT8_MAX, \ int8_t: INT8_MAX) #define saturate_add(a, b) ({ \ typeof((a)) __tmp; \ if (__builtin_add_overflow((a), (b), &__tmp)) \ __tmp = TYPE_MAX(__tmp); \ __tmp; \ })
It does a saturating addition on any integer type taking into account that signed and unsigned types of the same size have different maximum values. For signed types it doesn’t handle the case where b
is negative however.