#pragma once #include #include namespace fc { template void to_variant( const T& o, variant& v, uint32_t max_depth ); template void from_variant( const variant& v, T& o, uint32_t max_depth ); template class to_variant_visitor { public: to_variant_visitor( mutable_variant_object& mvo, const T& v, uint32_t max_depth ) :vo(mvo),val(v),_max_depth(max_depth - 1) { _FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" ); } template void operator()( const char* name )const { this->add(vo,name,(val.*member)); } private: template void add( mutable_variant_object& vo, const char* name, const optional& v )const { if( v.valid() ) vo(name, variant( *v, _max_depth )); } template void add( mutable_variant_object& vo, const char* name, const M& v )const { vo(name, variant( v, _max_depth )); } mutable_variant_object& vo; const T& val; const uint32_t _max_depth; }; template class from_variant_visitor { public: from_variant_visitor( const variant_object& _vo, T& v, uint32_t max_depth ) :vo(_vo),val(v),_max_depth(max_depth - 1) { _FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" ); } template void operator()( const char* name )const { auto itr = vo.find(name); if( itr != vo.end() ) from_variant( itr->value(), val.*member, _max_depth ); } const variant_object& vo; T& val; const uint32_t _max_depth; }; template struct if_enum { template static inline void to_variant( const T& v, fc::variant& vo, uint32_t max_depth ) { mutable_variant_object mvo; fc::reflector::visit( to_variant_visitor( mvo, v, max_depth ) ); vo = fc::move(mvo); } template static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth ) { const variant_object& vo = v.get_object(); fc::reflector::visit( from_variant_visitor( vo, o, max_depth ) ); } }; template<> struct if_enum { template static inline void to_variant( const T& o, fc::variant& v, uint32_t max_depth = 1 ) { v = fc::reflector::to_fc_string(o); } template static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth = 1 ) { if( v.is_string() ) o = fc::reflector::from_string( v.get_string().c_str() ); else o = fc::reflector::from_int( v.as_int64() ); } }; template void to_variant( const T& o, variant& v, uint32_t max_depth ) { if_enum::is_enum>::to_variant( o, v, max_depth ); } template void from_variant( const variant& v, T& o, uint32_t max_depth ) { if_enum::is_enum>::from_variant( v, o, max_depth ); } }