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
25struct 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