diff --git a/include/fc/datastream.hpp b/include/fc/datastream.hpp index 806973d..8a1eb11 100644 --- a/include/fc/datastream.hpp +++ b/include/fc/datastream.hpp @@ -15,75 +15,75 @@ namespace fc { */ template struct datastream { - datastream( T start, uint32_t s ) - :m_start(start),m_pos(start),m_end(start+s){}; - - template - inline datastream& operator<<(const DATA& d) { - static_assert( !fc::is_class::value, "no serialization defined" ); - write( (const char*)&d, sizeof(d) ); - return *this; - } - - template - inline datastream& operator>>(DATA& d) { - static_assert( !fc::is_class::value, "no serialization defined" ); - read((char*)&d, sizeof(d) ); - return *this; - } - - inline void skip( uint32_t s ){ m_pos += s; } - inline bool read( char* d, uint32_t s ) { - if( m_end - m_pos >= (int32_t)s ) { - memcpy( d, m_pos, s ); - m_pos += s; - return true; - } - FC_THROW( "Attempt to read %d bytes beyond end of buffer of size %d", -((m_end-m_pos) - s),(m_end-m_start) ); - return false; - } - - inline bool write( const char* d, uint32_t s ) { - if( m_end - m_pos >= (int32_t)s ) { - memcpy( m_pos, d, s ); - m_pos += s; - return true; - } - FC_THROW( "Attempt to write %d bytes beyond end of buffer of size %d",%-((m_end-m_pos) - s),(m_end-m_start) ); - return false; - } - - inline bool put(char c) { - if( m_pos < m_end ) { - *m_pos = c; - ++m_pos; - return true; - } - FC_THROW( "Attempt to write %d byte beyond end of buffer of size %d", -((m_end-m_pos) - 1), (m_end-m_start) ); - return false; - } - - inline bool get( unsigned char& c ) { return get( *(char*)&c ); } - inline bool get( char& c ) { - if( m_pos < m_end ) { - c = *m_pos; - ++m_pos; - return true; - } - FC_THROW( "Attempt to read %d byte beyond end of buffer of size %d", -((m_end-m_pos) - 1), (m_end-m_start) ); - ++m_pos; - return false; - } - - T pos()const { return m_pos; } - inline bool valid()const { return m_pos <= m_end && m_pos >= m_start; } - inline bool seekp(uint32_t p) { m_pos = m_start + p; return m_pos <= m_end; } - inline uint32_t tellp()const { return m_pos - m_start; } - inline uint32_t remaining()const { return m_end - m_pos; } -private: - T m_start; - T m_pos; - T m_end; + datastream( T start, uint32_t s ) + :m_start(start),m_pos(start),m_end(start+s){}; + + template + inline datastream& operator<<(const DATA& d) { + static_assert( !fc::is_class::type::value, "no serialization defined" ); + write( (const char*)&d, sizeof(d) ); + return *this; + } + + template + inline datastream& operator>>(DATA& d) { + static_assert( !fc::is_class::type::value, "no serialization defined" ); + read((char*)&d, sizeof(d) ); + return *this; + } + + inline void skip( uint32_t s ){ m_pos += s; } + inline bool read( char* d, uint32_t s ) { + if( m_end - m_pos >= (int32_t)s ) { + memcpy( d, m_pos, s ); + m_pos += s; + return true; + } + FC_THROW_MSG( "Attempt to read %s bytes beyond end of buffer of size %s", -((m_end-m_pos) - s),(m_end-m_start) ); + return false; + } + + inline bool write( const char* d, uint32_t s ) { + if( m_end - m_pos >= (int32_t)s ) { + memcpy( m_pos, d, s ); + m_pos += s; + return true; + } + FC_THROW_MSG( "Attempt to write %s bytes beyond end of buffer of size %s", -((m_end-m_pos) - s),(m_end-m_start) ); + return false; + } + + inline bool put(char c) { + if( m_pos < m_end ) { + *m_pos = c; + ++m_pos; + return true; + } + FC_THROW_MSG( "Attempt to write %s byte beyond end of buffer of size %s", -((m_end-m_pos) - 1), (m_end-m_start) ); + return false; + } + + inline bool get( unsigned char& c ) { return get( *(char*)&c ); } + inline bool get( char& c ) { + if( m_pos < m_end ) { + c = *m_pos; + ++m_pos; + return true; + } + FC_THROW_MSG( "Attempt to read %s byte beyond end of buffer of size %s", -((m_end-m_pos) - 1), (m_end-m_start) ); + ++m_pos; + return false; + } + + T pos()const { return m_pos; } + inline bool valid()const { return m_pos <= m_end && m_pos >= m_start; } + inline bool seekp(uint32_t p) { m_pos = m_start + p; return m_pos <= m_end; } + inline uint32_t tellp()const { return m_pos - m_start; } + inline uint32_t remaining()const { return m_end - m_pos; } + private: + T m_start; + T m_pos; + T m_end; }; template<> @@ -91,7 +91,7 @@ struct datastream { datastream( size_t init_size = 0):m_size(init_size){}; template inline datastream& operator<<(const DATA& d) { - static_assert( !fc::is_class::value, "no serialzation defined" ); + static_assert( !fc::is_class::type::value, "no serialzation defined" ); m_size += sizeof(d); return *this; } diff --git a/include/fc/exception.hpp b/include/fc/exception.hpp index 8eabf9f..6540e29 100644 --- a/include/fc/exception.hpp +++ b/include/fc/exception.hpp @@ -2,11 +2,10 @@ #define _FC_EXCEPTION_HPP_ #include #include +#include // TODO: Remove boost exception dependency here!! // TODO: Remove boost format dependency here!! -#include -#include // provided for easy integration with boost. namespace boost { class exception_ptr; } @@ -51,18 +50,46 @@ namespace fc { } void rethrow_exception( const exception_ptr& e ); + void throw_exception( const char* func, const char* file, int line, const char* msg ); + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1 ); + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2 ); + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2, const fc::string& a3 ); + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2, const fc::string& a3, const fc::string& a4 ); + + template + fc::string to_string( T&& v ) { return fc::string(fc::forward(v)); } + fc::string to_string( char v ); // { return fc::string(&v,1); } + fc::string to_string( uint64_t v ); + fc::string to_string( int64_t v ); + fc::string to_string( double v ); + fc::string to_string( float v ); + fc::string to_string( int32_t v ); + fc::string to_string( uint32_t v ); + fc::string to_string( int16_t v ); + fc::string to_string( uint16_t v ); + fc::string to_string( size_t v ); + fc::string to_string( long int v ); + + template + void throw_exception( const char* func, const char* file, int line, const char* msg, T&& a1 ) { + throw_exception( func, file, line, msg, to_string(fc::forward(a1) ) ); + } + + template + void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2 ) { + throw_exception( func, file, line, msg, to_string(fc::forward(a1) ), to_string( fc::forward(a2) ) ); + } + - typedef boost::error_info err_msg; - struct exception : public virtual boost::exception, public virtual std::exception { - const char* what()const throw() { return "exception"; } - virtual void rethrow()const { BOOST_THROW_EXCEPTION(*this); } - const std::string& message()const { return *boost::get_error_info(*this); } - }; } // namespace fc -#define FC_THROW(X,...) throw X -#define FC_THROW_MSG( MSG, ... ) \ +#define FC_THROW(X) throw X +#define FC_THROW_MSG( ... ) \ do { \ - BOOST_THROW_EXCEPTION( fc::exception() << fc::err_msg( (boost::format( MSG ) __VA_ARGS__ ).str() ) );\ + fc::throw_exception( BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, __VA_ARGS__ ); \ } while(0) diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp index bc2bc62..fb4b5a7 100644 --- a/include/fc/optional.hpp +++ b/include/fc/optional.hpp @@ -64,7 +64,7 @@ namespace fc { private: // force alignment... to 8 byte boundaries - double _value[(sizeof(T)+sizeof(double)-1)/sizeof(double)]; + double _value[8 * ((sizeof(T)+7)/8)]; bool _valid; }; diff --git a/include/fc/reflect.hpp b/include/fc/reflect.hpp index e9cdd63..8b2ce10 100644 --- a/include/fc/reflect.hpp +++ b/include/fc/reflect.hpp @@ -169,6 +169,7 @@ namespace fc { template class reflector : public detail::reflector_impl >{ public: + enum _is_defined { is_defined = 0 }; virtual const char* name()const { return get_typename::name(); } virtual void visit( void* s, const abstract_visitor& v )const { v.visit( *((T*)s) ); diff --git a/include/fc/reflect_fwd.hpp b/include/fc/reflect_fwd.hpp index b91149d..6481ffb 100644 --- a/include/fc/reflect_fwd.hpp +++ b/include/fc/reflect_fwd.hpp @@ -21,6 +21,7 @@ namespace fc { namespace fc{ \ template<> class reflector : virtual public detail::reflector_impl > { \ public:\ + enum _is_defined { is_defined = 1 }; \ virtual const char* name()const; \ virtual void visit( void* s, const abstract_visitor& v )const; \ virtual void visit( const void* s, const abstract_const_visitor& v )const; \ diff --git a/include/fc/static_reflect.hpp b/include/fc/static_reflect.hpp index 4fb189b..b8b69e5 100644 --- a/include/fc/static_reflect.hpp +++ b/include/fc/static_reflect.hpp @@ -1,6 +1,6 @@ /** - * @file mace/reflect/reflect.hpp + * @file fc/static_reflect.hpp * * @brief Defines types and macros used to provide reflection. * @@ -16,28 +16,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include + //#include //#include -namespace mace { -/** - * @brief types, methods associated with the MACE.Reflect Library - */ -namespace reflect { +namespace fc { /** * @brief defines visit functions for T @@ -49,11 +34,10 @@ namespace reflect { * class for your type. */ template -struct reflector{ +struct static_reflector{ typedef T type; - typedef boost::fusion::vector<> base_class_types; - typedef boost::false_type is_defined; - typedef boost::false_type is_enum; + typedef fc::false_type is_defined; + typedef fc::false_type is_enum; /** * @tparam Visitor a function object of the form: @@ -83,7 +67,7 @@ struct reflector{ #endif // DOXYGEN }; -} } // namespace mace::reflect + } // namespace fc #ifndef DOXYGEN @@ -97,9 +81,9 @@ struct reflector{ #else #define TEMPLATE #endif - +#include #define FC_STATIC_REFLECT_VISIT_MEMBER( r, visitor, elem ) \ - visitor.TEMPLATE operator()( BOOST_PP_STRINGIZE(elem) ); + visitor.TEMPLATE operator()elem), type, &type::elem>( BOOST_PP_STRINGIZE(elem) ); #define FC_STATIC_REFLECT_BASE_MEMBER_COUNT( r, OP, elem ) \ @@ -131,12 +115,10 @@ void fc::static_reflector::visit( const Visitor& v ) { \ if( strcmp( s, BOOST_PP_STRINGIZE(elem) ) == 0 ) return elem; #define FC_STATIC_REFLECT_ENUM( ENUM, FIELDS ) \ -FC_STATIC_REFLECT_TYPEINFO(ENUM) \ -namespace mace { namespace reflect { \ -template<> struct reflector { \ - typedef boost::true_type is_defined; \ - typedef boost::true_type is_enum; \ - typedef boost::fusion::vector<> base_class_types; \ +namespace fc { \ +template<> struct static_reflector { \ + typedef fc::true_type is_defined; \ + typedef fc::true_type is_enum; \ template \ static inline void visit( const Visitor& v ) { \ BOOST_PP_SEQ_FOR_EACH( FC_STATIC_REFLECT_VISIT_ENUM, v, FIELDS ) \ @@ -145,12 +127,12 @@ template<> struct reflector { \ switch( ENUM(i) ) { \ BOOST_PP_SEQ_FOR_EACH( FC_STATIC_REFLECT_ENUM_TO_STRING, v, FIELDS ) \ default: \ - FC_STATIC_REFLECT_THROW( mace::reflect::unknown_field(), "%1% not in enum '%2%'", %i %BOOST_PP_STRINGIZE(ENUM) ); \ + FC_STATIC_REFLECT_THROW( fc::reflect::unknown_field(), "%1% not in enum '%2%'", %i %BOOST_PP_STRINGIZE(ENUM) ); \ }\ } \ static ENUM from_string( const char* s ) { \ BOOST_PP_SEQ_FOR_EACH( FC_STATIC_REFLECT_ENUM_FROM_STRING, v, FIELDS ) \ - FC_STATIC_REFLECT_THROW( mace::reflect::unknown_field(), "%1% in enum %2%", %s %BOOST_PP_STRINGIZE(ENUM) ); \ + FC_STATIC_REFLECT_THROW( fc::reflect::unknown_field(), "%1% in enum %2%", %s %BOOST_PP_STRINGIZE(ENUM) ); \ } \ }; \ } } @@ -167,12 +149,11 @@ template<> struct reflector { \ * @param MEMBERS - a sequence of member names. (field1)(field2)(field3) */ #define FC_STATIC_REFLECT_DERIVED( TYPE, INHERITS, MEMBERS ) \ -FC_STATIC_REFLECT_TYPEINFO(TYPE) \ namespace fc { \ template<> struct static_reflector {\ typedef TYPE type; \ - typedef boost::true_type is_defined; \ - typedef boost::false_type is_enum; \ + typedef fc::true_type is_defined; \ + typedef fc::false_type is_enum; \ enum member_count_enum { \ local_member_count = BOOST_PP_SEQ_SIZE(MEMBERS), \ total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_STATIC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\ @@ -193,18 +174,16 @@ template<> struct static_reflector {\ FC_STATIC_REFLECT_DERIVED( TYPE, BOOST_PP_SEQ_NIL, MEMBERS ) #define FC_STATIC_REFLECT_FWD( TYPE ) \ -FC_STATIC_REFLECT_TYPEINFO(TYPE) \ -namespace mace { namespace reflect { \ +namespace fc { \ template<> struct static_reflector {\ typedef TYPE type; \ - typedef boost::true_type is_defined; \ + typedef fc::true_type is_defined; \ enum member_count_enum { \ local_member_count = BOOST_PP_SEQ_SIZE(MEMBERS), \ total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_STATIC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\ }; \ - typedef boost::fusion::vector base_class_types; \ template static void visit( const Visitor& v ); \ -}; } } +}; } #define FC_STATIC_REFLECT_DERIVED_IMPL( TYPE, MEMBERS ) \ diff --git a/include/fc/string.hpp b/include/fc/string.hpp index 352957f..9753ad1 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -20,6 +20,7 @@ namespace fc { string( const string& c ); string( string&& c ); string( const char* c ); + string( const char* c, int s ); string( const_iterator b, const_iterator e ); ~string(); diff --git a/include/fc/utility.hpp b/include/fc/utility.hpp index 0d3159c..02463a5 100644 --- a/include/fc/utility.hpp +++ b/include/fc/utility.hpp @@ -22,14 +22,16 @@ namespace fc { template inline T&& forward( U&& u ) { return static_cast(u); } + struct true_type { enum _value { value = 1 }; }; + struct false_type { enum _value { value = 0 }; }; + namespace detail { - template char is_class_helper(void(T::*)()); - template double is_class_helper(...); + template fc::true_type is_class_helper(void(T::*)()); + template fc::false_type is_class_helper(...); } + template - struct is_class { - enum { value = sizeof(char) == sizeof(detail::is_class_helper(0)) }; - }; + struct is_class { typedef decltype(detail::is_class_helper(0)) type; }; template void swap( T& a, T& b ) { diff --git a/include/fc/vector.hpp b/include/fc/vector.hpp index 89cadaf..99fe3d5 100644 --- a/include/fc/vector.hpp +++ b/include/fc/vector.hpp @@ -52,7 +52,7 @@ namespace fc { data(){}; }; - template + template struct vector_impl { public: vector_impl():_data(nullptr){} @@ -170,7 +170,7 @@ namespace fc { }; template - class vector_impl { + class vector_impl { public: vector_impl():_data(nullptr){} vector_impl( vector_impl&& c):_data(c._data){c._data =nullptr; } @@ -338,12 +338,12 @@ namespace fc { } template - class vector : public detail::vector_impl::value> { + class vector : public detail::vector_impl::type> { public: vector(){} - vector( uint64_t s ):detail::vector_impl::value>(s){} - vector( const vector& v ):detail::vector_impl::value>(v){} - vector( vector&& v ):detail::vector_impl::value>(fc::move(v)){} + vector( uint64_t s ):detail::vector_impl::type>(s){} + vector( const vector& v ):detail::vector_impl::type>(v){} + vector( vector&& v ):detail::vector_impl::type>(fc::move(v)){} vector& operator=( vector&& v ) { *((base*)this) = fc::move(v); @@ -354,7 +354,7 @@ namespace fc { return *this; } private: - typedef detail::vector_impl::value> base; + typedef detail::vector_impl::type> base; }; }; diff --git a/src/exception.cpp b/src/exception.cpp index 3b8bc6a..70537f1 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include namespace fc { #define bexcept void* e = &my[0]; (*((boost::exception_ptr*)e)) @@ -66,4 +68,38 @@ namespace fc { const void* e = &my[0]; return (*((boost::exception_ptr*)e)); } + + + fc::string to_string( char v ) { return fc::string(&v,1); } + fc::string to_string( uint64_t v ) { return boost::lexical_cast(v).c_str(); } + fc::string to_string( int64_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( double v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( float v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( int32_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( uint32_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( int16_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( uint16_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( size_t v ){ return boost::lexical_cast(v).c_str(); } + fc::string to_string( long int v ){ return boost::lexical_cast(v).c_str(); } + + void throw_exception( const char* func, const char* file, int line, const char* msg ) { + ::boost::exception_detail::throw_exception_(fc::generic_exception(msg),func, file, line ); + } + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1 ) { + ::boost::exception_detail::throw_exception_(fc::generic_exception(msg),func, file, line ); + } + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2 ) { + ::boost::exception_detail::throw_exception_(fc::generic_exception(msg),func, file, line ); + } + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2, const fc::string& a3 ) { + ::boost::exception_detail::throw_exception_(fc::generic_exception(msg),func, file, line ); + } + void throw_exception( const char* func, const char* file, int line, const char* msg, + const fc::string& a1, const fc::string& a2, const fc::string& a3, const fc::string& a4 ) { + ::boost::exception_detail::throw_exception_(fc::generic_exception(msg),func, file, line ); + } + } diff --git a/src/hex.cpp b/src/hex.cpp index 5904cab..ac51309 100644 --- a/src/hex.cpp +++ b/src/hex.cpp @@ -10,7 +10,7 @@ namespace fc { return c - 'a' + 10; if( c >= 'A' && c <= 'F' ) return c - 'A' + 10; - FC_THROW( "Invalid hex character '%c'", c ); + FC_THROW_MSG( "Invalid hex character '%s'", c ); return 0; } diff --git a/src/string.cpp b/src/string.cpp index 4504e50..0e2d6f5 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -15,6 +15,10 @@ namespace detail { namespace fc { + string::string(const char* s, int l) { + static_assert( sizeof(*this) >= sizeof(std::string), "failed to reserve enough space" ); + new (this) std::string(s,l); + } string::string() { static_assert( sizeof(*this) >= sizeof(std::string), "failed to reserve enough space" ); new (this) std::string();