|
35 | 35 | #define __is_noneg_int(x) \
|
36 | 36 | (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0)
|
37 | 37 |
|
38 |
| -#define __types_ok(x, y) \ |
39 |
| - (__is_signed(x) == __is_signed(y) || \ |
40 |
| - __is_signed((x) + 0) == __is_signed((y) + 0) || \ |
41 |
| - __is_noneg_int(x) || __is_noneg_int(y)) |
| 38 | +#define __types_ok(x, y, ux, uy) \ |
| 39 | + (__is_signed(ux) == __is_signed(uy) || \ |
| 40 | + __is_signed((ux) + 0) == __is_signed((uy) + 0) || \ |
| 41 | + __is_noneg_int(x) || __is_noneg_int(y)) |
42 | 42 |
|
43 | 43 | #define __cmp_op_min <
|
44 | 44 | #define __cmp_op_max >
|
|
51 | 51 | #define __cmp_once(op, type, x, y) \
|
52 | 52 | __cmp_once_unique(op, type, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
|
53 | 53 |
|
54 |
| -#define __careful_cmp_once(op, x, y) ({ \ |
55 |
| - static_assert(__types_ok(x, y), \ |
| 54 | +#define __careful_cmp_once(op, x, y, ux, uy) ({ \ |
| 55 | + __auto_type ux = (x); __auto_type uy = (y); \ |
| 56 | + static_assert(__types_ok(x, y, ux, uy), \ |
56 | 57 | #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \
|
57 |
| - __cmp_once(op, __auto_type, x, y); }) |
| 58 | + __cmp(op, ux, uy); }) |
58 | 59 |
|
59 |
| -#define __careful_cmp(op, x, y) \ |
60 |
| - __builtin_choose_expr(__is_constexpr((x) - (y)), \ |
61 |
| - __cmp(op, x, y), __careful_cmp_once(op, x, y)) |
| 60 | +#define __careful_cmp(op, x, y) \ |
| 61 | + __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) |
62 | 62 |
|
63 | 63 | #define __clamp(val, lo, hi) \
|
64 | 64 | ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
|
65 | 65 |
|
66 |
| -#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ |
67 |
| - typeof(val) unique_val = (val); \ |
68 |
| - typeof(lo) unique_lo = (lo); \ |
69 |
| - typeof(hi) unique_hi = (hi); \ |
| 66 | +#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \ |
| 67 | + __auto_type uval = (val); \ |
| 68 | + __auto_type ulo = (lo); \ |
| 69 | + __auto_type uhi = (hi); \ |
70 | 70 | static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
|
71 | 71 | (lo) <= (hi), true), \
|
72 | 72 | "clamp() low limit " #lo " greater than high limit " #hi); \
|
73 |
| - static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ |
74 |
| - static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ |
75 |
| - __clamp(unique_val, unique_lo, unique_hi); }) |
76 |
| - |
77 |
| -#define __careful_clamp(val, lo, hi) ({ \ |
78 |
| - __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ |
79 |
| - __clamp(val, lo, hi), \ |
80 |
| - __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \ |
81 |
| - __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); }) |
| 73 | + static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \ |
| 74 | + static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \ |
| 75 | + __clamp(uval, ulo, uhi); }) |
| 76 | + |
| 77 | +#define __careful_clamp(val, lo, hi) \ |
| 78 | + __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) |
82 | 79 |
|
83 | 80 | /**
|
84 | 81 | * min - return minimum of two values of the same or compatible types
|
|
0 commit comments