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)