Joel de Guzman wrote:
Or, if you can wait a bit, I do intend to write an intrusive version of the FUSION_ADAPT_STRUCT which also generates the struct along with the constructors and assignment to/from fusion sequences. I dunno, perhaps you can persuade a fusion guru to write the code (Christopher)? :-)
This isn't all of the above, but the attached worked for me as of Boost 1.35.0... #include <boost/fusion/adapted/struct/adapt_struct.hpp> #include <boost/preprocessor/seq/for_each_i.hpp> #include <boost/preprocessor/seq/enum.hpp> #include <boost/preprocessor/seq/transform.hpp> // only for testing #include <iostream> // BOOST_FUSION_BUILD_STRUCT() borrows its syntax from // BOOST_FUSION_ADAPT_STRUCT(). The general idea is that you write the same // code you'd have written for BOOST_FUSION_ADAPT_STRUCT(), but the _BUILD_ // variant actually declares the struct for you as well. The trouble with // BOOST_FUSION_ADAPT_STRUCT's member syntax is that it's a PP sequence of // tuples. BOOST_PP_SEQ_FOR_EACH() handles sequences of single tokens fine, // but a sequence of tuples breaks it. An implementation based on // BOOST_PP_SEQ_FOR_EACH() would require double parentheses, e.g.: // BOOST_FUSION_BUILD_STRUCT(employee, ((std::string, name))((int, age))) // But clearly BOOST_FUSION_ADAPT_STRUCT() manages to avoid that, so we borrow // its implementation. Thanks to Paul Mensonides and Joel de Guzman! #define BOOST_FUSION_BUILD_STRUCT(name, bseq) \ BOOST_FUSION_BUILD_STRUCT_I( \ name, BOOST_PP_CAT(BOOST_FUSION_BUILD_STRUCT_X bseq, 0)); \ BOOST_FUSION_ADAPT_STRUCT(name, bseq) \ /***/ #define BOOST_FUSION_BUILD_STRUCT_X(x, y) ((x, y)) BOOST_FUSION_BUILD_STRUCT_Y #define BOOST_FUSION_BUILD_STRUCT_Y(x, y) ((x, y)) BOOST_FUSION_BUILD_STRUCT_X #define BOOST_FUSION_BUILD_STRUCT_X0 #define BOOST_FUSION_BUILD_STRUCT_Y0 // BOOST_FUSION_BUILD_STRUCT_I generates the overarching structure and uses // SEQ_FOR_EACH_I to generate the "linear" substructures. // Thanks to Paul Mensonides for the PP macro help. #define BOOST_FUSION_BUILD_STRUCT_I(name, seq) \ struct name \ { \ name(BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(BOOST_FUSION_BUILD_STRUCT_P, ~, seq))): \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(BOOST_FUSION_BUILD_STRUCT_MI, ~, seq)) \ {} \ BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_BUILD_STRUCT_C, ~, seq) \ } \ /***/ #define BOOST_FUSION_BUILD_STRUCT_P(r, ignore, xy) \ BOOST_PP_TUPLE_ELEM(2, 0, xy) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, xy), _) \ /***/ #define BOOST_FUSION_BUILD_STRUCT_MI(r, ignore, xy) \ BOOST_PP_TUPLE_ELEM(2, 1, xy)(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, xy), _)) \ /***/ #define BOOST_FUSION_BUILD_STRUCT_C(r, ignore, i, xy) \ BOOST_PP_TUPLE_ELEM(2, 0, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy); \ /***/ // Example BOOST_FUSION_BUILD_STRUCT(employee, (std::string, name) (int, age)) int main(int argc, char *argv[]) { employee Jane("Jane", 37); std::cout << "Name " << Jane.name << ", age " << Jane.age << '\n'; return 0; }