http://rubinghsoftware.de/codestyle/between.html


The macros BETWEEN_IE() and BETWEEN_II()



Page contents
Abstract
Rationale

Abstract

In C/C++, I like to use the following macros, that test whether a number falls inside an interval (min ≤ x < max, or min ≤ x ≤ max) :

 #define BETWEEN_IE( min, x, max ) ( ((min) <= (x)) && ((x) < (max)) ) 
 #define BETWEEN_II( min, x, max ) ( ((min) <= (x)) && ((x) <= (max)) ) 

The two suffix letters in the names of the macros specify whether the first and second bound, respectively, is inclusive (I) or exclusive (E). 

These two simple macros are one of the "signatures" of my coding style, and over the years they have grown to be part of the standard set of macros that I like to use in C/C++ programming projects. 


Rationale

Simple macros/functions/templates like these add operators to the programming language.  If a piece of code uses a certain operation very frequently, then in my view it pays off to create a macro/function/template for it, even when the macro/function/template is as extremely trivial as these ones.

Interval tests are reasonably elegant in mathematical notation:

min ≤ x < max
min ≤ x ≤ max,
or more elegantly
x ∈ [min,max)
x ∈ [min,max]
But in my view they are somewhat clumsy when coded out in C/C++:
( (min <= x) && (x < max) )
( (min <= x) && (x <= max) )
Coded out in C/C++, the interval test at first glance looks like a complex conglomerate of logical conditions, which obscures the intended conceptual operation, which is the interval test. 

These interval tests are used so frequently that they deserve their own operators (which I added to the language via the two macros BETWEEN_IE() and BETWEEN_II()). 

These macros in my view are very much worth their while, namely because —simple and trivial though they are— they give a significant contribution towards making the code less cluttered and easier to follow in a brief glance. 

Another, related, benefit of these macros is that they reduce coding errors resulting from typos in coding out the interval tests by hand again and again.  Coding them out by hand is of course unproblematic in code that only uses them infrequently, but in the typical technical-mathematical code, coding out these trivial interval tests again and again becomes a small but significant time consumer and error source.