| 1 | /* @title: Range and Interval Operations */ |
| 2 | #pragma once |
| 3 | #include <compiler/core.h> |
| 4 | #include <enforce.h> |
| 5 | #include <stdbool.h> |
| 6 | #include <stdint.h> |
| 7 | |
| 8 | #define IN_RANGE(x, min, max) \ |
| 9 | ({ \ |
| 10 | __auto_type __ir_x = (x); \ |
| 11 | __auto_type __ir_lo = (min); \ |
| 12 | __auto_type __ir_hi = (max); \ |
| 13 | typedef ct_common_type_2(__ir_x, __ir_lo) __ir_t1; \ |
| 14 | typedef ct_common_type_2((__ir_t1) 0, __ir_hi) __ir_t; \ |
| 15 | ct_typecheck_widenable_to((__ir_t) 0, x); \ |
| 16 | ct_typecheck_widenable_to((__ir_t) 0, min); \ |
| 17 | ct_typecheck_widenable_to((__ir_t) 0, max); \ |
| 18 | __ir_t __ir_v = (__ir_t) __ir_x; \ |
| 19 | __ir_t __ir_l = (__ir_t) __ir_lo; \ |
| 20 | __ir_t __ir_h = (__ir_t) __ir_hi; \ |
| 21 | (void) enforce(__ir_l <= __ir_h); \ |
| 22 | (__ir_v >= __ir_l) && (__ir_v <= __ir_h); \ |
| 23 | }) |
| 24 | |
| 25 | struct range { |
| 26 | uint64_t low; |
| 27 | uint64_t hi; |
| 28 | }; |
| 29 | |
| 30 | #define RANGE(min, max) \ |
| 31 | ((struct range) {.low = (uint64_t) (min), .hi = (uint64_t) (max)}) |
| 32 | |
| 33 | #define RANGE_DEFINE(type, name) \ |
| 34 | struct { \ |
| 35 | type low; \ |
| 36 | type hi; \ |
| 37 | } name |
| 38 | |
| 39 | #define RANGE_CONTAINS(r, val) \ |
| 40 | ({ \ |
| 41 | __auto_type __rc_r = (r); \ |
| 42 | __auto_type __rc_val = (val); \ |
| 43 | (__rc_val >= __rc_r.low && __rc_val <= __rc_r.hi); \ |
| 44 | }) |
| 45 | |
| 46 | #define RANGE_VALID(r) \ |
| 47 | ({ \ |
| 48 | __auto_type __rv_r = (r); \ |
| 49 | (__rv_r.low <= __rv_r.hi); \ |
| 50 | }) |
| 51 | |