1 /* Overflow-safe math functions
2 * Portable Snippets - https://github.com/nemequ/portable-snippets
3 * Created by Evan Nemerson <evan@nemerson.com>
5 * To the extent possible under law, the authors have waived all
6 * copyright and related or neighboring rights to this code. For
7 * details, see the Creative Commons Zero 1.0 Universal license at
8 * https://creativecommons.org/publicdomain/zero/1.0/
11 #if !defined(PSNIP_SAFE_H)
14 #if !defined(PSNIP_SAFE_FORCE_PORTABLE)
15 # if defined(__has_builtin)
16 # if __has_builtin(__builtin_add_overflow) && !defined(__ibmxl__)
17 # define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
19 # elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
20 # define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
22 # if defined(__has_include)
23 # if __has_include(<intsafe.h>)
24 # define PSNIP_SAFE_HAVE_INTSAFE_H
26 # elif defined(_WIN32)
27 # define PSNIP_SAFE_HAVE_INTSAFE_H
29 #endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */
32 # define PSNIP_SAFE_LIKELY(expr) __builtin_expect(!!(expr), 1)
33 # define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
35 # define PSNIP_SAFE_LIKELY(expr) !!(expr)
36 # define PSNIP_SAFE_UNLIKELY(expr) !!(expr)
37 #endif /* defined(__GNUC__) */
39 #if !defined(PSNIP_SAFE_STATIC_INLINE)
40 # if defined(__GNUC__)
41 # define PSNIP_SAFE__COMPILER_ATTRIBUTES __attribute__((__unused__))
43 # define PSNIP_SAFE__COMPILER_ATTRIBUTES
46 # if defined(HEDLEY_INLINE)
47 # define PSNIP_SAFE__INLINE HEDLEY_INLINE
48 # elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
49 # define PSNIP_SAFE__INLINE inline
50 # elif defined(__GNUC_STDC_INLINE__)
51 # define PSNIP_SAFE__INLINE __inline__
52 # elif defined(_MSC_VER) && _MSC_VER >= 1200
53 # define PSNIP_SAFE__INLINE __inline
55 # define PSNIP_SAFE__INLINE
58 # define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE
61 #if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
62 # define psnip_safe_bool _Bool
64 # define psnip_safe_bool int
67 #if !defined(PSNIP_SAFE_NO_FIXED)
68 /* For maximum portability include the exact-int module from
71 !defined(psnip_int64_t) || !defined(psnip_uint64_t) || \
72 !defined(psnip_int32_t) || !defined(psnip_uint32_t) || \
73 !defined(psnip_int16_t) || !defined(psnip_uint16_t) || \
74 !defined(psnip_int8_t) || !defined(psnip_uint8_t)
76 # if !defined(psnip_int64_t)
77 # define psnip_int64_t int64_t
79 # if !defined(psnip_uint64_t)
80 # define psnip_uint64_t uint64_t
82 # if !defined(psnip_int32_t)
83 # define psnip_int32_t int32_t
85 # if !defined(psnip_uint32_t)
86 # define psnip_uint32_t uint32_t
88 # if !defined(psnip_int16_t)
89 # define psnip_int16_t int16_t
91 # if !defined(psnip_uint16_t)
92 # define psnip_uint16_t uint16_t
94 # if !defined(psnip_int8_t)
95 # define psnip_int8_t int8_t
97 # if !defined(psnip_uint8_t)
98 # define psnip_uint8_t uint8_t
101 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
105 #if !defined(PSNIP_SAFE_SIZE_MAX)
106 # if defined(__SIZE_MAX__)
107 # define PSNIP_SAFE_SIZE_MAX __SIZE_MAX__
108 # elif defined(PSNIP_EXACT_INT_HAVE_STDINT)
113 #if defined(PSNIP_SAFE_SIZE_MAX)
114 # define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX
116 # define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0))
119 #if defined(PSNIP_SAFE_HAVE_INTSAFE_H)
120 /* In VS 10, stdint.h and intsafe.h both define (U)INTN_MIN/MAX, which
121 triggers warning C4005 (level 1). */
122 # if defined(_MSC_VER) && (_MSC_VER == 1600)
123 # pragma warning(push)
124 # pragma warning(disable:4005)
126 # include <intsafe.h>
127 # if defined(_MSC_VER) && (_MSC_VER == 1600)
128 # pragma warning(pop)
130 #endif /* defined(PSNIP_SAFE_HAVE_INTSAFE_H) */
132 /* If there is a type larger than the one we're concerned with it's
133 * likely much faster to simply promote the operands, perform the
134 * requested operation, verify that the result falls within the
135 * original type, then cast the result back to the original type. */
137 #if !defined(PSNIP_SAFE_NO_PROMOTIONS)
139 #define PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, op_name, op) \
140 PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
141 psnip_safe_larger_##name##_##op_name (T a, T b) { \
142 return ((psnip_safe_##name##_larger) a) op ((psnip_safe_##name##_larger) b); \
145 #define PSNIP_SAFE_DEFINE_LARGER_UNARY_OP(T, name, op_name, op) \
146 PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
147 psnip_safe_larger_##name##_##op_name (T value) { \
148 return (op ((psnip_safe_##name##_larger) value)); \
151 #define PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(T, name) \
152 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
153 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
154 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
155 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
156 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) \
157 PSNIP_SAFE_DEFINE_LARGER_UNARY_OP (T, name, neg, -)
159 #define PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(T, name) \
160 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
161 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
162 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
163 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
164 PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %)
166 #define PSNIP_SAFE_IS_LARGER(ORIG_MAX, DEST_MAX) ((DEST_MAX / ORIG_MAX) >= ORIG_MAX)
168 #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__SIZEOF_INT128__) && !defined(__ibmxl__)
169 #define PSNIP_SAFE_HAVE_128
170 typedef __int128 psnip_safe_int128_t
;
171 typedef unsigned __int128 psnip_safe_uint128_t
;
172 #endif /* defined(__GNUC__) */
174 #if !defined(PSNIP_SAFE_NO_FIXED)
175 #define PSNIP_SAFE_HAVE_INT8_LARGER
176 #define PSNIP_SAFE_HAVE_UINT8_LARGER
177 typedef psnip_int16_t psnip_safe_int8_larger
;
178 typedef psnip_uint16_t psnip_safe_uint8_larger
;
180 #define PSNIP_SAFE_HAVE_INT16_LARGER
181 typedef psnip_int32_t psnip_safe_int16_larger
;
182 typedef psnip_uint32_t psnip_safe_uint16_larger
;
184 #define PSNIP_SAFE_HAVE_INT32_LARGER
185 typedef psnip_int64_t psnip_safe_int32_larger
;
186 typedef psnip_uint64_t psnip_safe_uint32_larger
;
188 #if defined(PSNIP_SAFE_HAVE_128)
189 #define PSNIP_SAFE_HAVE_INT64_LARGER
190 typedef psnip_safe_int128_t psnip_safe_int64_larger
;
191 typedef psnip_safe_uint128_t psnip_safe_uint64_larger
;
192 #endif /* defined(PSNIP_SAFE_HAVE_128) */
193 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
195 #define PSNIP_SAFE_HAVE_LARGER_SCHAR
196 #if PSNIP_SAFE_IS_LARGER(SCHAR_MAX, SHRT_MAX)
197 typedef short psnip_safe_schar_larger
;
198 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX)
199 typedef int psnip_safe_schar_larger
;
200 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX)
201 typedef long psnip_safe_schar_larger
;
202 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX)
203 typedef long long psnip_safe_schar_larger
;
204 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff)
205 typedef psnip_int16_t psnip_safe_schar_larger
;
206 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL)
207 typedef psnip_int32_t psnip_safe_schar_larger
;
208 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL)
209 typedef psnip_int64_t psnip_safe_schar_larger
;
210 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL)
211 typedef psnip_safe_int128_t psnip_safe_schar_larger
;
213 #undef PSNIP_SAFE_HAVE_LARGER_SCHAR
216 #define PSNIP_SAFE_HAVE_LARGER_UCHAR
217 #if PSNIP_SAFE_IS_LARGER(UCHAR_MAX, USHRT_MAX)
218 typedef unsigned short psnip_safe_uchar_larger
;
219 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX)
220 typedef unsigned int psnip_safe_uchar_larger
;
221 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX)
222 typedef unsigned long psnip_safe_uchar_larger
;
223 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX)
224 typedef unsigned long long psnip_safe_uchar_larger
;
225 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU)
226 typedef psnip_uint16_t psnip_safe_uchar_larger
;
227 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL)
228 typedef psnip_uint32_t psnip_safe_uchar_larger
;
229 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL)
230 typedef psnip_uint64_t psnip_safe_uchar_larger
;
231 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL)
232 typedef psnip_safe_uint128_t psnip_safe_uchar_larger
;
234 #undef PSNIP_SAFE_HAVE_LARGER_UCHAR
237 #if CHAR_MIN == 0 && defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
238 #define PSNIP_SAFE_HAVE_LARGER_CHAR
239 typedef psnip_safe_uchar_larger psnip_safe_char_larger
;
240 #elif CHAR_MIN < 0 && defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
241 #define PSNIP_SAFE_HAVE_LARGER_CHAR
242 typedef psnip_safe_schar_larger psnip_safe_char_larger
;
245 #define PSNIP_SAFE_HAVE_LARGER_SHRT
246 #if PSNIP_SAFE_IS_LARGER(SHRT_MAX, INT_MAX)
247 typedef int psnip_safe_short_larger
;
248 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX)
249 typedef long psnip_safe_short_larger
;
250 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX)
251 typedef long long psnip_safe_short_larger
;
252 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff)
253 typedef psnip_int16_t psnip_safe_short_larger
;
254 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL)
255 typedef psnip_int32_t psnip_safe_short_larger
;
256 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL)
257 typedef psnip_int64_t psnip_safe_short_larger
;
258 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL)
259 typedef psnip_safe_int128_t psnip_safe_short_larger
;
261 #undef PSNIP_SAFE_HAVE_LARGER_SHRT
264 #define PSNIP_SAFE_HAVE_LARGER_USHRT
265 #if PSNIP_SAFE_IS_LARGER(USHRT_MAX, UINT_MAX)
266 typedef unsigned int psnip_safe_ushort_larger
;
267 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX)
268 typedef unsigned long psnip_safe_ushort_larger
;
269 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX)
270 typedef unsigned long long psnip_safe_ushort_larger
;
271 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff)
272 typedef psnip_uint16_t psnip_safe_ushort_larger
;
273 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL)
274 typedef psnip_uint32_t psnip_safe_ushort_larger
;
275 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL)
276 typedef psnip_uint64_t psnip_safe_ushort_larger
;
277 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL)
278 typedef psnip_safe_uint128_t psnip_safe_ushort_larger
;
280 #undef PSNIP_SAFE_HAVE_LARGER_USHRT
283 #define PSNIP_SAFE_HAVE_LARGER_INT
284 #if PSNIP_SAFE_IS_LARGER(INT_MAX, LONG_MAX)
285 typedef long psnip_safe_int_larger
;
286 #elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX)
287 typedef long long psnip_safe_int_larger
;
288 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff)
289 typedef psnip_int16_t psnip_safe_int_larger
;
290 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL)
291 typedef psnip_int32_t psnip_safe_int_larger
;
292 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL)
293 typedef psnip_int64_t psnip_safe_int_larger
;
294 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL)
295 typedef psnip_safe_int128_t psnip_safe_int_larger
;
297 #undef PSNIP_SAFE_HAVE_LARGER_INT
300 #define PSNIP_SAFE_HAVE_LARGER_UINT
301 #if PSNIP_SAFE_IS_LARGER(UINT_MAX, ULONG_MAX)
302 typedef unsigned long psnip_safe_uint_larger
;
303 #elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX)
304 typedef unsigned long long psnip_safe_uint_larger
;
305 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff)
306 typedef psnip_uint16_t psnip_safe_uint_larger
;
307 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL)
308 typedef psnip_uint32_t psnip_safe_uint_larger
;
309 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL)
310 typedef psnip_uint64_t psnip_safe_uint_larger
;
311 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL)
312 typedef psnip_safe_uint128_t psnip_safe_uint_larger
;
314 #undef PSNIP_SAFE_HAVE_LARGER_UINT
317 #define PSNIP_SAFE_HAVE_LARGER_LONG
318 #if PSNIP_SAFE_IS_LARGER(LONG_MAX, LLONG_MAX)
319 typedef long long psnip_safe_long_larger
;
320 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff)
321 typedef psnip_int16_t psnip_safe_long_larger
;
322 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL)
323 typedef psnip_int32_t psnip_safe_long_larger
;
324 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL)
325 typedef psnip_int64_t psnip_safe_long_larger
;
326 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL)
327 typedef psnip_safe_int128_t psnip_safe_long_larger
;
329 #undef PSNIP_SAFE_HAVE_LARGER_LONG
332 #define PSNIP_SAFE_HAVE_LARGER_ULONG
333 #if PSNIP_SAFE_IS_LARGER(ULONG_MAX, ULLONG_MAX)
334 typedef unsigned long long psnip_safe_ulong_larger
;
335 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff)
336 typedef psnip_uint16_t psnip_safe_ulong_larger
;
337 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL)
338 typedef psnip_uint32_t psnip_safe_ulong_larger
;
339 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL)
340 typedef psnip_uint64_t psnip_safe_ulong_larger
;
341 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL)
342 typedef psnip_safe_uint128_t psnip_safe_ulong_larger
;
344 #undef PSNIP_SAFE_HAVE_LARGER_ULONG
347 #define PSNIP_SAFE_HAVE_LARGER_LLONG
348 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fff)
349 typedef psnip_int16_t psnip_safe_llong_larger
;
350 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL)
351 typedef psnip_int32_t psnip_safe_llong_larger
;
352 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL)
353 typedef psnip_int64_t psnip_safe_llong_larger
;
354 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL)
355 typedef psnip_safe_int128_t psnip_safe_llong_larger
;
357 #undef PSNIP_SAFE_HAVE_LARGER_LLONG
360 #define PSNIP_SAFE_HAVE_LARGER_ULLONG
361 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffff)
362 typedef psnip_uint16_t psnip_safe_ullong_larger
;
363 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL)
364 typedef psnip_uint32_t psnip_safe_ullong_larger
;
365 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL)
366 typedef psnip_uint64_t psnip_safe_ullong_larger
;
367 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL)
368 typedef psnip_safe_uint128_t psnip_safe_ullong_larger
;
370 #undef PSNIP_SAFE_HAVE_LARGER_ULLONG
373 #if defined(PSNIP_SAFE_SIZE_MAX)
374 #define PSNIP_SAFE_HAVE_LARGER_SIZE
375 #if PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, USHRT_MAX)
376 typedef unsigned short psnip_safe_size_larger
;
377 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX)
378 typedef unsigned int psnip_safe_size_larger
;
379 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX)
380 typedef unsigned long psnip_safe_size_larger
;
381 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX)
382 typedef unsigned long long psnip_safe_size_larger
;
383 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff)
384 typedef psnip_uint16_t psnip_safe_size_larger
;
385 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL)
386 typedef psnip_uint32_t psnip_safe_size_larger
;
387 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL)
388 typedef psnip_uint64_t psnip_safe_size_larger
;
389 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL)
390 typedef psnip_safe_uint128_t psnip_safe_size_larger
;
392 #undef PSNIP_SAFE_HAVE_LARGER_SIZE
396 #if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
397 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar
)
400 #if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
401 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar
)
404 #if defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
406 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char)
408 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char)
412 #if defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
413 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short)
416 #if defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
417 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort
)
420 #if defined(PSNIP_SAFE_HAVE_LARGER_INT)
421 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int)
424 #if defined(PSNIP_SAFE_HAVE_LARGER_UINT)
425 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint
)
428 #if defined(PSNIP_SAFE_HAVE_LARGER_LONG)
429 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long)
432 #if defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
433 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong
)
436 #if defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
437 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong
)
440 #if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
441 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong
)
444 #if defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
445 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size
)
448 #if !defined(PSNIP_SAFE_NO_FIXED)
449 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t
, int8
)
450 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t
, uint8
)
451 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t
, int16
)
452 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t
, uint16
)
453 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t
, int32
)
454 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t
, uint32
)
455 #if defined(PSNIP_SAFE_HAVE_128)
456 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t
, int64
)
457 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint64_t
, uint64
)
461 #endif /* !defined(PSNIP_SAFE_NO_PROMOTIONS) */
463 #define PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(T, name, op_name) \
464 PSNIP_SAFE__FUNCTION psnip_safe_bool \
465 psnip_safe_##name##_##op_name(T* res, T a, T b) { \
466 return !__builtin_##op_name##_overflow(a, b, res); \
469 #define PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(T, name, op_name, min, max) \
470 PSNIP_SAFE__FUNCTION psnip_safe_bool \
471 psnip_safe_##name##_##op_name(T* res, T a, T b) { \
472 const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
474 return (r >= min) && (r <= max); \
477 #define PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(T, name, op_name, max) \
478 PSNIP_SAFE__FUNCTION psnip_safe_bool \
479 psnip_safe_##name##_##op_name(T* res, T a, T b) { \
480 const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
485 #define PSNIP_SAFE_DEFINE_SIGNED_ADD(T, name, min, max) \
486 PSNIP_SAFE__FUNCTION psnip_safe_bool \
487 psnip_safe_##name##_add (T* res, T a, T b) { \
488 psnip_safe_bool r = !( ((b > 0) && (a > (max - b))) || \
489 ((b < 0) && (a < (min - b))) ); \
490 if(PSNIP_SAFE_LIKELY(r)) \
495 #define PSNIP_SAFE_DEFINE_UNSIGNED_ADD(T, name, max) \
496 PSNIP_SAFE__FUNCTION psnip_safe_bool \
497 psnip_safe_##name##_add (T* res, T a, T b) { \
498 *res = (T) (a + b); \
499 return !PSNIP_SAFE_UNLIKELY((b > 0) && (a > (max - b))); \
502 #define PSNIP_SAFE_DEFINE_SIGNED_SUB(T, name, min, max) \
503 PSNIP_SAFE__FUNCTION psnip_safe_bool \
504 psnip_safe_##name##_sub (T* res, T a, T b) { \
505 psnip_safe_bool r = !((b > 0 && a < (min + b)) || \
506 (b < 0 && a > (max + b))); \
507 if(PSNIP_SAFE_LIKELY(r)) \
512 #define PSNIP_SAFE_DEFINE_UNSIGNED_SUB(T, name, max) \
513 PSNIP_SAFE__FUNCTION psnip_safe_bool \
514 psnip_safe_##name##_sub (T* res, T a, T b) { \
516 return !PSNIP_SAFE_UNLIKELY(b > a); \
519 #define PSNIP_SAFE_DEFINE_SIGNED_MUL(T, name, min, max) \
520 PSNIP_SAFE__FUNCTION psnip_safe_bool \
521 psnip_safe_##name##_mul (T* res, T a, T b) { \
522 psnip_safe_bool r = 1; \
525 if (a > (max / b)) { \
529 if (b < (min / a)) { \
535 if (a < (min / b)) { \
539 if ( (a != 0) && (b < (max / a))) { \
544 if(PSNIP_SAFE_LIKELY(r)) \
549 #define PSNIP_SAFE_DEFINE_UNSIGNED_MUL(T, name, max) \
550 PSNIP_SAFE__FUNCTION psnip_safe_bool \
551 psnip_safe_##name##_mul (T* res, T a, T b) { \
552 *res = (T) (a * b); \
553 return !PSNIP_SAFE_UNLIKELY((a > 0) && (b > 0) && (a > (max / b))); \
556 #define PSNIP_SAFE_DEFINE_SIGNED_DIV(T, name, min, max) \
557 PSNIP_SAFE__FUNCTION psnip_safe_bool \
558 psnip_safe_##name##_div (T* res, T a, T b) { \
559 if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
562 } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
566 *res = (T) (a / b); \
571 #define PSNIP_SAFE_DEFINE_UNSIGNED_DIV(T, name, max) \
572 PSNIP_SAFE__FUNCTION psnip_safe_bool \
573 psnip_safe_##name##_div (T* res, T a, T b) { \
574 if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
583 #define PSNIP_SAFE_DEFINE_SIGNED_MOD(T, name, min, max) \
584 PSNIP_SAFE__FUNCTION psnip_safe_bool \
585 psnip_safe_##name##_mod (T* res, T a, T b) { \
586 if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
589 } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
593 *res = (T) (a % b); \
598 #define PSNIP_SAFE_DEFINE_UNSIGNED_MOD(T, name, max) \
599 PSNIP_SAFE__FUNCTION psnip_safe_bool \
600 psnip_safe_##name##_mod (T* res, T a, T b) { \
601 if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
610 #define PSNIP_SAFE_DEFINE_SIGNED_NEG(T, name, min, max) \
611 PSNIP_SAFE__FUNCTION psnip_safe_bool \
612 psnip_safe_##name##_neg (T* res, T value) { \
613 psnip_safe_bool r = value != min; \
614 *res = PSNIP_SAFE_LIKELY(r) ? -value : max; \
618 #define PSNIP_SAFE_DEFINE_INTSAFE(T, name, op, isf) \
619 PSNIP_SAFE__FUNCTION psnip_safe_bool \
620 psnip_safe_##name##_##op (T* res, T a, T b) { \
621 return isf(a, b, res) == S_OK; \
625 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
626 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add
)
627 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub
)
628 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul
)
629 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
630 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add
, CHAR_MAX
)
631 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub
, CHAR_MAX
)
632 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul
, CHAR_MAX
)
634 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX
)
635 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX
)
636 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX
)
638 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX
)
639 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX
)
640 #else /* CHAR_MIN != 0 */
641 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
642 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add
)
643 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub
)
644 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul
)
645 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
646 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add
, CHAR_MIN
, CHAR_MAX
)
647 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub
, CHAR_MIN
, CHAR_MAX
)
648 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul
, CHAR_MIN
, CHAR_MAX
)
650 PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN
, CHAR_MAX
)
651 PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN
, CHAR_MAX
)
652 PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN
, CHAR_MAX
)
654 PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN
, CHAR_MAX
)
655 PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN
, CHAR_MAX
)
656 PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN
, CHAR_MAX
)
659 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
660 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar
, add
)
661 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar
, sub
)
662 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar
, mul
)
663 #elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
664 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar
, add
, SCHAR_MIN
, SCHAR_MAX
)
665 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar
, sub
, SCHAR_MIN
, SCHAR_MAX
)
666 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar
, mul
, SCHAR_MIN
, SCHAR_MAX
)
668 PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
669 PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
670 PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
672 PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
673 PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
674 PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar
, SCHAR_MIN
, SCHAR_MAX
)
676 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
677 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar
, add
)
678 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar
, sub
)
679 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar
, mul
)
680 #elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
681 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar
, add
, UCHAR_MAX
)
682 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar
, sub
, UCHAR_MAX
)
683 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar
, mul
, UCHAR_MAX
)
685 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar
, UCHAR_MAX
)
686 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar
, UCHAR_MAX
)
687 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar
, UCHAR_MAX
)
689 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar
, UCHAR_MAX
)
690 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar
, UCHAR_MAX
)
692 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
693 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add
)
694 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub
)
695 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul
)
696 #elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
697 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add
, SHRT_MIN
, SHRT_MAX
)
698 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub
, SHRT_MIN
, SHRT_MAX
)
699 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul
, SHRT_MIN
, SHRT_MAX
)
701 PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN
, SHRT_MAX
)
702 PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN
, SHRT_MAX
)
703 PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN
, SHRT_MAX
)
705 PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN
, SHRT_MAX
)
706 PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN
, SHRT_MAX
)
707 PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN
, SHRT_MAX
)
709 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
710 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort
, add
)
711 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort
, sub
)
712 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort
, mul
)
713 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
714 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort
, add
, UShortAdd
)
715 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort
, sub
, UShortSub
)
716 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort
, mul
, UShortMult
)
717 #elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
718 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort
, add
, USHRT_MAX
)
719 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort
, sub
, USHRT_MAX
)
720 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort
, mul
, USHRT_MAX
)
722 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort
, USHRT_MAX
)
723 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort
, USHRT_MAX
)
724 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort
, USHRT_MAX
)
726 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort
, USHRT_MAX
)
727 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort
, USHRT_MAX
)
729 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
730 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add
)
731 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub
)
732 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul
)
733 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT)
734 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add
, INT_MIN
, INT_MAX
)
735 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub
, INT_MIN
, INT_MAX
)
736 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul
, INT_MIN
, INT_MAX
)
738 PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN
, INT_MAX
)
739 PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN
, INT_MAX
)
740 PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN
, INT_MAX
)
742 PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN
, INT_MAX
)
743 PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN
, INT_MAX
)
744 PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN
, INT_MAX
)
746 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
747 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint
, add
)
748 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint
, sub
)
749 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint
, mul
)
750 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
751 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint
, add
, UIntAdd
)
752 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint
, sub
, UIntSub
)
753 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint
, mul
, UIntMult
)
754 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT)
755 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint
, add
, UINT_MAX
)
756 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint
, sub
, UINT_MAX
)
757 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint
, mul
, UINT_MAX
)
759 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint
, UINT_MAX
)
760 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint
, UINT_MAX
)
761 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint
, UINT_MAX
)
763 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint
, UINT_MAX
)
764 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint
, UINT_MAX
)
766 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
767 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add
)
768 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub
)
769 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul
)
770 #elif defined(PSNIP_SAFE_HAVE_LARGER_LONG)
771 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add
, LONG_MIN
, LONG_MAX
)
772 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub
, LONG_MIN
, LONG_MAX
)
773 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul
, LONG_MIN
, LONG_MAX
)
775 PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN
, LONG_MAX
)
776 PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN
, LONG_MAX
)
777 PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN
, LONG_MAX
)
779 PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN
, LONG_MAX
)
780 PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN
, LONG_MAX
)
781 PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN
, LONG_MAX
)
783 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
784 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong
, add
)
785 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong
, sub
)
786 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong
, mul
)
787 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
788 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong
, add
, ULongAdd
)
789 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong
, sub
, ULongSub
)
790 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong
, mul
, ULongMult
)
791 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
792 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong
, add
, ULONG_MAX
)
793 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong
, sub
, ULONG_MAX
)
794 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong
, mul
, ULONG_MAX
)
796 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong
, ULONG_MAX
)
797 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong
, ULONG_MAX
)
798 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong
, ULONG_MAX
)
800 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong
, ULONG_MAX
)
801 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong
, ULONG_MAX
)
803 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
804 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong
, add
)
805 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong
, sub
)
806 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong
, mul
)
807 #elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
808 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong
, add
, LLONG_MIN
, LLONG_MAX
)
809 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong
, sub
, LLONG_MIN
, LLONG_MAX
)
810 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong
, mul
, LLONG_MIN
, LLONG_MAX
)
812 PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong
, LLONG_MIN
, LLONG_MAX
)
813 PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong
, LLONG_MIN
, LLONG_MAX
)
814 PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong
, LLONG_MIN
, LLONG_MAX
)
816 PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong
, LLONG_MIN
, LLONG_MAX
)
817 PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong
, LLONG_MIN
, LLONG_MAX
)
818 PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong
, LLONG_MIN
, LLONG_MAX
)
820 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
821 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong
, add
)
822 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong
, sub
)
823 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong
, mul
)
824 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
825 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong
, add
, ULongLongAdd
)
826 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong
, sub
, ULongLongSub
)
827 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong
, mul
, ULongLongMult
)
828 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
829 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong
, add
, ULLONG_MAX
)
830 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong
, sub
, ULLONG_MAX
)
831 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong
, mul
, ULLONG_MAX
)
833 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong
, ULLONG_MAX
)
834 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong
, ULLONG_MAX
)
835 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong
, ULLONG_MAX
)
837 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong
, ULLONG_MAX
)
838 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong
, ULLONG_MAX
)
840 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
841 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size
, add
)
842 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size
, sub
)
843 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size
, mul
)
844 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
845 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size
, add
, SizeTAdd
)
846 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size
, sub
, SizeTSub
)
847 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size
, mul
, SizeTMult
)
848 #elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
849 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size
, add
, PSNIP_SAFE__SIZE_MAX_RT
)
850 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size
, sub
, PSNIP_SAFE__SIZE_MAX_RT
)
851 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size
, mul
, PSNIP_SAFE__SIZE_MAX_RT
)
853 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size
, PSNIP_SAFE__SIZE_MAX_RT
)
854 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size
, PSNIP_SAFE__SIZE_MAX_RT
)
855 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size
, PSNIP_SAFE__SIZE_MAX_RT
)
857 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size
, PSNIP_SAFE__SIZE_MAX_RT
)
858 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(size_t, size
, PSNIP_SAFE__SIZE_MAX_RT
)
860 #if !defined(PSNIP_SAFE_NO_FIXED)
862 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
863 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t
, int8
, add
)
864 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t
, int8
, sub
)
865 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t
, int8
, mul
)
866 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT8)
867 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t
, int8
, add
, (-0x7fLL
-1), 0x7f)
868 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t
, int8
, sub
, (-0x7fLL
-1), 0x7f)
869 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t
, int8
, mul
, (-0x7fLL
-1), 0x7f)
871 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
872 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
873 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
875 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
876 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
877 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t
, int8
, (-0x7fLL
-1), 0x7f)
879 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
880 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t
, uint8
, add
)
881 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t
, uint8
, sub
)
882 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t
, uint8
, mul
)
883 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8)
884 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t
, uint8
, add
, 0xff)
885 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t
, uint8
, sub
, 0xff)
886 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t
, uint8
, mul
, 0xff)
888 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t
, uint8
, 0xff)
889 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t
, uint8
, 0xff)
890 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t
, uint8
, 0xff)
892 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t
, uint8
, 0xff)
893 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t
, uint8
, 0xff)
895 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
896 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t
, int16
, add
)
897 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t
, int16
, sub
)
898 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t
, int16
, mul
)
899 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT16)
900 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t
, int16
, add
, (-32767-1), 0x7fff)
901 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t
, int16
, sub
, (-32767-1), 0x7fff)
902 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t
, int16
, mul
, (-32767-1), 0x7fff)
904 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
905 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
906 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
908 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
909 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
910 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t
, int16
, (-32767-1), 0x7fff)
912 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
913 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t
, uint16
, add
)
914 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t
, uint16
, sub
)
915 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t
, uint16
, mul
)
916 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
917 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t
, uint16
, add
, UShortAdd
)
918 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t
, uint16
, sub
, UShortSub
)
919 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t
, uint16
, mul
, UShortMult
)
920 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16)
921 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t
, uint16
, add
, 0xffff)
922 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t
, uint16
, sub
, 0xffff)
923 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t
, uint16
, mul
, 0xffff)
925 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t
, uint16
, 0xffff)
926 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t
, uint16
, 0xffff)
927 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t
, uint16
, 0xffff)
929 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t
, uint16
, 0xffff)
930 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t
, uint16
, 0xffff)
932 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
933 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t
, int32
, add
)
934 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t
, int32
, sub
)
935 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t
, int32
, mul
)
936 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT32)
937 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t
, int32
, add
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
938 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t
, int32
, sub
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
939 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t
, int32
, mul
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
941 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
942 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
943 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
945 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
946 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
947 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t
, int32
, (-0x7fffffffLL
-1), 0x7fffffffLL
)
949 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
950 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t
, uint32
, add
)
951 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t
, uint32
, sub
)
952 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t
, uint32
, mul
)
953 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
954 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t
, uint32
, add
, UIntAdd
)
955 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t
, uint32
, sub
, UIntSub
)
956 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t
, uint32
, mul
, UIntMult
)
957 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32)
958 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t
, uint32
, add
, 0xffffffffUL
)
959 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t
, uint32
, sub
, 0xffffffffUL
)
960 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t
, uint32
, mul
, 0xffffffffUL
)
962 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t
, uint32
, 0xffffffffUL
)
963 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t
, uint32
, 0xffffffffUL
)
964 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t
, uint32
, 0xffffffffUL
)
966 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t
, uint32
, 0xffffffffUL
)
967 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t
, uint32
, 0xffffffffUL
)
969 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
970 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t
, int64
, add
)
971 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t
, int64
, sub
)
972 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t
, int64
, mul
)
973 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT64)
974 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t
, int64
, add
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
975 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t
, int64
, sub
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
976 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t
, int64
, mul
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
978 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
979 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
980 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
982 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
983 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
984 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t
, int64
, (-0x7fffffffffffffffLL
-1), 0x7fffffffffffffffLL
)
986 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
987 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t
, uint64
, add
)
988 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t
, uint64
, sub
)
989 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t
, uint64
, mul
)
990 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
991 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t
, uint64
, add
, ULongLongAdd
)
992 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t
, uint64
, sub
, ULongLongSub
)
993 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t
, uint64
, mul
, ULongLongMult
)
994 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64)
995 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t
, uint64
, add
, 0xffffffffffffffffULL
)
996 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t
, uint64
, sub
, 0xffffffffffffffffULL
)
997 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t
, uint64
, mul
, 0xffffffffffffffffULL
)
999 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t
, uint64
, 0xffffffffffffffffULL
)
1000 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t
, uint64
, 0xffffffffffffffffULL
)
1001 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t
, uint64
, 0xffffffffffffffffULL
)
1003 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t
, uint64
, 0xffffffffffffffffULL
)
1004 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint64_t
, uint64
, 0xffffffffffffffffULL
)
1006 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
1008 #define PSNIP_SAFE_C11_GENERIC_SELECTION(res, op) \
1010 char: psnip_safe_char_##op, \
1011 unsigned char: psnip_safe_uchar_##op, \
1012 short: psnip_safe_short_##op, \
1013 unsigned short: psnip_safe_ushort_##op, \
1014 int: psnip_safe_int_##op, \
1015 unsigned int: psnip_safe_uint_##op, \
1016 long: psnip_safe_long_##op, \
1017 unsigned long: psnip_safe_ulong_##op, \
1018 long long: psnip_safe_llong_##op, \
1019 unsigned long long: psnip_safe_ullong_##op)
1021 #define PSNIP_SAFE_C11_GENERIC_BINARY_OP(op, res, a, b) \
1022 PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, a, b)
1023 #define PSNIP_SAFE_C11_GENERIC_UNARY_OP(op, res, v) \
1024 PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, v)
1026 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
1027 #define psnip_safe_add(res, a, b) !__builtin_add_overflow(a, b, res)
1028 #define psnip_safe_sub(res, a, b) !__builtin_sub_overflow(a, b, res)
1029 #define psnip_safe_mul(res, a, b) !__builtin_mul_overflow(a, b, res)
1030 #define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b)
1031 #define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b)
1032 #define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1034 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
1035 /* The are no fixed-length or size selections because they cause an
1036 * error about _Generic specifying two compatible types. Hopefully
1037 * this doesn't cause problems on exotic platforms, but if it does
1038 * please let me know and I'll try to figure something out. */
1040 #define psnip_safe_add(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(add, res, a, b)
1041 #define psnip_safe_sub(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(sub, res, a, b)
1042 #define psnip_safe_mul(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mul, res, a, b)
1043 #define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b)
1044 #define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b)
1045 #define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1050 #define ws_safe_op_jmp(op, res, a, b, env) \
1052 if(!psnip_safe_##op(res, a, b)) { \
1057 #define ws_safe_add_jmp(res, a, b, env) ws_safe_op_jmp(add, res, a, b, env)
1058 #define ws_safe_sub_jmp(res, a, b, env) ws_safe_op_jmp(sub, res, a, b, env)
1059 #define ws_safe_mul_jmp(res, a, b, env) ws_safe_op_jmp(mul, res, a, b, env)
1060 #define ws_safe_div_jmp(res, a, b, env) ws_safe_op_jmp(div, res, a, b, env)
1061 #define ws_safe_mod_jmp(res, a, b, env) ws_safe_op_jmp(mod, res, a, b, env)
1062 #define ws_safe_neg_jmp(res, a, b, env) ws_safe_op_jmp(neg, res, a, b, env)
1064 #endif /* !defined(PSNIP_SAFE_H) */