Range Constrained Types in C++

Posted on Fri 05 September 2014 in misc View Comments

One of the first things a new Ada programmer will learn is the ability to define constrained type. Which means that one can restrict the values that can be assigned to a variable of this specific type.

For example:

subtype Positive is Integer range 1 .. Integer'Last;

Being a subtype of Integer, Positive is fully compatible with it and can be used wherever Integer is applicable. Ada's runtime system however, will guard against assignments of values lower than 1 and will dispatch a runtime error whenever this happens.

This feature enhances type safety and reduces probability for bugs. For example, one can safely divide an Integer by Positive without fear of dividing by zero.

C++ does not have this feature. There is an unofficial Boost library claiming to implement it. However reading the implementation I found out that constrained_value is not a proper subtype of value_type. There are examples where instances of the first, can not substitute the other:

void f(bounded_int<int, 0, 100>::type x) { ... };

...

bounded_int<int, 0, 100>::type x = 5;
x++; // Compilation error: operator not defined.
f(x); // Compilation error: casting operator not defined.

With these limitations, this feature becomes less useful.

Therefore, as an exercise, I decided to implement this feature on my own. The goals of my implementation were:

  • Proper subtyping of the base type.
  • Smallest possible performance and memory penalty.
  • Simple interface.
  • Extensive automatic testing.

How to Use

The code itself can be found on github. Just grab the file named subtype_range_constrained.h and add it to your project.

Here is a simple usage example:

typedef ct::RangeConstrained<short, 1, 12> positive;

int main(void) {
    positive p = 12;
    int x = -3;

    p = p + x;  // Ok
    p = x;      // Exception!
}