Поосмотрел я тут на всплывшие "минусы STL" и вспомнил ещё более древний флейм про signed vs unsigned.
И подумалось мне, что мастера выразительности и декларативности, скучающие по паскалевским отрезкам целых типов должны бы использовать что-то вроде следующего:
#ifndef IntRange_h
#define IntRange_h
#include <assert.h>
template<int TMinVal, int TMaxVal>
struct IntRange {
enum Type {
MinValue = TMinVal,
MaxValue = TMaxVal
};
static bool IsValid( int a ) { return MinValue <= a && a <= MaxValue; }
static Type To( int a ) { assert( IsValid( a ) ); return static_cast<Type>( a ); }
static Type& SetTo( Type& dst, int a2 ) { return dst = To( a2 ); }
static Type Plus( int a1, int a2 ) { return To( a1 + a2 ); }
static Type Minus( int a1, int a2 ) { return To( a1 - a2 ); }
static Type Mult( int a1, int a2 ) { return To( a1 * a2 ); }
static Type Div( int a1, int a2 ) { assert( a2 != 0 ); return To( a1 / a2 ); }
static Type Rest( int a1, int a2 ) { assert( a2 != 0 ); return To( a1 % a2 ); }
friend inline bool IsValid( Type a ) { return IntRange::IsValid( a ); }
friend inline Type MinValue( const Type& ) { return IntRange::MinValue; }
friend inline Type MaxValue( const Type& ) { return IntRange::MaxValue; }
friend inline Type& SetTo( Type& dst, int a2 ) { return IntRange::SetTo( dst, a2 ); }
friend inline bool IsMinValue( Type a ) { return a == MinValue; }
friend inline bool IsMaxValue( Type a ) { return a == MaxValue; }
friend inline Type Succ( Type a ) { return a + 1; }
friend inline Type Pred( Type a ) { return a - 1; }
friend inline Type operator + ( Type a1, Type a2 ) { return Plus( a1, a2 ); }
friend inline Type operator + ( Type a1, int a2 ) { return Plus( a1, a2 ); }
friend inline Type operator + ( int a1, Type a2 ) { return Plus( a1, a2 ); }
friend inline Type& operator += ( Type& dst, int a2 ) { return dst = dst + a2; }
friend inline Type operator - ( Type a1, Type a2 ) { return Minus( a1, a2 ); }
friend inline Type operator - ( Type a1, int a2 ) { return Minus( a1, a2 ); }
friend inline Type operator - ( int a1, Type a2 ) { return Minus( a1, a2 ); }
friend inline Type& operator -= ( Type& dst, int a2 ) { return dst = dst - a2; }
friend inline Type operator * ( Type a1, Type a2 ) { return Mult( a1, a2 ); }
friend inline Type operator * ( Type a1, int a2 ) { return Mult( a1, a2 ); }
friend inline Type operator * ( int a1, Type a2 ) { return Mult( a1, a2 ); }
friend inline Type& operator *= ( Type& dst, int a2 ) { return dst = dst * a2; }
friend inline Type operator / ( Type a1, Type a2 ) { return Div( a1, a2 ); }
friend inline Type operator / ( Type a1, int a2 ) { return Div( a1, a2 ); }
friend inline Type operator / ( int a1, Type a2 ) { return Div( a1, a2 ); }
friend inline Type& operator /= ( Type& dst, int a2 ) { return dst = dst / a2; }
friend inline Type operator % ( Type a1, Type a2 ) { return Rest( a1, a2 ); }
friend inline Type operator % ( Type a1, int a2 ) { return Rest( a1, a2 ); }
friend inline Type operator % ( int a1, Type a2 ) { return Rest( a1, a2 ); }
friend inline Type& operator %= ( Type& dst, int a2 ) { return dst = dst % a2; }
friend inline Type operator ++ ( Type& a ) { return a += 1; }
friend inline Type operator ++ ( Type& a, int ) { Type res = a; a += 1; return res; }
friend inline Type operator -- ( Type& a ) { return a -= 1; }
friend inline Type operator -- ( Type& a, int ) { Type res = a; a -= 1; return res; }
};
#endif//!IntRange_h
Ну а используется оно как-то так:
IntRange<1, 3>::Type x = MinValue( x );
x = x + 1;
x += 1;
--x;
x++; IntRange<-2, 2>::Type y = MaxValue( y );
Set( x, y );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском