10 #include <boost/lexical_cast.hpp> 11 #include <boost/preprocessor/seq/for_each.hpp> 12 #include <boost/preprocessor/seq/enum.hpp> 13 #include <boost/preprocessor/seq/size.hpp> 14 #include <boost/preprocessor/seq/seq.hpp> 15 #include <boost/preprocessor/stringize.hpp> 18 #include <type_traits> 26 namespace member_names {
28 template<
typename Class, std::
size_t index>
struct member_name {
29 constexpr
static const char*
value =
"Unknown member";
40 template<std::
size_t Index,
typename Container,
typename Member, Member Container::*field>
45 constexpr
static std::size_t
index = Index;
46 constexpr
static bool is_derived =
false;
57 template<std::
size_t IndexInBase,
typename Base,
typename Derived,
typename Member, Member Base::*field>
63 constexpr
static std::size_t index_in_base = IndexInBase;
64 constexpr
static bool is_derived =
true;
70 return c.*derived_field;
74 return c.*derived_field;
78 return Reflector::get_name();
84 template<
typename Container>
86 template<
typename Member>
88 template<std::
size_t Index>
90 template<Member Container::*field>
98 template<
typename Derived>
101 template<std::
size_t IndexInBase,
typename BaseContainer,
typename Member, Member BaseContainer::*field>
105 template<std::size_t IndexInBase,
typename BaseContainer,
typename IntermediateContainer,
106 typename Member, Member BaseContainer::*field>
114 #define FC_CONCAT_BASE_MEMBER_REFLECTIONS(r, derived, base) \ 115 ::add_list<typelist::transform<reflector<base>::members, impl::Derivation_reflection_transformer<derived>>> 116 #define FC_CONCAT_MEMBER_REFLECTION(r, container, idx, member) \ 118 ::add<typename impl::Reflect_type<container>::template with_field_type<decltype(container::member)> \ 119 ::template at_index<idx> \ 120 ::template with_field_pointer<&container::member>::type> 121 #define FC_REFLECT_MEMBER_NAME(r, container, idx, member) \ 122 template<> struct member_name<container, idx> { constexpr static const char* value = BOOST_PP_STRINGIZE(member); }; 123 #define FC_REFLECT_TEMPLATE_MEMBER_NAME(r, data, idx, member) \ 124 template<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_ELEM(0, data))> struct member_name<BOOST_PP_SEQ_ELEM(1, data), idx> { \ 125 constexpr static const char* value = BOOST_PP_STRINGIZE(member); }; 126 #define FC_CONCAT_TYPE(r, x, TYPE) ::add<TYPE> 174 template<
typename Visitor>
175 static inline void visit(
const Visitor& v );
186 #define FC_REFLECT_VISIT_BASE(r, visitor, base) \ 187 fc::reflector<base>::visit( visitor ); 191 #define TEMPLATE template 194 #pragma warning( disable: 4482 ) 198 #define FC_REFLECT_VISIT_MEMBER( r, visitor, elem ) \ 199 { typedef decltype(((type*)nullptr)->elem) member_type; \ 200 visitor.TEMPLATE operator()<member_type,type,&type::elem>( BOOST_PP_STRINGIZE(elem) ); \ 203 #define FC_REFLECT_VISIT_MEMBER_I( r, visitor, I, elem ) \ 204 case I: FC_REFLECT_VISIT_MEMBER( r, visitor, elem ) break; 207 #define FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \ 208 template<typename Visitor>\ 209 static inline void visit( const Visitor& v ) { \ 210 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_BASE, v, INHERITS ) \ 211 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_MEMBER, v, MEMBERS ) \ 217 #define FC_REFLECT_VISIT_ENUM( r, enum_type, elem ) \ 218 v.operator()(BOOST_PP_STRINGIZE(elem), int64_t(enum_type::elem) ); 219 #define FC_REFLECT_ENUM_TO_STRING( r, enum_type, elem ) \ 220 case enum_type::elem: return BOOST_PP_STRINGIZE(elem); 221 #define FC_REFLECT_ENUM_TO_FC_STRING( r, enum_type, elem ) \ 222 case enum_type::elem: return std::string(BOOST_PP_STRINGIZE(elem)); 224 #define FC_REFLECT_ENUM_FROM_STRING( r, enum_type, elem ) \ 225 if( strcmp( s, BOOST_PP_STRINGIZE(elem) ) == 0 ) return enum_type::elem; 226 #define FC_REFLECT_ENUM_FROM_STRING_CASE( r, enum_type, elem ) \ 227 case enum_type::elem: 229 #define FC_REFLECT_ENUM( ENUM, FIELDS ) \ 231 template<> struct reflector<ENUM> { \ 232 typedef std::true_type is_defined; \ 233 static const char* to_string(ENUM elem) { \ 235 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \ 237 fc::throw_bad_enum_cast( fc::to_string(int64_t(elem)).c_str(), BOOST_PP_STRINGIZE(ENUM) ); \ 241 static const char* to_string(int64_t i) { \ 242 return to_string(ENUM(i)); \ 244 static std::string to_fc_string(ENUM elem) { \ 246 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_FC_STRING, ENUM, FIELDS ) \ 248 return fc::to_string(int64_t(elem)); \ 250 static std::string to_fc_string(int64_t i) { \ 251 return to_fc_string(ENUM(i)); \ 253 static ENUM from_int(int64_t i) { \ 257 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_FROM_STRING_CASE, ENUM, FIELDS ) \ 260 fc::throw_bad_enum_cast( i, BOOST_PP_STRINGIZE(ENUM) ); \ 264 static ENUM from_string( const char* s ) { \ 265 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_FROM_STRING, ENUM, FIELDS ) \ 269 i = boost::lexical_cast<int64_t>(s); \ 271 catch( const boost::bad_lexical_cast& ) \ 273 fc::throw_bad_enum_cast( s, BOOST_PP_STRINGIZE(ENUM) ); \ 275 return from_int(i); \ 277 template< typename Visitor > \ 278 static void visit( Visitor& v ) \ 280 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_ENUM, ENUM, FIELDS ) \ 283 template<> struct get_typename<ENUM> { static const char* name() { return BOOST_PP_STRINGIZE(ENUM); } }; \ 305 #define FC_REFLECT_DERIVED( TYPE, INHERITS, MEMBERS ) \ 307 template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \ 308 template<> struct reflector<TYPE> {\ 310 typedef std::true_type is_defined; \ 311 using native_members = \ 312 typename typelist::builder<>::type \ 313 BOOST_PP_SEQ_FOR_EACH_I( FC_CONCAT_MEMBER_REFLECTION, TYPE, MEMBERS ) ::finalize; \ 314 using inherited_members = \ 315 typename typelist::builder<>::type \ 316 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_BASE_MEMBER_REFLECTIONS, TYPE, INHERITS ) ::finalize; \ 317 using members = typename typelist::concat<inherited_members, native_members>::type; \ 318 using base_classes = typename typelist::builder<>::type \ 319 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_TYPE, x, INHERITS ) ::finalize; \ 320 enum member_count_enum { \ 321 local_member_count = typelist::length<native_members>(), \ 322 total_member_count = typelist::length<members>() \ 324 FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \ 326 namespace member_names { \ 327 BOOST_PP_SEQ_FOR_EACH_I( FC_REFLECT_MEMBER_NAME, TYPE, MEMBERS ) \ 330 #define FC_REFLECT_DERIVED_TEMPLATE( TEMPLATE_ARGS, TYPE, INHERITS, MEMBERS ) \ 332 template<BOOST_PP_SEQ_ENUM(TEMPLATE_ARGS)> struct get_typename<TYPE> { \ 333 static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } \ 335 template<BOOST_PP_SEQ_ENUM(TEMPLATE_ARGS)> struct reflector<TYPE> {\ 337 typedef std::true_type is_defined; \ 338 using native_members = \ 339 typename typelist::builder<>::type \ 340 BOOST_PP_SEQ_FOR_EACH_I( FC_CONCAT_MEMBER_REFLECTION, TYPE, MEMBERS ) ::finalize; \ 341 using inherited_members = \ 342 typename typelist::builder<>::type \ 343 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_BASE_MEMBER_REFLECTIONS, TYPE, INHERITS ) ::finalize; \ 344 using members = typename typelist::concat<inherited_members, native_members>::type; \ 345 using base_classes = typename typelist::builder<>::type \ 346 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_TYPE, x, INHERITS ) ::finalize; \ 347 enum member_count_enum { \ 348 local_member_count = typelist::length<native_members>(), \ 349 total_member_count = typelist::length<members>() \ 351 FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \ 353 namespace member_names { \ 354 BOOST_PP_SEQ_FOR_EACH_I( FC_REFLECT_TEMPLATE_MEMBER_NAME, (TEMPLATE_ARGS)(TYPE), MEMBERS ) \ 357 #define FC_REFLECT_DERIVED_NO_TYPENAME( TYPE, INHERITS, MEMBERS ) \ 359 template<> struct reflector<TYPE> {\ 361 typedef std::true_type is_defined; \ 362 using native_members = \ 363 typename typelist::builder<>::type \ 364 BOOST_PP_SEQ_FOR_EACH_I( FC_CONCAT_MEMBER_REFLECTION, TYPE, MEMBERS ) ::finalize; \ 365 using inherited_members = \ 366 typename typelist::builder<>::type \ 367 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_BASE_MEMBER_REFLECTIONS, TYPE, INHERITS ) ::finalize; \ 368 using members = typename typelist::concat<inherited_members, native_members>::type; \ 369 using base_classes = typename typelist::builder<>::type \ 370 BOOST_PP_SEQ_FOR_EACH( FC_CONCAT_TYPE, x, INHERITS ) ::finalize; \ 371 enum member_count_enum { \ 372 local_member_count = typelist::length<native_members>(), \ 373 total_member_count = typelist::length<members>() \ 375 FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \ 388 #define FC_REFLECT( TYPE, MEMBERS ) \ 389 FC_REFLECT_DERIVED( TYPE, BOOST_PP_SEQ_NIL, MEMBERS ) 392 #define FC_REFLECT_TEMPLATE( TEMPLATE_ARGS, TYPE, MEMBERS ) \ 393 FC_REFLECT_DERIVED_TEMPLATE( TEMPLATE_ARGS, TYPE, BOOST_PP_SEQ_NIL, MEMBERS ) 395 #define FC_REFLECT_EMPTY( TYPE ) \ 396 FC_REFLECT_DERIVED( TYPE, BOOST_PP_SEQ_NIL, BOOST_PP_SEQ_NIL ) 398 #define FC_REFLECT_TYPENAME( TYPE ) \ 400 template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \ static constexpr const char * value
Defines a template for manipulating and storing compile-time lists of types.
Helper template to create a field_reflection without any commas (makes it macro-friendly) ...
A template to store compile-time information about a field in a reflected struct. ...
void throw_bad_enum_cast(int64_t i, const char *e)
typename impl::zip< typename impl::make_sequence< length< List >()>::type, List >::type index
static const char * get_name()
defines visit functions for T Unless this is specialized, visit() will not be defined for T...
std::false_type is_defined
static const char * get_name()
Get the name of the field.
A template which stores the name of the native member at a given index in a given class...