A Subrange type for C++


Algol68, Pascal and Ada but not C++ (or Java) have the concept of a subrange type built in to the language. So in Pascal, for example, you can write the following:

type TwoDigitWholeNumber = 1..99 ;
var t : TwoDigitWholeNumber ;
t = 21 ; // OK
t = t * 8 ; // ERROR outside range 1..99

with any assignment to variable t that is not in the range 1..99 generating a runtime error. Many compilers allow the range checks to be switched off but using this facility is clearly a bad idea as it subverts the whole point of the subrange type – even if all the unit tests pass!

A Subrange Type for C++

subrange provides this subrange type facility in C\\. The class can be used with any host type that has a total ordering, i.e. the integer types, the floating point types and enumerated types. However the arithmetic operations will only work for types that allow it (i.e. not enums since there is no automated conversion from int to the enum symbols). All assignment operations on the type are processed by the policy class using the range specified in the traits class. It is possible to specify a policy that ignores errors but this would be somewhat not sensible. So, using subrange, the above Pascal example can be encoded in C++ as:

typedef subrange::subrange<subrange::ordinal_range<short, 1, 99>> TwoDigitWholeNumber;
TwoDigitWholeNumber t;
t = 21; // OK
t *= 8; // ERROR outside range 1..99

This type is a subrange type where the exception subrange::range_error is thrown on any bounds violation. Policies for modulo arithmetic, saturated arithmetic and NaN arithmetic are provided, so:

subrange::subrange<subrange::ordinal_range<short, 0, 8>, subrange::modulo_arithmetic> Modulo8;

is a type for modulo 8 arithmetic.

This software is distributed as source code (it is just a C++ template after all) the latest version of which can be found here. The tests using the Catch test framework can be found here. Of course software should be maintained using a version control system, so there is a Git repository containing the material, to clone it then:

git clone http://www.russel.org.uk/Git/Subrange_C++.git

This software is distributed under the Boost Software License, Version 1.0.

Feel free to contact me if you have any thoughts on the code or you have a merge request or patch.

Copyright © 2005–2020 Russel Winder - Creative Commons License BY-NC-ND 4.0