1 ```#ifndef __NPY_TYPED_COMMON_INC ``` 2 ```#define __NPY_TYPED_COMMON_INC ``` 3 4 ```/* utility functions that profit from templates */ ``` 5 6 ```#include "numpy/npy_common.h" ``` 7 8 ```/**begin repeat ``` 9 ``` * #name = int, uint, long, ulong, ``` 10 ``` * longlong, ulonglong, intp# ``` 11 ``` * #type = npy_int, npy_uint, npy_long, npy_ulong, ``` 12 ``` * npy_longlong, npy_ulonglong, npy_intp# ``` 13 ``` * #MAX = NPY_MAX_INT, NPY_MAX_UINT, NPY_MAX_LONG, NPY_MAX_ULONG, ``` 14 ``` * NPY_MAX_LONGLONG, NPY_MAX_ULONGLONG, NPY_MAX_INTP# ``` 15 ``` */ ``` 16 17 ```/* ``` 18 ``` * writes result of a * b into r ``` 19 ``` * returns 1 if a * b overflowed else returns 0 ``` 20 ``` * ``` 21 ``` * These functions are not designed to work if either a or b is negative, but ``` 22 ``` * that is not checked. Could use absolute values and adjust the sign if that ``` 23 ``` * functionality was desired. ``` 24 ``` */ ``` 25 ```static NPY_INLINE int ``` 26 ```npy_mul_with_overflow_@name@(@type@ * r, @type@ a, @type@ b) ``` 27 ```{ ``` 28 ```#ifdef HAVE___BUILTIN_MUL_OVERFLOW ``` 29 1 ``` return __builtin_mul_overflow(a, b, r); ``` 30 ```#else ``` 31 ``` const @type@ half_sz = ((@type@)1 << ((sizeof(a) * 8 - 1 ) / 2)); ``` 32 33 ``` *r = a * b; ``` 34 ``` /* ``` 35 ``` * avoid expensive division on common no overflow case ``` 36 ``` */ ``` 37 ``` if (NPY_UNLIKELY((a | b) >= half_sz) && ``` 38 ``` a != 0 && b > @MAX@ / a) { ``` 39 ``` return 1; ``` 40 ``` } ``` 41 ``` return 0; ``` 42 ```#endif ``` 43 ```} ``` 44 ```/**end repeat**/ ``` 45 46 ```#endif ```

Read our documentation on viewing source code .