Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 08:27:16

0001 /* Overflow-safe math functions
0002  * Portable Snippets - https://github.com/nemequ/portable-snippets
0003  * Created by Evan Nemerson <evan@nemerson.com>
0004  *
0005  *   To the extent possible under law, the authors have waived all
0006  *   copyright and related or neighboring rights to this code.  For
0007  *   details, see the Creative Commons Zero 1.0 Universal license at
0008  *   https://creativecommons.org/publicdomain/zero/1.0/
0009  */
0010 
0011 #if !defined(PSNIP_SAFE_H)
0012 #define PSNIP_SAFE_H
0013 
0014 #if !defined(PSNIP_SAFE_FORCE_PORTABLE)
0015 #  if defined(__has_builtin)
0016 #    if __has_builtin(__builtin_add_overflow) && !defined(__ibmxl__)
0017 #      define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
0018 #    endif
0019 #  elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
0020 #    define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
0021 #  endif
0022 #  if defined(__has_include)
0023 #    if __has_include(<intsafe.h>)
0024 #      define PSNIP_SAFE_HAVE_INTSAFE_H
0025 #    endif
0026 #  elif defined(_WIN32)
0027 #    define PSNIP_SAFE_HAVE_INTSAFE_H
0028 #  endif
0029 #endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */
0030 
0031 #if defined(__GNUC__)
0032 #  define PSNIP_SAFE_LIKELY(expr)   __builtin_expect(!!(expr), 1)
0033 #  define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
0034 #else
0035 #  define PSNIP_SAFE_LIKELY(expr) !!(expr)
0036 #  define PSNIP_SAFE_UNLIKELY(expr) !!(expr)
0037 #endif /* defined(__GNUC__) */
0038 
0039 #if !defined(PSNIP_SAFE_STATIC_INLINE)
0040 #  if defined(__GNUC__)
0041 #    define PSNIP_SAFE__COMPILER_ATTRIBUTES __attribute__((__unused__))
0042 #  else
0043 #    define PSNIP_SAFE__COMPILER_ATTRIBUTES
0044 #  endif
0045 
0046 #  if defined(HEDLEY_INLINE)
0047 #    define PSNIP_SAFE__INLINE HEDLEY_INLINE
0048 #  elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
0049 #    define PSNIP_SAFE__INLINE inline
0050 #  elif defined(__GNUC_STDC_INLINE__)
0051 #    define PSNIP_SAFE__INLINE __inline__
0052 #  elif defined(_MSC_VER) && _MSC_VER >= 1200
0053 #    define PSNIP_SAFE__INLINE __inline
0054 #  else
0055 #    define PSNIP_SAFE__INLINE
0056 #  endif
0057 
0058 #  define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE
0059 #endif
0060 
0061 // !defined(__cplusplus) added for Solaris support
0062 #if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
0063 #  define psnip_safe_bool _Bool
0064 #else
0065 #  define psnip_safe_bool int
0066 #endif
0067 
0068 #if !defined(PSNIP_SAFE_NO_FIXED)
0069 /* For maximum portability include the exact-int module from
0070    portable snippets. */
0071 #  if \
0072     !defined(psnip_int64_t) || !defined(psnip_uint64_t) || \
0073     !defined(psnip_int32_t) || !defined(psnip_uint32_t) || \
0074     !defined(psnip_int16_t) || !defined(psnip_uint16_t) || \
0075     !defined(psnip_int8_t)  || !defined(psnip_uint8_t)
0076 #    include <stdint.h>
0077 #    if !defined(psnip_int64_t)
0078 #      define psnip_int64_t int64_t
0079 #    endif
0080 #    if !defined(psnip_uint64_t)
0081 #      define psnip_uint64_t uint64_t
0082 #    endif
0083 #    if !defined(psnip_int32_t)
0084 #      define psnip_int32_t int32_t
0085 #    endif
0086 #    if !defined(psnip_uint32_t)
0087 #      define psnip_uint32_t uint32_t
0088 #    endif
0089 #    if !defined(psnip_int16_t)
0090 #      define psnip_int16_t int16_t
0091 #    endif
0092 #    if !defined(psnip_uint16_t)
0093 #      define psnip_uint16_t uint16_t
0094 #    endif
0095 #    if !defined(psnip_int8_t)
0096 #      define psnip_int8_t int8_t
0097 #    endif
0098 #    if !defined(psnip_uint8_t)
0099 #      define psnip_uint8_t uint8_t
0100 #    endif
0101 #  endif
0102 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
0103 #include <limits.h>
0104 #include <stdlib.h>
0105 
0106 #if !defined(PSNIP_SAFE_SIZE_MAX)
0107 #  if defined(__SIZE_MAX__)
0108 #    define PSNIP_SAFE_SIZE_MAX __SIZE_MAX__
0109 #  elif defined(PSNIP_EXACT_INT_HAVE_STDINT)
0110 #    include <stdint.h>
0111 #  endif
0112 #endif
0113 
0114 #if defined(PSNIP_SAFE_SIZE_MAX)
0115 #  define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX
0116 #else
0117 #  define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0))
0118 #endif
0119 
0120 #if defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0121 /* In VS 10, stdint.h and intsafe.h both define (U)INTN_MIN/MAX, which
0122    triggers warning C4005 (level 1). */
0123 #  if defined(_MSC_VER) && (_MSC_VER == 1600)
0124 #    pragma warning(push)
0125 #    pragma warning(disable:4005)
0126 #  endif
0127 #  include <intsafe.h>
0128 #  if defined(_MSC_VER) && (_MSC_VER == 1600)
0129 #    pragma warning(pop)
0130 #  endif
0131 #endif /* defined(PSNIP_SAFE_HAVE_INTSAFE_H) */
0132 
0133 /* If there is a type larger than the one we're concerned with it's
0134  * likely much faster to simply promote the operands, perform the
0135  * requested operation, verify that the result falls within the
0136  * original type, then cast the result back to the original type. */
0137 
0138 #if !defined(PSNIP_SAFE_NO_PROMOTIONS)
0139 
0140 #define PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, op_name, op) \
0141   PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
0142   psnip_safe_larger_##name##_##op_name (T a, T b) { \
0143     return ((psnip_safe_##name##_larger) a) op ((psnip_safe_##name##_larger) b); \
0144   }
0145 
0146 #define PSNIP_SAFE_DEFINE_LARGER_UNARY_OP(T, name, op_name, op) \
0147   PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
0148   psnip_safe_larger_##name##_##op_name (T value) { \
0149     return (op ((psnip_safe_##name##_larger) value)); \
0150   }
0151 
0152 #define PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(T, name) \
0153   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
0154   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
0155   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
0156   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
0157   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) \
0158   PSNIP_SAFE_DEFINE_LARGER_UNARY_OP (T, name, neg, -)
0159 
0160 #define PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(T, name) \
0161   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
0162   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
0163   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
0164   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
0165   PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %)
0166 
0167 #define PSNIP_SAFE_IS_LARGER(ORIG_MAX, DEST_MAX) ((DEST_MAX / ORIG_MAX) >= ORIG_MAX)
0168 
0169 #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__SIZEOF_INT128__) && !defined(__ibmxl__)
0170 #define PSNIP_SAFE_HAVE_128
0171 typedef __int128  psnip_safe_int128_t;
0172 typedef unsigned __int128 psnip_safe_uint128_t;
0173 #endif /* defined(__GNUC__) */
0174 
0175 #if !defined(PSNIP_SAFE_NO_FIXED)
0176 #define PSNIP_SAFE_HAVE_INT8_LARGER
0177 #define PSNIP_SAFE_HAVE_UINT8_LARGER
0178 typedef psnip_int16_t  psnip_safe_int8_larger;
0179 typedef psnip_uint16_t psnip_safe_uint8_larger;
0180 
0181 #define PSNIP_SAFE_HAVE_INT16_LARGER
0182 typedef psnip_int32_t  psnip_safe_int16_larger;
0183 typedef psnip_uint32_t psnip_safe_uint16_larger;
0184 
0185 #define PSNIP_SAFE_HAVE_INT32_LARGER
0186 typedef psnip_int64_t  psnip_safe_int32_larger;
0187 typedef psnip_uint64_t psnip_safe_uint32_larger;
0188 
0189 #if defined(PSNIP_SAFE_HAVE_128)
0190 #define PSNIP_SAFE_HAVE_INT64_LARGER
0191 typedef psnip_safe_int128_t psnip_safe_int64_larger;
0192 typedef psnip_safe_uint128_t psnip_safe_uint64_larger;
0193 #endif /* defined(PSNIP_SAFE_HAVE_128) */
0194 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
0195 
0196 #define PSNIP_SAFE_HAVE_LARGER_SCHAR
0197 #if PSNIP_SAFE_IS_LARGER(SCHAR_MAX, SHRT_MAX)
0198 typedef short psnip_safe_schar_larger;
0199 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX)
0200 typedef int psnip_safe_schar_larger;
0201 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX)
0202 typedef long psnip_safe_schar_larger;
0203 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX)
0204 typedef long long psnip_safe_schar_larger;
0205 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff)
0206 typedef psnip_int16_t psnip_safe_schar_larger;
0207 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL)
0208 typedef psnip_int32_t psnip_safe_schar_larger;
0209 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL)
0210 typedef psnip_int64_t psnip_safe_schar_larger;
0211 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL)
0212 typedef psnip_safe_int128_t psnip_safe_schar_larger;
0213 #else
0214 #undef PSNIP_SAFE_HAVE_LARGER_SCHAR
0215 #endif
0216 
0217 #define PSNIP_SAFE_HAVE_LARGER_UCHAR
0218 #if PSNIP_SAFE_IS_LARGER(UCHAR_MAX, USHRT_MAX)
0219 typedef unsigned short psnip_safe_uchar_larger;
0220 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX)
0221 typedef unsigned int psnip_safe_uchar_larger;
0222 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX)
0223 typedef unsigned long psnip_safe_uchar_larger;
0224 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX)
0225 typedef unsigned long long psnip_safe_uchar_larger;
0226 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU)
0227 typedef psnip_uint16_t psnip_safe_uchar_larger;
0228 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL)
0229 typedef psnip_uint32_t psnip_safe_uchar_larger;
0230 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL)
0231 typedef psnip_uint64_t psnip_safe_uchar_larger;
0232 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL)
0233 typedef psnip_safe_uint128_t psnip_safe_uchar_larger;
0234 #else
0235 #undef PSNIP_SAFE_HAVE_LARGER_UCHAR
0236 #endif
0237 
0238 #if CHAR_MIN == 0 && defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
0239 #define PSNIP_SAFE_HAVE_LARGER_CHAR
0240 typedef psnip_safe_uchar_larger psnip_safe_char_larger;
0241 #elif CHAR_MIN < 0 && defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
0242 #define PSNIP_SAFE_HAVE_LARGER_CHAR
0243 typedef psnip_safe_schar_larger psnip_safe_char_larger;
0244 #endif
0245 
0246 #define PSNIP_SAFE_HAVE_LARGER_SHRT
0247 #if PSNIP_SAFE_IS_LARGER(SHRT_MAX, INT_MAX)
0248 typedef int psnip_safe_short_larger;
0249 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX)
0250 typedef long psnip_safe_short_larger;
0251 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX)
0252 typedef long long psnip_safe_short_larger;
0253 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff)
0254 typedef psnip_int16_t psnip_safe_short_larger;
0255 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL)
0256 typedef psnip_int32_t psnip_safe_short_larger;
0257 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL)
0258 typedef psnip_int64_t psnip_safe_short_larger;
0259 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL)
0260 typedef psnip_safe_int128_t psnip_safe_short_larger;
0261 #else
0262 #undef PSNIP_SAFE_HAVE_LARGER_SHRT
0263 #endif
0264 
0265 #define PSNIP_SAFE_HAVE_LARGER_USHRT
0266 #if PSNIP_SAFE_IS_LARGER(USHRT_MAX, UINT_MAX)
0267 typedef unsigned int psnip_safe_ushort_larger;
0268 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX)
0269 typedef unsigned long psnip_safe_ushort_larger;
0270 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX)
0271 typedef unsigned long long psnip_safe_ushort_larger;
0272 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff)
0273 typedef psnip_uint16_t psnip_safe_ushort_larger;
0274 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL)
0275 typedef psnip_uint32_t psnip_safe_ushort_larger;
0276 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL)
0277 typedef psnip_uint64_t psnip_safe_ushort_larger;
0278 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL)
0279 typedef psnip_safe_uint128_t psnip_safe_ushort_larger;
0280 #else
0281 #undef PSNIP_SAFE_HAVE_LARGER_USHRT
0282 #endif
0283 
0284 #define PSNIP_SAFE_HAVE_LARGER_INT
0285 #if PSNIP_SAFE_IS_LARGER(INT_MAX, LONG_MAX)
0286 typedef long psnip_safe_int_larger;
0287 #elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX)
0288 typedef long long psnip_safe_int_larger;
0289 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff)
0290 typedef psnip_int16_t psnip_safe_int_larger;
0291 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL)
0292 typedef psnip_int32_t psnip_safe_int_larger;
0293 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL)
0294 typedef psnip_int64_t psnip_safe_int_larger;
0295 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL)
0296 typedef psnip_safe_int128_t psnip_safe_int_larger;
0297 #else
0298 #undef PSNIP_SAFE_HAVE_LARGER_INT
0299 #endif
0300 
0301 #define PSNIP_SAFE_HAVE_LARGER_UINT
0302 #if PSNIP_SAFE_IS_LARGER(UINT_MAX, ULONG_MAX)
0303 typedef unsigned long psnip_safe_uint_larger;
0304 #elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX)
0305 typedef unsigned long long psnip_safe_uint_larger;
0306 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff)
0307 typedef psnip_uint16_t psnip_safe_uint_larger;
0308 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL)
0309 typedef psnip_uint32_t psnip_safe_uint_larger;
0310 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL)
0311 typedef psnip_uint64_t psnip_safe_uint_larger;
0312 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL)
0313 typedef psnip_safe_uint128_t psnip_safe_uint_larger;
0314 #else
0315 #undef PSNIP_SAFE_HAVE_LARGER_UINT
0316 #endif
0317 
0318 #define PSNIP_SAFE_HAVE_LARGER_LONG
0319 #if PSNIP_SAFE_IS_LARGER(LONG_MAX, LLONG_MAX)
0320 typedef long long psnip_safe_long_larger;
0321 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff)
0322 typedef psnip_int16_t psnip_safe_long_larger;
0323 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL)
0324 typedef psnip_int32_t psnip_safe_long_larger;
0325 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL)
0326 typedef psnip_int64_t psnip_safe_long_larger;
0327 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL)
0328 typedef psnip_safe_int128_t psnip_safe_long_larger;
0329 #else
0330 #undef PSNIP_SAFE_HAVE_LARGER_LONG
0331 #endif
0332 
0333 #define PSNIP_SAFE_HAVE_LARGER_ULONG
0334 #if PSNIP_SAFE_IS_LARGER(ULONG_MAX, ULLONG_MAX)
0335 typedef unsigned long long psnip_safe_ulong_larger;
0336 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff)
0337 typedef psnip_uint16_t psnip_safe_ulong_larger;
0338 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL)
0339 typedef psnip_uint32_t psnip_safe_ulong_larger;
0340 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL)
0341 typedef psnip_uint64_t psnip_safe_ulong_larger;
0342 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL)
0343 typedef psnip_safe_uint128_t psnip_safe_ulong_larger;
0344 #else
0345 #undef PSNIP_SAFE_HAVE_LARGER_ULONG
0346 #endif
0347 
0348 #define PSNIP_SAFE_HAVE_LARGER_LLONG
0349 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fff)
0350 typedef psnip_int16_t psnip_safe_llong_larger;
0351 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL)
0352 typedef psnip_int32_t psnip_safe_llong_larger;
0353 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL)
0354 typedef psnip_int64_t psnip_safe_llong_larger;
0355 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL)
0356 typedef psnip_safe_int128_t psnip_safe_llong_larger;
0357 #else
0358 #undef PSNIP_SAFE_HAVE_LARGER_LLONG
0359 #endif
0360 
0361 #define PSNIP_SAFE_HAVE_LARGER_ULLONG
0362 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffff)
0363 typedef psnip_uint16_t psnip_safe_ullong_larger;
0364 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL)
0365 typedef psnip_uint32_t psnip_safe_ullong_larger;
0366 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL)
0367 typedef psnip_uint64_t psnip_safe_ullong_larger;
0368 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL)
0369 typedef psnip_safe_uint128_t psnip_safe_ullong_larger;
0370 #else
0371 #undef PSNIP_SAFE_HAVE_LARGER_ULLONG
0372 #endif
0373 
0374 #if defined(PSNIP_SAFE_SIZE_MAX)
0375 #define PSNIP_SAFE_HAVE_LARGER_SIZE
0376 #if PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, USHRT_MAX)
0377 typedef unsigned short psnip_safe_size_larger;
0378 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX)
0379 typedef unsigned int psnip_safe_size_larger;
0380 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX)
0381 typedef unsigned long psnip_safe_size_larger;
0382 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX)
0383 typedef unsigned long long psnip_safe_size_larger;
0384 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff)
0385 typedef psnip_uint16_t psnip_safe_size_larger;
0386 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL)
0387 typedef psnip_uint32_t psnip_safe_size_larger;
0388 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL)
0389 typedef psnip_uint64_t psnip_safe_size_larger;
0390 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL)
0391 typedef psnip_safe_uint128_t psnip_safe_size_larger;
0392 #else
0393 #undef PSNIP_SAFE_HAVE_LARGER_SIZE
0394 #endif
0395 #endif
0396 
0397 #if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
0398 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar)
0399 #endif
0400 
0401 #if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
0402 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar)
0403 #endif
0404 
0405 #if defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
0406 #if CHAR_MIN == 0
0407 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char)
0408 #else
0409 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char)
0410 #endif
0411 #endif
0412 
0413 #if defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
0414 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short)
0415 #endif
0416 
0417 #if defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
0418 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort)
0419 #endif
0420 
0421 #if defined(PSNIP_SAFE_HAVE_LARGER_INT)
0422 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int)
0423 #endif
0424 
0425 #if defined(PSNIP_SAFE_HAVE_LARGER_UINT)
0426 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint)
0427 #endif
0428 
0429 #if defined(PSNIP_SAFE_HAVE_LARGER_LONG)
0430 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long)
0431 #endif
0432 
0433 #if defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
0434 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong)
0435 #endif
0436 
0437 #if defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
0438 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong)
0439 #endif
0440 
0441 #if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
0442 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong)
0443 #endif
0444 
0445 #if defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
0446 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size)
0447 #endif
0448 
0449 #if !defined(PSNIP_SAFE_NO_FIXED)
0450 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t,   int8)
0451 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t,  uint8)
0452 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t,  int16)
0453 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t, uint16)
0454 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t,  int32)
0455 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t, uint32)
0456 #if defined(PSNIP_SAFE_HAVE_128)
0457 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t,  int64)
0458 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint64_t, uint64)
0459 #endif
0460 #endif
0461 
0462 #endif /* !defined(PSNIP_SAFE_NO_PROMOTIONS) */
0463 
0464 #define PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(T, name, op_name) \
0465   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0466   psnip_safe_##name##_##op_name(T* res, T a, T b) { \
0467     return !__builtin_##op_name##_overflow(a, b, res); \
0468   }
0469 
0470 #define PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(T, name, op_name, min, max) \
0471   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0472   psnip_safe_##name##_##op_name(T* res, T a, T b) { \
0473     const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
0474     *res = (T) r; \
0475     return (r >= min) && (r <= max); \
0476   }
0477 
0478 #define PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(T, name, op_name, max) \
0479   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0480   psnip_safe_##name##_##op_name(T* res, T a, T b) { \
0481     const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
0482     *res = (T) r; \
0483     return (r <= max); \
0484   }
0485 
0486 #define PSNIP_SAFE_DEFINE_SIGNED_ADD(T, name, min, max) \
0487   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0488   psnip_safe_##name##_add (T* res, T a, T b) { \
0489     psnip_safe_bool r = !( ((b > 0) && (a > (max - b))) ||   \
0490                  ((b < 0) && (a < (min - b))) ); \
0491     if(PSNIP_SAFE_LIKELY(r)) \
0492         *res = a + b; \
0493     return r; \
0494   }
0495 
0496 #define PSNIP_SAFE_DEFINE_UNSIGNED_ADD(T, name, max) \
0497   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0498   psnip_safe_##name##_add (T* res, T a, T b) { \
0499     *res = (T) (a + b); \
0500     return !PSNIP_SAFE_UNLIKELY((b > 0) && (a > (max - b))); \
0501   }
0502 
0503 #define PSNIP_SAFE_DEFINE_SIGNED_SUB(T, name, min, max) \
0504   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0505   psnip_safe_##name##_sub (T* res, T a, T b) { \
0506       psnip_safe_bool r = !((b > 0 && a < (min + b)) || \
0507                   (b < 0 && a > (max + b))); \
0508       if(PSNIP_SAFE_LIKELY(r)) \
0509           *res = a - b; \
0510       return r; \
0511   }
0512 
0513 #define PSNIP_SAFE_DEFINE_UNSIGNED_SUB(T, name, max) \
0514   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0515   psnip_safe_##name##_sub (T* res, T a, T b) { \
0516       *res = a - b; \
0517       return !PSNIP_SAFE_UNLIKELY(b > a); \
0518   }
0519 
0520 #define PSNIP_SAFE_DEFINE_SIGNED_MUL(T, name, min, max) \
0521   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0522   psnip_safe_##name##_mul (T* res, T a, T b) { \
0523     psnip_safe_bool r = 1;  \
0524     if (a > 0) { \
0525       if (b > 0) { \
0526         if (a > (max / b)) { \
0527           r = 0; \
0528         } \
0529       } else { \
0530         if (b < (min / a)) { \
0531           r = 0; \
0532         } \
0533       } \
0534     } else { \
0535       if (b > 0) { \
0536         if (a < (min / b)) { \
0537           r = 0; \
0538         } \
0539       } else { \
0540         if ( (a != 0) && (b < (max / a))) { \
0541           r = 0; \
0542         } \
0543       } \
0544     } \
0545     if(PSNIP_SAFE_LIKELY(r)) \
0546         *res = a * b; \
0547     return r; \
0548   }
0549 
0550 #define PSNIP_SAFE_DEFINE_UNSIGNED_MUL(T, name, max) \
0551   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0552   psnip_safe_##name##_mul (T* res, T a, T b) { \
0553     *res = (T) (a * b); \
0554     return !PSNIP_SAFE_UNLIKELY((a > 0) && (b > 0) && (a > (max / b))); \
0555   }
0556 
0557 #define PSNIP_SAFE_DEFINE_SIGNED_DIV(T, name, min, max)   \
0558   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0559   psnip_safe_##name##_div (T* res, T a, T b) { \
0560     if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
0561       *res = 0; \
0562       return 0; \
0563     } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) {    \
0564       *res = min; \
0565       return 0; \
0566     } else { \
0567       *res = (T) (a / b); \
0568       return 1; \
0569     } \
0570   }
0571 
0572 #define PSNIP_SAFE_DEFINE_UNSIGNED_DIV(T, name, max) \
0573   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0574   psnip_safe_##name##_div (T* res, T a, T b) { \
0575     if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
0576       *res = 0; \
0577       return 0; \
0578     } else { \
0579       *res = a / b; \
0580       return 1; \
0581     } \
0582   }
0583 
0584 #define PSNIP_SAFE_DEFINE_SIGNED_MOD(T, name, min, max) \
0585   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0586   psnip_safe_##name##_mod (T* res, T a, T b) { \
0587     if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
0588       *res = 0; \
0589       return 0; \
0590     } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
0591       *res = min; \
0592       return 0; \
0593     } else { \
0594       *res = (T) (a % b); \
0595       return 1; \
0596     } \
0597   }
0598 
0599 #define PSNIP_SAFE_DEFINE_UNSIGNED_MOD(T, name, max) \
0600   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0601   psnip_safe_##name##_mod (T* res, T a, T b) { \
0602     if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
0603       *res = 0; \
0604       return 0; \
0605     } else { \
0606       *res = a % b; \
0607       return 1; \
0608     } \
0609   }
0610 
0611 #define PSNIP_SAFE_DEFINE_SIGNED_NEG(T, name, min, max) \
0612   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0613   psnip_safe_##name##_neg (T* res, T value) { \
0614     psnip_safe_bool r = value != min; \
0615     *res = PSNIP_SAFE_LIKELY(r) ? -value : max; \
0616     return r; \
0617   }
0618 
0619 #define PSNIP_SAFE_DEFINE_INTSAFE(T, name, op, isf) \
0620   PSNIP_SAFE__FUNCTION psnip_safe_bool \
0621   psnip_safe_##name##_##op (T* res, T a, T b) { \
0622     return isf(a, b, res) == S_OK; \
0623   }
0624 
0625 #if CHAR_MIN == 0
0626 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0627 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
0628 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
0629 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
0630 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
0631 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add, CHAR_MAX)
0632 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub, CHAR_MAX)
0633 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul, CHAR_MAX)
0634 #else
0635 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX)
0636 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX)
0637 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX)
0638 #endif
0639 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX)
0640 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX)
0641 #else /* CHAR_MIN != 0 */
0642 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0643 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
0644 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
0645 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
0646 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
0647 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add, CHAR_MIN, CHAR_MAX)
0648 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub, CHAR_MIN, CHAR_MAX)
0649 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul, CHAR_MIN, CHAR_MAX)
0650 #else
0651 PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN, CHAR_MAX)
0652 PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN, CHAR_MAX)
0653 PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN, CHAR_MAX)
0654 #endif
0655 PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN, CHAR_MAX)
0656 PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN, CHAR_MAX)
0657 PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN, CHAR_MAX)
0658 #endif
0659 
0660 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0661 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, add)
0662 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, sub)
0663 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, mul)
0664 #elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
0665 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, add, SCHAR_MIN, SCHAR_MAX)
0666 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, sub, SCHAR_MIN, SCHAR_MAX)
0667 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, mul, SCHAR_MIN, SCHAR_MAX)
0668 #else
0669 PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0670 PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0671 PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0672 #endif
0673 PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0674 PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0675 PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar, SCHAR_MIN, SCHAR_MAX)
0676 
0677 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0678 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, add)
0679 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, sub)
0680 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, mul)
0681 #elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
0682 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, add, UCHAR_MAX)
0683 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, sub, UCHAR_MAX)
0684 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, mul, UCHAR_MAX)
0685 #else
0686 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar, UCHAR_MAX)
0687 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar, UCHAR_MAX)
0688 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar, UCHAR_MAX)
0689 #endif
0690 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar, UCHAR_MAX)
0691 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar, UCHAR_MAX)
0692 
0693 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0694 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add)
0695 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub)
0696 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul)
0697 #elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
0698 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add, SHRT_MIN, SHRT_MAX)
0699 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub, SHRT_MIN, SHRT_MAX)
0700 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul, SHRT_MIN, SHRT_MAX)
0701 #else
0702 PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN, SHRT_MAX)
0703 PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN, SHRT_MAX)
0704 PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN, SHRT_MAX)
0705 #endif
0706 PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN, SHRT_MAX)
0707 PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN, SHRT_MAX)
0708 PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN, SHRT_MAX)
0709 
0710 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0711 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, add)
0712 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, sub)
0713 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, mul)
0714 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0715 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, add, UShortAdd)
0716 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, sub, UShortSub)
0717 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, mul, UShortMult)
0718 #elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
0719 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, add, USHRT_MAX)
0720 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, sub, USHRT_MAX)
0721 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, mul, USHRT_MAX)
0722 #else
0723 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort, USHRT_MAX)
0724 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort, USHRT_MAX)
0725 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort, USHRT_MAX)
0726 #endif
0727 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort, USHRT_MAX)
0728 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort, USHRT_MAX)
0729 
0730 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0731 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add)
0732 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub)
0733 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul)
0734 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT)
0735 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add, INT_MIN, INT_MAX)
0736 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub, INT_MIN, INT_MAX)
0737 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul, INT_MIN, INT_MAX)
0738 #else
0739 PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN, INT_MAX)
0740 PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN, INT_MAX)
0741 PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN, INT_MAX)
0742 #endif
0743 PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN, INT_MAX)
0744 PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN, INT_MAX)
0745 PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN, INT_MAX)
0746 
0747 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0748 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, add)
0749 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, sub)
0750 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, mul)
0751 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0752 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, add, UIntAdd)
0753 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, sub, UIntSub)
0754 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, mul, UIntMult)
0755 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT)
0756 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, add, UINT_MAX)
0757 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, sub, UINT_MAX)
0758 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, mul, UINT_MAX)
0759 #else
0760 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint, UINT_MAX)
0761 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint, UINT_MAX)
0762 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint, UINT_MAX)
0763 #endif
0764 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint, UINT_MAX)
0765 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint, UINT_MAX)
0766 
0767 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0768 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add)
0769 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub)
0770 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul)
0771 #elif defined(PSNIP_SAFE_HAVE_LARGER_LONG)
0772 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add, LONG_MIN, LONG_MAX)
0773 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub, LONG_MIN, LONG_MAX)
0774 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul, LONG_MIN, LONG_MAX)
0775 #else
0776 PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN, LONG_MAX)
0777 PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN, LONG_MAX)
0778 PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN, LONG_MAX)
0779 #endif
0780 PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN, LONG_MAX)
0781 PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN, LONG_MAX)
0782 PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN, LONG_MAX)
0783 
0784 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0785 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, add)
0786 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, sub)
0787 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, mul)
0788 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0789 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, add, ULongAdd)
0790 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, sub, ULongSub)
0791 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, mul, ULongMult)
0792 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
0793 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, add, ULONG_MAX)
0794 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, sub, ULONG_MAX)
0795 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, mul, ULONG_MAX)
0796 #else
0797 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong, ULONG_MAX)
0798 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong, ULONG_MAX)
0799 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong, ULONG_MAX)
0800 #endif
0801 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong, ULONG_MAX)
0802 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong, ULONG_MAX)
0803 
0804 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0805 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, add)
0806 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, sub)
0807 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, mul)
0808 #elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
0809 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, add, LLONG_MIN, LLONG_MAX)
0810 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, sub, LLONG_MIN, LLONG_MAX)
0811 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, mul, LLONG_MIN, LLONG_MAX)
0812 #else
0813 PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong, LLONG_MIN, LLONG_MAX)
0814 PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong, LLONG_MIN, LLONG_MAX)
0815 PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong, LLONG_MIN, LLONG_MAX)
0816 #endif
0817 PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong, LLONG_MIN, LLONG_MAX)
0818 PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong, LLONG_MIN, LLONG_MAX)
0819 PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong, LLONG_MIN, LLONG_MAX)
0820 
0821 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0822 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, add)
0823 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, sub)
0824 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, mul)
0825 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0826 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, add, ULongLongAdd)
0827 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, sub, ULongLongSub)
0828 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, mul, ULongLongMult)
0829 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
0830 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, add, ULLONG_MAX)
0831 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, sub, ULLONG_MAX)
0832 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, mul, ULLONG_MAX)
0833 #else
0834 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong, ULLONG_MAX)
0835 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong, ULLONG_MAX)
0836 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong, ULLONG_MAX)
0837 #endif
0838 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong, ULLONG_MAX)
0839 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong, ULLONG_MAX)
0840 
0841 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0842 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, add)
0843 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, sub)
0844 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, mul)
0845 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
0846 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, add, SizeTAdd)
0847 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, sub, SizeTSub)
0848 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, mul, SizeTMult)
0849 #elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
0850 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, add, PSNIP_SAFE__SIZE_MAX_RT)
0851 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, sub, PSNIP_SAFE__SIZE_MAX_RT)
0852 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, mul, PSNIP_SAFE__SIZE_MAX_RT)
0853 #else
0854 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
0855 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
0856 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
0857 #endif
0858 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
0859 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
0860 
0861 #if !defined(PSNIP_SAFE_NO_FIXED)
0862 
0863 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0864 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, add)
0865 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, sub)
0866 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, mul)
0867 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT8)
0868 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, add, (-0x7fLL-1), 0x7f)
0869 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, sub, (-0x7fLL-1), 0x7f)
0870 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, mul, (-0x7fLL-1), 0x7f)
0871 #else
0872 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0873 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0874 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0875 #endif
0876 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0877 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0878 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
0879 
0880 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0881 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, add)
0882 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, sub)
0883 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, mul)
0884 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8)
0885 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, add, 0xff)
0886 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, sub, 0xff)
0887 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, mul, 0xff)
0888 #else
0889 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t, uint8, 0xff)
0890 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t, uint8, 0xff)
0891 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t, uint8, 0xff)
0892 #endif
0893 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t, uint8, 0xff)
0894 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t, uint8, 0xff)
0895 
0896 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0897 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, add)
0898 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, sub)
0899 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, mul)
0900 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT16)
0901 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, add, (-32767-1), 0x7fff)
0902 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, sub, (-32767-1), 0x7fff)
0903 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, mul, (-32767-1), 0x7fff)
0904 #else
0905 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t, int16, (-32767-1), 0x7fff)
0906 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t, int16, (-32767-1), 0x7fff)
0907 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t, int16, (-32767-1), 0x7fff)
0908 #endif
0909 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t, int16, (-32767-1), 0x7fff)
0910 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t, int16, (-32767-1), 0x7fff)
0911 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t, int16, (-32767-1), 0x7fff)
0912 
0913 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0914 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, add)
0915 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, sub)
0916 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, mul)
0917 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
0918 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, add, UShortAdd)
0919 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, sub, UShortSub)
0920 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, mul, UShortMult)
0921 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16)
0922 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, add, 0xffff)
0923 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, sub, 0xffff)
0924 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, mul, 0xffff)
0925 #else
0926 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t, uint16, 0xffff)
0927 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t, uint16, 0xffff)
0928 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t, uint16, 0xffff)
0929 #endif
0930 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t, uint16, 0xffff)
0931 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t, uint16, 0xffff)
0932 
0933 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0934 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, add)
0935 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, sub)
0936 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, mul)
0937 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT32)
0938 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, add, (-0x7fffffffLL-1), 0x7fffffffLL)
0939 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, sub, (-0x7fffffffLL-1), 0x7fffffffLL)
0940 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, mul, (-0x7fffffffLL-1), 0x7fffffffLL)
0941 #else
0942 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0943 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0944 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0945 #endif
0946 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0947 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0948 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
0949 
0950 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0951 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, add)
0952 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, sub)
0953 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, mul)
0954 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
0955 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, add, UIntAdd)
0956 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, sub, UIntSub)
0957 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, mul, UIntMult)
0958 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32)
0959 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, add, 0xffffffffUL)
0960 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, sub, 0xffffffffUL)
0961 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, mul, 0xffffffffUL)
0962 #else
0963 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t, uint32, 0xffffffffUL)
0964 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t, uint32, 0xffffffffUL)
0965 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t, uint32, 0xffffffffUL)
0966 #endif
0967 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t, uint32, 0xffffffffUL)
0968 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t, uint32, 0xffffffffUL)
0969 
0970 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0971 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, add)
0972 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, sub)
0973 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, mul)
0974 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT64)
0975 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, add, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0976 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, sub, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0977 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, mul, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0978 #else
0979 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0980 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0981 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0982 #endif
0983 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0984 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0985 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
0986 
0987 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
0988 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, add)
0989 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, sub)
0990 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, mul)
0991 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
0992 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, add, ULongLongAdd)
0993 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, sub, ULongLongSub)
0994 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, mul, ULongLongMult)
0995 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64)
0996 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, add, 0xffffffffffffffffULL)
0997 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, sub, 0xffffffffffffffffULL)
0998 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, mul, 0xffffffffffffffffULL)
0999 #else
1000 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1001 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1002 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1003 #endif
1004 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1005 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1006 
1007 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
1008 
1009 #define PSNIP_SAFE_C11_GENERIC_SELECTION(res, op) \
1010   _Generic((*res), \
1011        char: psnip_safe_char_##op, \
1012        unsigned char: psnip_safe_uchar_##op, \
1013        short: psnip_safe_short_##op, \
1014        unsigned short: psnip_safe_ushort_##op, \
1015        int: psnip_safe_int_##op, \
1016        unsigned int: psnip_safe_uint_##op, \
1017        long: psnip_safe_long_##op, \
1018        unsigned long: psnip_safe_ulong_##op, \
1019        long long: psnip_safe_llong_##op, \
1020        unsigned long long: psnip_safe_ullong_##op)
1021 
1022 #define PSNIP_SAFE_C11_GENERIC_BINARY_OP(op, res, a, b) \
1023   PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, a, b)
1024 #define PSNIP_SAFE_C11_GENERIC_UNARY_OP(op, res, v) \
1025   PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, v)
1026 
1027 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
1028 #define psnip_safe_add(res, a, b) !__builtin_add_overflow(a, b, res)
1029 #define psnip_safe_sub(res, a, b) !__builtin_sub_overflow(a, b, res)
1030 #define psnip_safe_mul(res, a, b) !__builtin_mul_overflow(a, b, res)
1031 #define psnip_safe_div(res, a, b) !__builtin_div_overflow(a, b, res)
1032 #define psnip_safe_mod(res, a, b) !__builtin_mod_overflow(a, b, res)
1033 #define psnip_safe_neg(res, v)    PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1034 
1035 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
1036 /* The are no fixed-length or size selections because they cause an
1037  * error about _Generic specifying two compatible types.  Hopefully
1038  * this doesn't cause problems on exotic platforms, but if it does
1039  * please let me know and I'll try to figure something out. */
1040 
1041 #define psnip_safe_add(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(add, res, a, b)
1042 #define psnip_safe_sub(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(sub, res, a, b)
1043 #define psnip_safe_mul(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mul, res, a, b)
1044 #define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b)
1045 #define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b)
1046 #define psnip_safe_neg(res, v)    PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1047 #endif
1048 
1049 #if !defined(PSNIP_SAFE_HAVE_BUILTINS) && (defined(PSNIP_SAFE_EMULATE_NATIVE) || defined(PSNIP_BUILTIN_EMULATE_NATIVE))
1050 #  define __builtin_sadd_overflow(a, b, res)   (!psnip_safe_int_add(res, a, b))
1051 #  define __builtin_saddl_overflow(a, b, res)  (!psnip_safe_long_add(res, a, b))
1052 #  define __builtin_saddll_overflow(a, b, res) (!psnip_safe_llong_add(res, a, b))
1053 #  define __builtin_uadd_overflow(a, b, res)   (!psnip_safe_uint_add(res, a, b))
1054 #  define __builtin_uaddl_overflow(a, b, res)  (!psnip_safe_ulong_add(res, a, b))
1055 #  define __builtin_uaddll_overflow(a, b, res) (!psnip_safe_ullong_add(res, a, b))
1056 
1057 #  define __builtin_ssub_overflow(a, b, res)   (!psnip_safe_int_sub(res, a, b))
1058 #  define __builtin_ssubl_overflow(a, b, res)  (!psnip_safe_long_sub(res, a, b))
1059 #  define __builtin_ssubll_overflow(a, b, res) (!psnip_safe_llong_sub(res, a, b))
1060 #  define __builtin_usub_overflow(a, b, res)   (!psnip_safe_uint_sub(res, a, b))
1061 #  define __builtin_usubl_overflow(a, b, res)  (!psnip_safe_ulong_sub(res, a, b))
1062 #  define __builtin_usubll_overflow(a, b, res) (!psnip_safe_ullong_sub(res, a, b))
1063 
1064 #  define __builtin_smul_overflow(a, b, res)   (!psnip_safe_int_mul(res, a, b))
1065 #  define __builtin_smull_overflow(a, b, res)  (!psnip_safe_long_mul(res, a, b))
1066 #  define __builtin_smulll_overflow(a, b, res) (!psnip_safe_llong_mul(res, a, b))
1067 #  define __builtin_umul_overflow(a, b, res)   (!psnip_safe_uint_mul(res, a, b))
1068 #  define __builtin_umull_overflow(a, b, res)  (!psnip_safe_ulong_mul(res, a, b))
1069 #  define __builtin_umulll_overflow(a, b, res) (!psnip_safe_ullong_mul(res, a, b))
1070 #endif
1071 
1072 #endif /* !defined(PSNIP_SAFE_H) */