added type for safe int ops
This commit is contained in:
parent
cf4ed08d4b
commit
ec66863902
7 changed files with 101 additions and 2 deletions
|
|
@ -84,3 +84,5 @@ namespace std
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#include <fc/reflect/reflect.hpp>
|
||||||
|
FC_REFLECT_TYPENAME( fc::sha224 )
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,9 @@ namespace fc
|
||||||
unknown_host_exception_code = 15,
|
unknown_host_exception_code = 15,
|
||||||
null_optional_code = 16,
|
null_optional_code = 16,
|
||||||
udt_error_code = 17,
|
udt_error_code = 17,
|
||||||
aes_error_code = 18
|
aes_error_code = 18,
|
||||||
|
overflow_code = 19,
|
||||||
|
underflow_code = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -285,6 +287,8 @@ namespace fc
|
||||||
FC_DECLARE_EXCEPTION( null_optional, null_optional_code, "null optional" );
|
FC_DECLARE_EXCEPTION( null_optional, null_optional_code, "null optional" );
|
||||||
FC_DECLARE_EXCEPTION( udt_exception, udt_error_code, "UDT error" );
|
FC_DECLARE_EXCEPTION( udt_exception, udt_error_code, "UDT error" );
|
||||||
FC_DECLARE_EXCEPTION( aes_exception, aes_error_code, "AES error" );
|
FC_DECLARE_EXCEPTION( aes_exception, aes_error_code, "AES error" );
|
||||||
|
FC_DECLARE_EXCEPTION( overflow_exception, overflow_code, "Integer Overflow" );
|
||||||
|
FC_DECLARE_EXCEPTION( underflow_exception, underflow_code, "Integer Underflow" );
|
||||||
|
|
||||||
std::string except_str();
|
std::string except_str();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <fc/time.hpp>
|
#include <fc/time.hpp>
|
||||||
#include <fc/filesystem.hpp>
|
#include <fc/filesystem.hpp>
|
||||||
#include <fc/exception/exception.hpp>
|
#include <fc/exception/exception.hpp>
|
||||||
|
#include <fc/safe.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#define MAX_ARRAY_ALLOC_SIZE (1024*1024*10)
|
#define MAX_ARRAY_ALLOC_SIZE (1024*1024*10)
|
||||||
|
|
@ -162,11 +163,24 @@ namespace fc {
|
||||||
vi.value = static_cast<uint32_t>(v);
|
vi.value = static_cast<uint32_t>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
|
||||||
|
{
|
||||||
|
T tmp;
|
||||||
|
unpack( s, tmp );
|
||||||
|
FC_ASSERT( vi == tmp );
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, fc::string(v) ); }
|
template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, fc::string(v) ); }
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
void pack( Stream& s, const safe<T>& v ) { pack( s, v.value ); }
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
void unpack( Stream& s, fc::safe<T>& v ) { unpack( s, v.value ); }
|
||||||
|
|
||||||
// optional
|
// optional
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void pack( Stream& s, const fc::optional<T>& v ) {
|
void pack( Stream& s, const fc::optional<T>& v ) {
|
||||||
pack( s, bool(!!v) );
|
pack( s, bool(!!v) );
|
||||||
if( !!v ) pack( s, *v );
|
if( !!v ) pack( s, *v );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <fc/io/varint.hpp>
|
#include <fc/io/varint.hpp>
|
||||||
#include <fc/array.hpp>
|
#include <fc/array.hpp>
|
||||||
|
#include <fc/safe.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
@ -48,7 +49,10 @@ namespace fc {
|
||||||
|
|
||||||
|
|
||||||
template<typename Stream, typename T> void unpack( Stream& s, fc::optional<T>& v );
|
template<typename Stream, typename T> void unpack( Stream& s, fc::optional<T>& v );
|
||||||
|
template<typename Stream, typename T> void unpack( Stream& s, const T& v );
|
||||||
template<typename Stream, typename T> void pack( Stream& s, const fc::optional<T>& v );
|
template<typename Stream, typename T> void pack( Stream& s, const fc::optional<T>& v );
|
||||||
|
template<typename Stream, typename T> void pack( Stream& s, const safe<T>& v );
|
||||||
|
template<typename Stream, typename T> void unpack( Stream& s, fc::safe<T>& v );
|
||||||
|
|
||||||
template<typename Stream> void unpack( Stream& s, time_point& );
|
template<typename Stream> void unpack( Stream& s, time_point& );
|
||||||
template<typename Stream> void pack( Stream& s, const time_point& );
|
template<typename Stream> void pack( Stream& s, const time_point& );
|
||||||
|
|
|
||||||
64
include/fc/safe.hpp
Normal file
64
include/fc/safe.hpp
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fc/exception/exception.hpp>
|
||||||
|
|
||||||
|
namespace fc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is designed to provide automatic checks for
|
||||||
|
* integer overflow and default initialization. It will
|
||||||
|
* throw an exception on overflow conditions.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
struct safe
|
||||||
|
{
|
||||||
|
template<typename O>
|
||||||
|
safe( O o ):value(o){}
|
||||||
|
safe(){}
|
||||||
|
safe( const safe& o ):value(o.value){}
|
||||||
|
|
||||||
|
|
||||||
|
safe& operator += ( const safe& b )
|
||||||
|
{
|
||||||
|
if( b.value > 0 && value > (std::numeric_limits<T>::max() - b.value) ) FC_CAPTURE_AND_THROW( overflow_exception, (*this)(b) );
|
||||||
|
if( b.value < 0 && value < (std::numeric_limits<T>::min() - b.value) ) FC_CAPTURE_AND_THROW( underflow_exception, (*this)(b) );
|
||||||
|
value += b.value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
friend safe operator + ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
if( b.value > 0 && a.value > std::numeric_limits<T>::max() - b.value ) FC_CAPTURE_AND_THROW( overflow_exception, (a)(b) );
|
||||||
|
if( b.value < 0 && a.value < std::numeric_limits<T>::min() - b.value ) FC_CAPTURE_AND_THROW( underflow_exception, (a)(b) );
|
||||||
|
return safe(a.value+b.value);
|
||||||
|
}
|
||||||
|
safe& operator -= ( const safe& b ) { return *this += safe(-b.value); }
|
||||||
|
safe operator -()const{ return safe(-value); }
|
||||||
|
|
||||||
|
friend safe operator - ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
safe tmp(a); tmp -= b; return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator == ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
return a.value == b.value;
|
||||||
|
}
|
||||||
|
friend bool operator < ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
return a.value < b.value;
|
||||||
|
}
|
||||||
|
friend bool operator > ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
return a.value > b.value;
|
||||||
|
}
|
||||||
|
friend bool operator >= ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
return a.value >= b.value;
|
||||||
|
}
|
||||||
|
friend bool operator <= ( const safe& a, const safe& b )
|
||||||
|
{
|
||||||
|
return a.value <= b.value;
|
||||||
|
}
|
||||||
|
T value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -30,11 +30,14 @@ namespace fc
|
||||||
class time_point;
|
class time_point;
|
||||||
class time_point_sec;
|
class time_point_sec;
|
||||||
class microseconds;
|
class microseconds;
|
||||||
|
template<typename T> struct safe;
|
||||||
|
|
||||||
struct blob { std::vector<char> data; };
|
struct blob { std::vector<char> data; };
|
||||||
|
|
||||||
void to_variant( const blob& var, variant& vo );
|
void to_variant( const blob& var, variant& vo );
|
||||||
void from_variant( const variant& var, blob& vo );
|
void from_variant( const variant& var, blob& vo );
|
||||||
|
template<typename T> void to_variant( const safe<T>& s, variant& v );
|
||||||
|
template<typename T> void from_variant( const variant& v, safe<T>& s );
|
||||||
|
|
||||||
void to_variant( const uint8_t& var, variant& vo );
|
void to_variant( const uint8_t& var, variant& vo );
|
||||||
void from_variant( const variant& var, uint8_t& vo );
|
void from_variant( const variant& var, uint8_t& vo );
|
||||||
|
|
@ -111,6 +114,7 @@ namespace fc
|
||||||
void from_variant( const variant& v, std::pair<A,B>& p );
|
void from_variant( const variant& v, std::pair<A,B>& p );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
|
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
|
||||||
* and variant_object's.
|
* and variant_object's.
|
||||||
|
|
@ -480,6 +484,11 @@ namespace fc
|
||||||
from_variant( var, *vo );
|
from_variant( var, *vo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
void to_variant( const safe<T>& s, variant& v ) { v = s.value; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void from_variant( const variant& v, safe<T>& s ) { s.value = v.as_uint64(); }
|
||||||
|
|
||||||
variant operator + ( const variant& a, const variant& b );
|
variant operator + ( const variant& a, const variant& b );
|
||||||
variant operator - ( const variant& a, const variant& b );
|
variant operator - ( const variant& a, const variant& b );
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ namespace fc
|
||||||
(null_optional)
|
(null_optional)
|
||||||
(udt_exception)
|
(udt_exception)
|
||||||
(aes_exception)
|
(aes_exception)
|
||||||
|
(overflow_exception)
|
||||||
|
(underflow_exception)
|
||||||
)
|
)
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue