Graphviz 16.1.1~dev.20261017.1520
Loading...
Searching...
No Matches
overflow.h
Go to the documentation of this file.
1
6
7#pragma once
8
9#include <assert.h>
10#include <limits.h>
11#include <math.h>
12#include <stdbool.h>
13#include <stddef.h>
14#include <stdint.h>
15
23static inline bool sadd_overflow(int a, int b, int *res) {
24 assert(res != NULL);
25
26 // delegate to hardware optimized implementations where possible
27#if defined(__clang__)
28 return __builtin_sadd_overflow(a, b, res);
29#elif defined(__GNUC__) && __GNUC__ > 4 // GCC ≥ 5
30 return __builtin_sadd_overflow(a, b, res);
31#endif
32
33 if (a > 0 && INT_MAX - a < b) {
34 return true;
35 }
36 if (a < 0 && INT_MIN - a > b) {
37 return true;
38 }
39
40 *res = a + b;
41 return false;
42}
43
49static inline int sadd_saturate(int a, int b) {
50
51 // overflow?
52 if (b > 0 && INT_MAX - b < a) {
53 return INT_MAX;
54 }
55
56 // underflow?
57 if (b < 0 && INT_MIN - b > a) {
58 return INT_MIN;
59 }
60
61 return a + b;
62}
63
70static inline bool size_overflow(size_t a, size_t b, size_t *res) {
71 assert(res != NULL);
72
73 // delegate to hardware optimized implementations where possible
74#if defined(__clang__)
75 return __builtin_add_overflow(a, b, res);
76#elif defined(__GNUC__) && __GNUC__ > 4 // GCC ≥ 5
77 return __builtin_add_overflow(a, b, res);
78#endif
79
80 if (SIZE_MAX - a < b) {
81 return true;
82 }
83
84 *res = a + b;
85 return false;
86}
87
94static inline bool u64add_overflow(uint64_t a, uint64_t b, uint64_t *res) {
95 assert(res != NULL);
96
97 // delegate to hardware optimized implementations where possible
98#if defined(__clang__)
99 return __builtin_add_overflow(a, b, res);
100#elif defined(__GNUC__) && __GNUC__ > 4 // GCC ≥ 5
101 return __builtin_add_overflow(a, b, res);
102#endif
103
104 if (UINT64_MAX - a < b) {
105 return true;
106 }
107
108 *res = a + b;
109 return false;
110}
111
118static inline bool u64mul_overflow(uint64_t a, uint64_t b, uint64_t *res) {
119 assert(res != NULL);
120
121 // delegate to hardware optimized implementations where possible
122#if defined(__clang__)
123 return __builtin_mul_overflow(a, b, res);
124#elif defined(__GNUC__) && __GNUC__ > 4 // GCC ≥ 5
125 return __builtin_mul_overflow(a, b, res);
126#endif
127
128 if (a > 0 && UINT64_MAX / a < b) {
129 return true;
130 }
131
132 *res = a * b;
133 return false;
134}
135
142static inline bool fdiv_overflow(double n, double d, double *res) {
143 assert(res != NULL);
144
145 const double r = n / d;
146
147 // did we overflow?
148 if (!isfinite(r)) {
149 return true;
150 }
151
152 *res = r;
153 return false;
154}
155
162static inline bool fdivf_overflow(float n, float d, float *res) {
163 assert(res != NULL);
164
165 const float r = n / d;
166
167 // did we overflow?
168 if (!isfinite(r)) {
169 return true;
170 }
171
172 *res = r;
173 return false;
174}
#define SIZE_MAX
Definition gmlscan.c:347
node NULL
Definition grammar.y:181
static int sadd_saturate(int a, int b)
Definition overflow.h:49
static bool fdivf_overflow(float n, float d, float *res)
Definition overflow.h:162
static bool fdiv_overflow(double n, double d, double *res)
Definition overflow.h:142
static bool size_overflow(size_t a, size_t b, size_t *res)
Definition overflow.h:70
static bool sadd_overflow(int a, int b, int *res)
Definition overflow.h:23
static bool u64mul_overflow(uint64_t a, uint64_t b, uint64_t *res)
Definition overflow.h:118
static bool u64add_overflow(uint64_t a, uint64_t b, uint64_t *res)
Definition overflow.h:94