Информация об изменениях

Сообщение Перечитывая тему про signed vs unsigned... от 29.04.2008 17:00

Изменено 11.05.2020 7:25 Erop

Перечитывая тема про signed vs unsigned...
Поосмотрел я тут на всплывшие "минусы 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 );
Перечитывая тему про signed vs unsigned...
Поосмотрел я тут на всплывшие "минусы 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 );