BitShares-Core
7.0.2
BitShares blockchain node software and command-line wallet software
|
Go to the documentation of this file.
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;
57 template<std::
size_t IndexInBase,
typename Base,
typename Derived,
typename Member, Member Base::*field>
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); } }; \
constexpr static bool is_derived
constexpr static type field_container::* pointer
static const type & get(const container &c)
Defines a template for manipulating and storing compile-time lists of types.
static const char * get_name()
constexpr static std::size_t index
constexpr static std::size_t index_in_base
static type & get(container &c)
A template which stores the name of the native member at a given index in a given class.
Helper template to create a field_reflection without any commas (makes it macro-friendly)
constexpr static const char * value
std::false_type is_defined
static type & get(container &c)
Given a reference to the container type, get a reference to the field.
constexpr static bool is_derived
constexpr static type container::* pointer
defines visit functions for T Unless this is specialized, visit() will not be defined for T.
static const char * get_name()
Get the name of the field.
static const type & get(const container &c)
void throw_bad_enum_cast(int64_t i, const char *e)
A template to store compile-time information about a field in a reflected struct.