Search code examples
adapterboost-fusion

Is it possible to fusion adapt the base class?


Is it possible to fusion-adapt the base class as if it where a member?

First this is the documentation example, side-by-side with the new case:

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

struct employee{
    std::string name;
    int age;
};

BOOST_FUSION_ADAPT_STRUCT(
    employee,
    (std::string, name)
    (int, age))

struct employee2 : std::string{
    int age;
};

BOOST_FUSION_ADAPT_STRUCT(
    employee2,
    (std::string, name) ???
    (int, age))


int main(){}

What should I put in the line with the ???.

Currently the only solution I found is to do this, but 1) I have to make all members getter and setter functions 2) seems an overkill.

#include <boost/fusion/adapted/adt/adapt_adt.hpp>
struct employee2 : std::string{
    int age;
    void set_base(std::string const& age_){std::string::operator=(age_);}
    std::string const& get_base() const{return static_cast<std::string const&>(*this);}
    void set_age(int const& age_){age = age_;}
    int const& get_age() const{return age;}
};

BOOST_FUSION_ADAPT_ADT(
   employee2,
    (std::string, std::string, obj.get_base(), obj.set_base(val))
    (int, int, obj.get_age(), obj.set_age(val))
)

Solution

  • Well, it looks (by experimentation) that one can put all sorts of valid expressions in BOOST_FUSION_ADAPT_ADT. I am not very sure if this is optimal (for example if fusion will make copies when accessing the elements), so other answers are welcomed.

    #include <boost/fusion/adapted/adt/adapt_adt.hpp>
    BOOST_FUSION_ADAPT_ADT(
       employee2,
        (static_cast<std::string const&>(obj), obj.std::string::operator=(val))
        (obj.age, obj.age = val)
    )
    
    int main(){
    
        employee2 e2;
        boost::fusion::at_c<0>(e2) = "Pepe";
        boost::fusion::at_c<1>(e2) = 37;
    
        cout << e2 << " " << e2.age <<'\n';
    
    }
    

    This may prevent some copies and seems to work in more cases (e.g. boost::fusion::copy) but I am not sure why:

    BOOST_FUSION_ADAPT_ADT(
       employee2,
        (std::string, std::string const&, obj, obj.std::string::operator=(val))
        (int, int const&, obj.age, obj.age = val)
    )