/** * @file limited_int.h * @brief Integer class catching overflows. */ /* sorry if it is not styled correctly, i'll work on it further */ #ifndef LIMITED_INT_H_INCLUDED #define LIMITED_INT_H_INCLUDED 1 #include #include #include template < typename T = int > class LIMITED_INT { private: T m_Value; public: LIMITED_INT( void ) : m_Value() { } template LIMITED_INT( const LIMITED_INT< V >& orig ) : m_Value( orig.m_Value ) { assert(std::numeric_limits::min() <= orig.m_Value); assert(orig.m_Value <= std::numeric_limits::max()); } template LIMITED_INT( const double v ) : m_Value( floor(v+0.5) ) { assert(std::numeric_limits::min() <= v); assert(v <= std::numeric_limits::max()); } LIMITED_INT( T v ): m_Value( v ) { } operator T( void ) const { return m_Value; } operator double( void ) const { return ( double )m_Value; } LIMITED_INT & operator = ( LIMITED_INT< T > src ) { m_Value = src.m_Value; return *this; } LIMITED_INT & operator = ( T src ) { m_Value = src; return *this; } /*************************/ /* comparisons and tests */ /*************************/ bool operator ! (void) const { return !m_Value; } bool operator == ( const LIMITED_INT< T > &y ) const { return m_Value == y.m_Value; } bool operator == ( const T y ) const { return m_Value == y; } friend bool operator == ( const T x, const LIMITED_INT< T > &y ) { return x == y.m_Value; } bool operator != ( const LIMITED_INT &y ) const { return m_Value != y.m_Value; } bool operator != ( const T y ) const { return m_Value != y; } friend bool operator != ( const T x, const LIMITED_INT< T > &y ) { return x != y.m_Value; } bool operator < ( const LIMITED_INT< T > &y ) const { return m_Value < y.m_Value; } bool operator < ( const T y ) const { return m_Value < y; } friend bool operator < ( const T x, const LIMITED_INT< T > &y ) { return x < y.m_Value; } bool operator >= ( const LIMITED_INT< T > &y ) const { return m_Value >= y.m_Value; } bool operator >= ( const T y ) const { return m_Value >= y; } friend bool operator >= ( const T x, const LIMITED_INT &y ) { return x >= y.m_Value; } bool operator > ( const LIMITED_INT< T > &y ) const { return m_Value > y.m_Value; } bool operator > ( const T y ) const { return m_Value > y; } friend bool operator > ( const T x, const LIMITED_INT< T > &y ) { return x > y.m_Value; } bool operator <= ( const LIMITED_INT< T > &y ) const { return m_Value <= y.m_Value; } bool operator <= ( const T y ) const { return m_Value <= y; } friend bool operator <= ( const T x, const LIMITED_INT< T > &y ) { return x <= y.m_Value; } /*************************/ /* basic arithmetic */ /*************************/ LIMITED_INT< T > operator + ( const LIMITED_INT< T > &y ) const { assert( !( 0 < m_Value ) || y.m_Value <= std::numeric_limits< T >::max() - m_Value ); assert( !( m_Value < 0 ) || std::numeric_limits< T >::min() - m_Value <= y.m_Value ); return m_Value + y.m_Value; } LIMITED_INT< T > operator + ( const T y ) const { return *this + LIMITED_INT< T >( y ); } friend LIMITED_INT< T > operator + ( const T x, const LIMITED_INT< T > &y ) { return LIMITED_INT< T >( x ) + y; } double operator + ( const double y ) const { return double( m_Value ) + y; } friend double operator + ( const double x, const LIMITED_INT< T > &y ) { return x + double( y.m_Value ); } LIMITED_INT< T > operator - ( void ) const { assert( -std::numeric_limits< T >::max() <= m_Value ); return -m_Value; } LIMITED_INT< T > operator - ( const LIMITED_INT< T > &y ) const { assert( !( 0 < m_Value ) || m_Value - std::numeric_limits< T >::max() <= y.m_Value ); assert( !( m_Value < 0 ) || y.m_Value <= m_Value - std::numeric_limits< T >::min() ); return m_Value - y.m_Value; } LIMITED_INT< T > operator - ( const T y ) const { return *this - LIMITED_INT< T >( y ); } friend LIMITED_INT< T > operator - ( const T x, const LIMITED_INT< T > &y ) { return LIMITED_INT< T >( x ) - y; } double operator - ( const double y ) const { return double( m_Value ) - y; } friend double operator - ( const double x, const LIMITED_INT< T > &y ) { return x - double( y.m_Value ); } LIMITED_INT< T > operator * ( const LIMITED_INT< T > &y ) const { assert( !( 0 < m_Value && 0 < y.m_Value ) || y.m_Value <= std::numeric_limits::max() / m_Value ); assert( !( 0 < m_Value && y.m_Value < 0 ) || std::numeric_limits::min() / m_Value <= y.m_Value ); assert( !( m_Value < 0 && 0 < y.m_Value ) || std::numeric_limits::min() / y.m_Value <= m_Value ); assert( !( m_Value < 0 && y.m_Value < 0 ) || std::numeric_limits::max() / m_Value <= y.m_Value ); return m_Value * y.m_Value; } LIMITED_INT operator * ( const T y) const { return *this * LIMITED_INT< T >( y ); } friend LIMITED_INT< T > operator *( const T x, const LIMITED_INT< T > &y ) { return LIMITED_INT< T >( x ) * y; } double operator * ( const double y ) const { return double( m_Value ) * y; } friend double operator * ( const double x, const LIMITED_INT< T > &y ) { return x * double( y.m_Value ); } LIMITED_INT operator / ( const LIMITED_INT &y ) const { assert( !( -1 == y.m_Value ) || -std::numeric_limits< T >::max() <= m_Value ); return m_Value / y.m_Value; } LIMITED_INT operator / ( const T y ) const { return *this / LIMITED_INT(y); } friend LIMITED_INT< T > operator / ( const T x, const LIMITED_INT< T > &y ) { return LIMITED_INT< T >( x ) / y; } double operator / ( const double y ) const { return double( m_Value ) / y; } friend double operator / ( const double x, const LIMITED_INT< T > &y ) { return x / double( y.m_Value ); } LIMITED_INT operator % ( const LIMITED_INT &y ) const { return m_Value % y.m_Value; } LIMITED_INT operator % ( const T y ) const { return *this % LIMITED_INT(y); } friend LIMITED_INT< T > operator % ( const T x, const LIMITED_INT< T > &y ) { return LIMITED_INT< T >( x ) % y; } LIMITED_INT< T >& operator += ( const LIMITED_INT< T > &y ) { *this = *this + y; return *this; } LIMITED_INT< T >& operator += ( const T y ) { *this = *this + y; return *this; } LIMITED_INT< T >& operator ++ ( void ) { *this = *this + 1; return *this; } LIMITED_INT< T >& operator -= ( const LIMITED_INT< T > &y ) { *this = *this - y; return *this; } LIMITED_INT< T >& operator -= ( const T y ) { *this = *this - y; return *this; } LIMITED_INT< T >& operator -- ( void ) { *this = *this - 1; return *this; } LIMITED_INT< T >& operator *= ( const LIMITED_INT< T > &y ) { *this = *this * y; return *this; } LIMITED_INT< T >& operator *= ( const T y ) { *this = *this * y; return *this; } LIMITED_INT< T >& operator /= ( const LIMITED_INT< T > &y ) { *this = *this / y; return *this; } LIMITED_INT< T >& operator /= ( const T y ) { *this = *this / y; return *this; } }; #endif /* def LIMITED_INT_H_INCLUDED*/