From 72088c548be873e5921edb82ed516a0b37ca378e Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Fri, 31 Oct 2014 16:30:18 -0400 Subject: [PATCH] Tweak FC enum reflection Previously when enum values not defined in the original enum type were used in serialized objects, FC threw exceptions when it encountered these values. Now it just serializes unknown values to and from numbers instead of names. As an added benefit, the compiler now warns you if a value is defined in the enum, but not reflected! --- include/fc/reflect/reflect.hpp | 25 +++++++++++++++---------- include/fc/reflect/variant.hpp | 5 ++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/fc/reflect/reflect.hpp b/include/fc/reflect/reflect.hpp index 361a646..4deea27 100644 --- a/include/fc/reflect/reflect.hpp +++ b/include/fc/reflect/reflect.hpp @@ -114,6 +114,8 @@ void fc::reflector::visit( const Visitor& v ) { \ v.TEMPLATE operator()(BOOST_PP_STRINGIZE(elem)); #define FC_REFLECT_ENUM_TO_STRING( r, enum_type, elem ) \ case enum_type::elem: return BOOST_PP_STRINGIZE(elem); +#define FC_REFLECT_ENUM_TO_FC_STRING( r, enum_type, elem ) \ + case enum_type::elem: return fc::string(BOOST_PP_STRINGIZE(elem)); #define FC_REFLECT_ENUM_FROM_STRING( r, enum_type, elem ) \ if( strcmp( s, BOOST_PP_STRINGIZE(elem) ) == 0 ) return enum_type::elem; @@ -124,14 +126,6 @@ namespace fc { \ template<> struct reflector { \ typedef fc::true_type is_defined; \ typedef fc::true_type is_enum; \ - static const char* to_string(int64_t i) { \ - switch( ENUM(i) ) { \ - BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \ - default: \ - fc::throw_bad_enum_cast( i, BOOST_PP_STRINGIZE(ENUM) ); \ - }\ - return nullptr; \ - } \ static const char* to_string(ENUM elem) { \ switch( elem ) { \ BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \ @@ -140,10 +134,21 @@ template<> struct reflector { \ }\ return nullptr; \ } \ + static const char* to_string(int64_t i) { \ + return to_string(ENUM(i)); \ + } \ + static fc::string to_fc_string(ENUM elem) { \ + switch( elem ) { \ + BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_FC_STRING, ENUM, FIELDS ) \ + } \ + return fc::to_string(int64_t(elem)); \ + } \ + static fc::string to_fc_string(int64_t i) { \ + return to_fc_string(ENUM(i)); \ + } \ static ENUM from_string( const char* s ) { \ BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_FROM_STRING, ENUM, FIELDS ) \ - fc::throw_bad_enum_cast( s, BOOST_PP_STRINGIZE(ENUM) ); \ - return ENUM();\ + return ENUM(atoi(s));\ } \ }; \ } diff --git a/include/fc/reflect/variant.hpp b/include/fc/reflect/variant.hpp index 0c41de1..bc14fc4 100644 --- a/include/fc/reflect/variant.hpp +++ b/include/fc/reflect/variant.hpp @@ -70,7 +70,7 @@ namespace fc template static inline void to_variant( const T& o, fc::variant& v ) { - v = fc::reflector::to_string(o); + v = fc::reflector::to_fc_string(o); } template static inline void from_variant( const fc::variant& v, T& o ) @@ -78,8 +78,7 @@ namespace fc if( v.is_string() ) o = fc::reflector::from_string( v.get_string().c_str() ); else - // throw if invalid int, by attempting to convert to string - fc::reflector::to_string( o = static_cast(v.as_int64()) ); + o = static_cast(v.as_int64()); } };