Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost fusion sequence type and name identification for structs and class

Tags:

c++

boost

I am trying to use boost fusion for one of my projects and I an figuring out how to get type names and variable names for structures and classes.

#include <typeinfo>
#include <string>
#include <iostream>
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/adapt_adt.hpp>

#include <boost/lexical_cast.hpp>

using namespace boost::fusion;

struct Foo
{
    int integer_value;
    bool boolean_value;
};


class Bar
{
    int integer_value;
    bool boolean_value;
public:
    Bar(int i_val, bool b_val):integer_value(i_val),boolean_value(b_val) {}
    int     get_integer_value() const       { return integer_value; }
    void    set_integer_value(int i_val)    { integer_value = i_val; }
    bool    get_boolean_value() const       { return boolean_value; }
    void    set_boolean_value(bool b_val)   { boolean_value = b_val; }
};

BOOST_FUSION_ADAPT_STRUCT(
    Foo,
    (int, integer_value)
    (bool, boolean_value)    
)

BOOST_FUSION_ADAPT_ADT(
    Bar,
    (int, int, obj.get_integer_value() , obj.set_integer_value(val))
    (bool, bool, obj.get_boolean_value(), obj.set_boolean_value(val))    
)


struct DisplayMembers
{

    template <typename T>
    void operator()(T& t) const {
        std::cout << typeid(t).name() << " : " << boost::lexical_cast<std::string>(t) << std::endl;
    }

};

int main(int argc, char *argv[]) 
{
  struct Foo f = { 33, false};
  for_each(f, DisplayMembers());

  Bar b(34,true);
  for_each(b, DisplayMembers());
  return 0;
}

In the above example the result is

int : 33
bool : 0
struct boost::fusion::extension::adt_attribute_proxy<class Bar,0,0> : 34
struct boost::fusion::extension::adt_attribute_proxy<class Bar,1,0> : 1

I want the result as

int : integer_value : 33
bool : boolean_value : 0
int : integer_value : 34
bool : boolean_value : 1
like image 571
balas bellobas Avatar asked Oct 15 '14 10:10

balas bellobas


1 Answers

I distilled the answer by sehe into something much simpler, provided you are using C++14

#include <iostream>

#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/mpl/range_c.hpp>

struct MyStruct {
    std::string foo;
    double bar;
};

BOOST_FUSION_ADAPT_STRUCT(MyStruct,
                          foo,
                          bar)

namespace fuz = boost::fusion;
namespace mpl = boost::mpl;

int main(int argc, char* argv[]) {
  MyStruct dummy{"yo",3.14};

  fuz::for_each(mpl::range_c<
                unsigned, 0, fuz::result_of::size<MyStruct>::value>(),
                [&](auto index){
      std::cout << "Name: "
                << fuz::extension::struct_member_name<MyStruct,index>::call()
                << " Value: "
                << fuz::at_c<index>(dummy) << std::endl; 
    });

}

Outputs:

Name: foo Value: yo
Name: bar Value: 3.14

See it live on coliru

like image 72
Joao Tavora Avatar answered Sep 18 '22 15:09

Joao Tavora