TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags
[wireshark-sm.git] / wsutil / safe-math.h
blobf40ee16e1776beada085d8e987a41b7c52c5a608
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/
9 */
11 #if !defined(PSNIP_SAFE_H)
12 #define 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
18 # endif
19 # elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
20 # define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
21 # endif
22 # if defined(__has_include)
23 # if __has_include(<intsafe.h>)
24 # define PSNIP_SAFE_HAVE_INTSAFE_H
25 # endif
26 # elif defined(_WIN32)
27 # define PSNIP_SAFE_HAVE_INTSAFE_H
28 # endif
29 #endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */
31 #if defined(__GNUC__)
32 # define PSNIP_SAFE_LIKELY(expr) __builtin_expect(!!(expr), 1)
33 # define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
34 #else
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__))
42 # else
43 # define PSNIP_SAFE__COMPILER_ATTRIBUTES
44 # endif
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
54 # else
55 # define PSNIP_SAFE__INLINE
56 # endif
58 # define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE
59 #endif
61 #if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
62 # define psnip_safe_bool _Bool
63 #else
64 # define psnip_safe_bool int
65 #endif
67 #if !defined(PSNIP_SAFE_NO_FIXED)
68 /* For maximum portability include the exact-int module from
69 portable snippets. */
70 # if \
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)
75 # include <stdint.h>
76 # if !defined(psnip_int64_t)
77 # define psnip_int64_t int64_t
78 # endif
79 # if !defined(psnip_uint64_t)
80 # define psnip_uint64_t uint64_t
81 # endif
82 # if !defined(psnip_int32_t)
83 # define psnip_int32_t int32_t
84 # endif
85 # if !defined(psnip_uint32_t)
86 # define psnip_uint32_t uint32_t
87 # endif
88 # if !defined(psnip_int16_t)
89 # define psnip_int16_t int16_t
90 # endif
91 # if !defined(psnip_uint16_t)
92 # define psnip_uint16_t uint16_t
93 # endif
94 # if !defined(psnip_int8_t)
95 # define psnip_int8_t int8_t
96 # endif
97 # if !defined(psnip_uint8_t)
98 # define psnip_uint8_t uint8_t
99 # endif
100 # endif
101 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
102 #include <limits.h>
103 #include <stdlib.h>
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)
109 # include <stdint.h>
110 # endif
111 #endif
113 #if defined(PSNIP_SAFE_SIZE_MAX)
114 # define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX
115 #else
116 # define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0))
117 #endif
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)
125 # endif
126 # include <intsafe.h>
127 # if defined(_MSC_VER) && (_MSC_VER == 1600)
128 # pragma warning(pop)
129 # endif
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;
212 #else
213 #undef PSNIP_SAFE_HAVE_LARGER_SCHAR
214 #endif
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;
233 #else
234 #undef PSNIP_SAFE_HAVE_LARGER_UCHAR
235 #endif
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;
243 #endif
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;
260 #else
261 #undef PSNIP_SAFE_HAVE_LARGER_SHRT
262 #endif
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;
279 #else
280 #undef PSNIP_SAFE_HAVE_LARGER_USHRT
281 #endif
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;
296 #else
297 #undef PSNIP_SAFE_HAVE_LARGER_INT
298 #endif
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;
313 #else
314 #undef PSNIP_SAFE_HAVE_LARGER_UINT
315 #endif
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;
328 #else
329 #undef PSNIP_SAFE_HAVE_LARGER_LONG
330 #endif
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;
343 #else
344 #undef PSNIP_SAFE_HAVE_LARGER_ULONG
345 #endif
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;
356 #else
357 #undef PSNIP_SAFE_HAVE_LARGER_LLONG
358 #endif
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;
369 #else
370 #undef PSNIP_SAFE_HAVE_LARGER_ULLONG
371 #endif
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;
391 #else
392 #undef PSNIP_SAFE_HAVE_LARGER_SIZE
393 #endif
394 #endif
396 #if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
397 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar)
398 #endif
400 #if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
401 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar)
402 #endif
404 #if defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
405 #if CHAR_MIN == 0
406 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char)
407 #else
408 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char)
409 #endif
410 #endif
412 #if defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
413 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short)
414 #endif
416 #if defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
417 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort)
418 #endif
420 #if defined(PSNIP_SAFE_HAVE_LARGER_INT)
421 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int)
422 #endif
424 #if defined(PSNIP_SAFE_HAVE_LARGER_UINT)
425 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint)
426 #endif
428 #if defined(PSNIP_SAFE_HAVE_LARGER_LONG)
429 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long)
430 #endif
432 #if defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
433 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong)
434 #endif
436 #if defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
437 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong)
438 #endif
440 #if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
441 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong)
442 #endif
444 #if defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
445 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size)
446 #endif
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)
458 #endif
459 #endif
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); \
473 *res = (T) r; \
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); \
481 *res = (T) r; \
482 return (r <= max); \
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)) \
491 *res = a + b; \
492 return 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)) \
508 *res = a - b; \
509 return 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) { \
515 *res = a - 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; \
523 if (a > 0) { \
524 if (b > 0) { \
525 if (a > (max / b)) { \
526 r = 0; \
528 } else { \
529 if (b < (min / a)) { \
530 r = 0; \
533 } else { \
534 if (b > 0) { \
535 if (a < (min / b)) { \
536 r = 0; \
538 } else { \
539 if ( (a != 0) && (b < (max / a))) { \
540 r = 0; \
544 if(PSNIP_SAFE_LIKELY(r)) \
545 *res = a * b; \
546 return 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)) { \
560 *res = 0; \
561 return 0; \
562 } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
563 *res = min; \
564 return 0; \
565 } else { \
566 *res = (T) (a / b); \
567 return 1; \
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)) { \
575 *res = 0; \
576 return 0; \
577 } else { \
578 *res = a / b; \
579 return 1; \
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)) { \
587 *res = 0; \
588 return 0; \
589 } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
590 *res = min; \
591 return 0; \
592 } else { \
593 *res = (T) (a % b); \
594 return 1; \
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)) { \
602 *res = 0; \
603 return 0; \
604 } else { \
605 *res = a % b; \
606 return 1; \
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; \
615 return r; \
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; \
624 #if CHAR_MIN == 0
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)
633 #else
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)
637 #endif
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)
649 #else
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)
653 #endif
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)
657 #endif
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)
667 #else
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)
671 #endif
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)
684 #else
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)
688 #endif
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)
700 #else
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)
704 #endif
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)
721 #else
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)
725 #endif
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)
737 #else
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)
741 #endif
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)
758 #else
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)
762 #endif
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)
774 #else
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)
778 #endif
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)
795 #else
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)
799 #endif
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)
811 #else
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)
815 #endif
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)
832 #else
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)
836 #endif
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)
852 #else
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)
856 #endif
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)
870 #else
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)
874 #endif
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)
887 #else
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)
891 #endif
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)
903 #else
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)
907 #endif
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)
924 #else
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)
928 #endif
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)
940 #else
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)
944 #endif
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)
961 #else
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)
965 #endif
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)
977 #else
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)
981 #endif
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)
998 #else
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)
1002 #endif
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) \
1009 _Generic((*res), \
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)
1046 #endif
1048 #include <setjmp.h>
1050 #define ws_safe_op_jmp(op, res, a, b, env) \
1051 do { \
1052 if(!psnip_safe_##op(res, a, b)) { \
1053 longjmp(env, 1); \
1055 } while (0)
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) */