Listing 1
/* Wrapping macros */
#define CIRC_ARR_WRAP_END( ptr, base, end ) \
((ptr) == (end) ? (base) : (ptr))
#define CIRC_ARR_WRAP_FWD( ptr, end, sz ) \
((ptr) >= (end) ? (ptr) - (sz) : (ptr))
#define CIRC_ARR_WRAP_REV( ptr, base, sz ) \
((ptr) < (base) ? (ptr) + (sz) : (ptr))
#define CIRC_ARR_WRAP( ptr, base, end, sz ) \
((ptr) < (base) ? (ptr) + (sz)
: ((ptr) >= (end) ? (ptr) - (sz) : (ptr)))
#define CIRC_ARR_ADV_PTR( ptr, base, end ) \
CIRC_ARR_WRAP_END (ptr + 1, base, end)
/* Counting macros */
#define CIRC_ARR_EMPTY( head, tail ) ((head) == (tail))
#define CIRC_ARR_USED( head, tail, sz ) \
CIRC_ARR_WRAP_REV ((tail) - (head), 0, sz)
#define CIRC_ARR_LUSED( head, tail, end ) \
((tail) >= (head) ? (tail) - (head) : (end) - (head))
#define CIRC_ARR_DS_FULL( head, tail, sz ) \
(((tail) + 1 - (head) == 0) || ((tail) + 1 - (head) == (sz)))
#define CIRC_ARR_DS_AVAIL( head, tail, sz ) \
CIRC_ARR_WRAP_REV (head - 1 - tail, 0, sz)
#define CIRC_ARR_DS_LAVAIL( base, end, head, tail, sz ) \
((head) <= (tail) \
? (end) - (tail) - ((head) == (base) ? 1 : 0) \
: CIRC_ARR_DS_AVAIL (head, tail, sz) \
)
/* "Power of 2" macros */
#define CIRC_ARR_P2_OFFSET( ptr, base, mask ) \
(((ptr) - (base)) & (mask))
#define CIRC_ARR_P2_WRAP( ptr, base, mask ) \
((base) + CIRC_ARR_P2_OFFSET (ptr, base, mask))
#define CIRC_ARR_P2_ADV_PTR( ptr, base, mask ) \
CIRC_ARR_P2_WRAP (ptr + 1, base, mask)
#define CIRC_ARR_P2_USED( head, tail, mask ) \
CIRC_ARR_P2_OFFSET (tail, head, mask)
#define CIRC_ARR_P2_DS_AVAIL( head, tail, mask ) \
CIRC_ARR_P2_OFFSET (tail - 1, head, mask)