2011-11-09 13:25:49 +00:00
|
|
|
/**
|
|
|
|
* @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 <limits>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
template < typename T = int > class LIMITED_INT {
|
|
|
|
private:
|
|
|
|
T m_Value;
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
public:
|
|
|
|
LIMITED_INT( void ) : m_Value() {
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
template<typename V> LIMITED_INT( const LIMITED_INT< V >& orig )
|
|
|
|
: m_Value( orig.m_Value )
|
|
|
|
{
|
|
|
|
assert(std::numeric_limits<T>::min() <= orig.m_Value);
|
|
|
|
assert(orig.m_Value <= std::numeric_limits<T>::max());
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
template<typename V> LIMITED_INT( const double v )
|
|
|
|
: m_Value( floor(v+0.5) )
|
|
|
|
{
|
|
|
|
assert(std::numeric_limits<T>::min() <= v);
|
|
|
|
assert(v <= std::numeric_limits<T>::max());
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT( T v ): m_Value( v )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
operator T( void ) const
|
|
|
|
{
|
|
|
|
return m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
operator double( void ) const
|
|
|
|
{
|
|
|
|
return ( double )m_Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LIMITED_INT<T> & operator = ( LIMITED_INT< T > src )
|
|
|
|
{
|
|
|
|
m_Value = src.m_Value;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT<T> & operator = ( T src )
|
|
|
|
{
|
|
|
|
m_Value = src;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
/*************************/
|
|
|
|
/* comparisons and tests */
|
|
|
|
/*************************/
|
|
|
|
bool operator ! (void) const {
|
|
|
|
return !m_Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator == ( const LIMITED_INT< T > &y ) const
|
|
|
|
{
|
|
|
|
return m_Value == y.m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator == ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value == y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator != ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value != y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator < ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value < y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator >= ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value >= y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator > ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value > y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
bool operator <= ( const T y ) const
|
|
|
|
{
|
|
|
|
return m_Value <= y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T > operator + ( const T y ) const
|
|
|
|
{
|
|
|
|
return *this + LIMITED_INT< T >( y );
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend LIMITED_INT< T > operator + ( const T x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return LIMITED_INT< T >( x ) + y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
double operator + ( const double y ) const
|
|
|
|
{
|
|
|
|
return double( m_Value ) + y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend double operator + ( const double x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return x + double( y.m_Value );
|
|
|
|
}
|
|
|
|
|
2011-11-11 17:44:20 +00:00
|
|
|
LIMITED_INT< T > operator - ( void ) const
|
|
|
|
{
|
|
|
|
assert( -std::numeric_limits< T >::max() <= m_Value );
|
|
|
|
return -m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T > operator - ( const T y ) const
|
|
|
|
{
|
|
|
|
return *this - LIMITED_INT< T >( y );
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend LIMITED_INT< T > operator - ( const T x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return LIMITED_INT< T >( x ) - y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
double operator - ( const double y ) const
|
|
|
|
{
|
|
|
|
return double( m_Value ) - y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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<T>::max() / m_Value );
|
|
|
|
assert( !( 0 < m_Value && y.m_Value < 0 )
|
|
|
|
|| std::numeric_limits<T>::min() / m_Value <= y.m_Value );
|
|
|
|
assert( !( m_Value < 0 && 0 < y.m_Value )
|
|
|
|
|| std::numeric_limits<T>::min() / y.m_Value <= m_Value );
|
|
|
|
assert( !( m_Value < 0 && y.m_Value < 0 )
|
|
|
|
|| std::numeric_limits<T>::max() / m_Value <= y.m_Value );
|
|
|
|
return m_Value * y.m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT<T> operator * ( const T y) const
|
|
|
|
{
|
|
|
|
return *this * LIMITED_INT< T >( y );
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend LIMITED_INT< T > operator *( const T x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return LIMITED_INT< T >( x ) * y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
double operator * ( const double y ) const
|
|
|
|
{
|
|
|
|
return double( m_Value ) * y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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( !( -1 == y.m_Value )
|
|
|
|
|| -std::numeric_limits< T >::max() <= m_Value );
|
|
|
|
return m_Value / y.m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT<T> operator / ( const T y ) const
|
|
|
|
{
|
|
|
|
return *this / LIMITED_INT<T>(y);
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend LIMITED_INT< T > operator / ( const T x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return LIMITED_INT< T >( x ) / y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
double operator / ( const double y ) const
|
|
|
|
{
|
|
|
|
return double( m_Value ) / y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
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
|
|
|
|
{
|
|
|
|
return m_Value % y.m_Value;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT<T> operator % ( const T y ) const
|
|
|
|
{
|
|
|
|
return *this % LIMITED_INT<T>(y);
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
friend LIMITED_INT< T > operator % ( const T x, const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
return LIMITED_INT< T >( x ) % y;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator += ( const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
*this = *this + y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator += ( const T y )
|
|
|
|
{
|
|
|
|
*this = *this + y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator ++ ( void )
|
|
|
|
{
|
|
|
|
*this = *this + 1;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator -= ( const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
*this = *this - y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator -= ( const T y )
|
|
|
|
{
|
|
|
|
*this = *this - y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator -- ( void )
|
|
|
|
{
|
|
|
|
*this = *this - 1;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator *= ( const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
*this = *this * y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator *= ( const T y )
|
|
|
|
{
|
|
|
|
*this = *this * y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator /= ( const LIMITED_INT< T > &y )
|
|
|
|
{
|
|
|
|
*this = *this / y;
|
|
|
|
return *this;
|
|
|
|
}
|
2011-11-15 18:26:06 +00:00
|
|
|
|
2011-11-09 13:25:49 +00:00
|
|
|
LIMITED_INT< T >& operator /= ( const T y )
|
|
|
|
{
|
|
|
|
*this = *this / y;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* def LIMITED_INT_H_INCLUDED*/
|