| /* CC0 (Public domain) - see LICENSE.CC0 file for details */ |
| #ifndef CCAN_MINMAX_H |
| #define CCAN_MINMAX_H |
| |
| #include "config.h" |
| |
| #include <ccan/build_assert.h> |
| |
| #if !HAVE_STATEMENT_EXPR || !HAVE_TYPEOF |
| /* |
| * Without these, there's no way to avoid unsafe double evaluation of |
| * the arguments |
| */ |
| #error Sorry, minmax module requires statement expressions and typeof |
| #endif |
| |
| #if HAVE_BUILTIN_TYPES_COMPATIBLE_P |
| #define MINMAX_ASSERT_COMPATIBLE(a, b) \ |
| BUILD_ASSERT(__builtin_types_compatible_p(a, b)) |
| #else |
| #define MINMAX_ASSERT_COMPATIBLE(a, b) \ |
| do { } while (0) |
| #endif |
| |
| #define min(a, b) \ |
| ({ \ |
| typeof(a) _a = (a); \ |
| typeof(b) _b = (b); \ |
| MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ |
| _a < _b ? _a : _b; \ |
| }) |
| |
| #define max(a, b) \ |
| ({ \ |
| typeof(a) _a = (a); \ |
| typeof(b) _b = (b); \ |
| MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ |
| _a > _b ? _a : _b; \ |
| }) |
| |
| #define clamp(v, f, c) (max(min((v), (c)), (f))) |
| |
| |
| #define min_t(t, a, b) \ |
| ({ \ |
| t _ta = (a); \ |
| t _tb = (b); \ |
| min(_ta, _tb); \ |
| }) |
| #define max_t(t, a, b) \ |
| ({ \ |
| t _ta = (a); \ |
| t _tb = (b); \ |
| max(_ta, _tb); \ |
| }) |
| |
| #define clamp_t(t, v, f, c) \ |
| ({ \ |
| t _tv = (v); \ |
| t _tf = (f); \ |
| t _tc = (c); \ |
| clamp(_tv, _tf, _tc); \ |
| }) |
| |
| #endif /* CCAN_MINMAX_H */ |