-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterval.h
55 lines (45 loc) · 1.32 KB
/
interval.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef RANGE_INCLUDED
#define RANGE_INCLUDED
#include <stdbool.h>
/*
* Interval - too clever way of representing a numeric interval in a
* C macro. Any of these forms are valid intervals.
*
* N is an interval of a single number.
* M-N is an interval from M to N, inclusive.
* M- is an interval from M to infinity.
*
* We abuse the C preprocessor to change that into an integer constant
* that can be unpacked by the following functions.
*
* M and N are restricted to the range 0..255.
*/
#define V_(ivl) (!!(0 * ivl + 0))
#define I_(ivl) (ivl + 1 < ivl + 0)
#define L_(ivl) ((ivl + 0) - (0 * ivl + 0))
#define U_(ivl) ((0 * ivl + 0) ? \
-(0 * ivl + 0) : \
(ivl + 0) - (0 * ivl + 0))
#define COMPILE_INTERVAL(ivl) \
(V_(ivl) | I_(ivl) << 1 | L_(ivl) << 8 | U_(ivl) << 16)
typedef int interval_t;
static inline bool interval_is_variadic(interval_t ivl)
{
// True if interval not a single number
return ivl & 1;
}
static inline bool interval_is_infinite(interval_t ivl)
{
// True if interval is unbounded
return ivl >> 1 & 1;
}
static inline int interval_lower_bound(interval_t ivl)
{
return ivl >> 8 & 0xFF;
}
static inline int interval_upper_bound(interval_t ivl)
{
// Only defined if finite.
return ivl >> 16 & 0xFF;
}
#endif /* !RANGE_INCLUDED */