MACE
1.0.0
|
Expose and query type names, members, and methods. More...
Often times it is helpful to have access to the string name of a class type, particularlly when you are putting print statements in templated code. This information is made available through a very simple templated method.
reflect::get_typename<uint32_t>(); // return "uint32_t" reflect::get_typename<std::vector<uint32_t> >(); // return "std::vector<uint32_t>"
These names will be the same on all compilers so long as you utilize one of the following macro:
MACE_REFLECT( your_namespace::your_class ) MACE_REFLECT_TYPEINFO_ALIAS( your_namespace::your_class, "AkaMyClass" )
To reflect the members of a struct you want to use one of the following macros which automatically include MACE_REFLECT_TYPEINFO for the class name.
MACE_REFLECT( Class, MemberSequence)
MACE_REFLECT_DERIVED( Class, BaseSequence, MemberSequence)
struct A { std::string hello; }; struct B : A { std::string world; int other; }; MACE_REFLECT( A, (hello) ) MACE_REFLECT_DERIVED( B, (A), (world)(other) )
You can then convert these types to json by defining a visitor:
template<typename T> struct to_json_visitor { to_json_visitor( const T& v, std::ostream& _os ):val(v),os(_os),i(0){} template<typename MemberPtr, MemberPtr m> void operator()( const char* name )const { if( i == 0 ) os << "{"; os<<"\""<<name<<"\":"; to_json( val.*m, os); if( i != mace::reflect::reflector<T>::total_member_count-1 ) os << ","; if( i == mace::reflect::reflector<T>::total_member_count-1 ) os << "}"; ++i; } mutable int i; const T& val; std::ostream& os; };
Then use the reflect::reflector<T>
to visit the members.
template<typename T> void to_json( const T& v, std::ostream& os ) { mace::reflect::reflector<T>::visit( to_json_visitor<T>( v, os ) ); }
When combined with the following base cases:
template<typename T> void to_json( const std::vector<T>& v, std::ostream& os ); void to_json( const std::string& s, std::ostream& os ) { os << '"'<<s<<'"'; } void to_json( const int& i, std::ostream& os ) { os << i; } void to_json( const double& d, std::ostream& os ) { os << d; } void to_json( const float& f, std::ostream& os ) { os << f; } void to_json( const bool& b, std::ostream& os ) { os << (b ? "true" : "false"); }
Makes conversion to json of complex types trivial:
struct contact { contact( const std::string& f, const std::string& l, int z ) :first_name(f),last_name(l),zip(z){} std::string first_name; std::string last_name; int zip; }; struct address_book { std::string name; bool is_locked; std::vector<contact> contacts; }; MACE_REFLECT( contact, (first_name)(last_name)(zip) ) MACE_REFLECT( address_book, (name)(is_locked)(contacts) )
Convert it to JSON:
int main( int argc, char** argv ) { address_book ab; ab.name = "My Address Book"; ab.is_locked = false; ab.contacts.push_back( contact( "Steve", "Jobs", 90210 ) ); ab.contacts.push_back( contact( "Bill", "Gates", 10000 ) ); to_json( ab, std::cout ); return 0; }
The above code will generate the following output:
{"name":"My Address Book","is_locked":false,"contacts":[{"first_name":"Steve","last_name":"Jobs","zip":90210},{"first_name":"Bill","last_name":"Gates","zip":10000}]}
See the full text for this example in examples/reflect_to_json.cpp
Next Topic: mace_reflect_erasure