diff --git a/doc/adapted.qbk b/doc/adapted.qbk index e6adfd29..1b5c97c0 100644 --- a/doc/adapted.qbk +++ b/doc/adapted.qbk @@ -337,10 +337,31 @@ arbitrary struct a model of __random_access_sequence__. The given struct is adapted using the given name. [heading Synopsis] + BOOST_FUSION_ADAPT_STRUCT_NAMED( + struct_name, adapted_name, + member_name0, + member_name1, + member_name2, + ... + ) + + BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( + struct_name, + (namespace0)(namespace1)..., + adapted_name, + member_name0, + member_name1, + member_name2, + ... + ) + + // When BOOST_PP_VARIADICS is missing : + BOOST_FUSION_ADAPT_STRUCT_NAMED( struct_name, adapted_name, (member_type0, member_name0) (member_type1, member_name1) + (BOOST_FUSION_ADAPT_AUTO, member_name2), ... ) @@ -350,9 +371,12 @@ adapted using the given name. adapted_name, (member_type0, member_name0) (member_type1, member_name1) + (BOOST_FUSION_ADAPT_AUTO, member_name2), ... ) + + [heading Semantics] The above macros generate the necessary code to adapt `struct_name` @@ -365,9 +389,12 @@ If an empty namespace sequence is given (that is a macro that expands to nothing), the adapted view is placed in the global namespace. If no namespace sequence is given (i.e. `BOOST_FUSION_ADAPT_STRUCT_NAMED`), the adapted view is placed in the namespace `boost::fusion::adapted`. -The sequence of `(member_typeN, member_nameN)` -pairs declares the type and names of each of the struct members that are -part of the sequence. +The sequence of `member_nameN,` arguments or `(member_typeN, member_nameN)` +pairs declares the type and names of each of the struct members that are part of +the sequence. + +Omitting the type or using BOOST_FUSION_ADAPT_AUTO can be used to infer the type, +as with decltype. The macros should be used at global scope, and `struct_name` should be the fully namespace qualified name of the struct to be converted. @@ -391,8 +418,14 @@ namespace qualified name of the struct to be converted. // referring to demo::employee BOOST_FUSION_ADAPT_STRUCT_NAMED( demo::employee, adapted_employee, - (std::string, name) - (int, age)) + name, + age) + + // When BOOST_PP_VARIADICS is missing : + BOOST_FUSION_ADAPT_STRUCT_NAMED( + demo::employee, adapted_employee, + (BOOST_FUSION_ADAPT_AUTO, name), + (BOOST_FUSION_ADAPT_AUTO, age)) [endsect] diff --git a/include/boost/fusion/adapted/adt/adapt_adt.hpp b/include/boost/fusion/adapted/adt/adapt_adt.hpp index 3be25b1e..88ab177c 100644 --- a/include/boost/fusion/adapted/adt/adapt_adt.hpp +++ b/include/boost/fusion/adapted/adt/adapt_adt.hpp @@ -40,9 +40,10 @@ #define BOOST_FUSION_ADAPT_ADT_FILLER_0_END #define BOOST_FUSION_ADAPT_ADT_FILLER_1_END -#define BOOST_FUSION_ADAPT_ADT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE) \ - BOOST_FUSION_ADAPT_ADT_C_BASE( \ - TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE, 4) +#define BOOST_FUSION_ADAPT_ADT_C( \ + TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \ + BOOST_FUSION_ADAPT_ADT_C_BASE( \ + TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE, 4) #define BOOST_FUSION_ADAPT_TPL_ADT(TEMPLATE_PARAMS_SEQ, NAME_SEQ , ATTRIBUTES) \ BOOST_FUSION_ADAPT_STRUCT_BASE( \ diff --git a/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp b/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp index 12bf6aa2..ff33ac59 100644 --- a/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp +++ b/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp @@ -44,7 +44,7 @@ #define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1_END #define BOOST_FUSION_ADAPT_ASSOC_ADT_C( \ - TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE) \ + TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \ \ BOOST_FUSION_ADAPT_ADT_C_BASE(TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,5) \ \ diff --git a/include/boost/fusion/adapted/struct/adapt_assoc_struct.hpp b/include/boost/fusion/adapted/struct/adapt_assoc_struct.hpp index eca77d61..c0665ae6 100644 --- a/include/boost/fusion/adapted/struct/adapt_assoc_struct.hpp +++ b/include/boost/fusion/adapted/struct/adapt_assoc_struct.hpp @@ -43,10 +43,10 @@ #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1_END #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \ - TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE) \ + TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW,I,PREFIX,ATTRIBUTE) \ \ BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ - TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, PREFIX, ATTRIBUTE, 3) \ + TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, PREFIX, ATTRIBUTE, 3) \ \ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ @@ -57,10 +57,10 @@ }; #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C( \ - TEMPLATE_PARAMS_SEQ,NAME_SEQ, I, ATTRIBUTE) \ + TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, I, ATTRIBUTE) \ \ BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \ - TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,BOOST_PP_EMPTY,ATTRIBUTE) + TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW,I,BOOST_PP_EMPTY,ATTRIBUTE) #define BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( \ TEMPLATE_PARAMS_SEQ, NAME_SEQ, ATTRIBUTES) \ diff --git a/include/boost/fusion/adapted/struct/adapt_struct.hpp b/include/boost/fusion/adapted/struct/adapt_struct.hpp index 4c798518..9c1d19f1 100644 --- a/include/boost/fusion/adapted/struct/adapt_struct.hpp +++ b/include/boost/fusion/adapted/struct/adapt_struct.hpp @@ -34,14 +34,16 @@ #include #include -#define BOOST_FUSION_ADAPT_STRUCT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE)\ - BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ - TEMPLATE_PARAMS_SEQ, \ - NAME_SEQ, \ - I, \ - BOOST_PP_EMPTY, \ - BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE), \ - BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE)) +#define BOOST_FUSION_ADAPT_STRUCT_C( \ + TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \ + BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ + TEMPLATE_PARAMS_SEQ, \ + NAME_SEQ, \ + IS_VIEW, \ + I, \ + BOOST_PP_IF(IS_VIEW, BOOST_FUSION_PROXY_PREFIX, BOOST_PP_EMPTY), \ + BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE), \ + BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE)) #define BOOST_FUSION_ADAPT_AUTO BOOST_PP_EMPTY() diff --git a/include/boost/fusion/adapted/struct/adapt_struct_named.hpp b/include/boost/fusion/adapted/struct/adapt_struct_named.hpp index 3f29f3a3..791fb5b0 100644 --- a/include/boost/fusion/adapted/struct/adapt_struct_named.hpp +++ b/include/boost/fusion/adapted/struct/adapt_struct_named.hpp @@ -15,26 +15,41 @@ #include #include -#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0(X, Y) \ - (X, obj.Y) BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1 -#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1(X, Y) \ - (X, obj.Y) BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0 -#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0_END -#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1_END +#ifdef BOOST_PP_VARIADICS -#define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ - WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ATTRIBUTES) \ +# define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ + WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ...) \ \ - BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ - WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \ + BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ + WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \ \ - BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \ - BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION((0)NAMESPACE_SEQ)NAME, \ - BOOST_PP_CAT( \ - BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0 ATTRIBUTES,_END)) + BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \ + BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION( \ + (0)NAMESPACE_SEQ)NAME, \ + __VA_ARGS__) -#define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ATTRIBUTES) \ - BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ - WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,ATTRIBUTES) +# define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ...) \ + BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ + WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,__VA_ARGS__) + + +#else // BOOST_PP_VARIADICS + +# define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ + WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ATTRIBUTES) \ + \ + BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ + WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \ + \ + BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \ + BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION( \ + (0)NAMESPACE_SEQ)NAME, \ + ATTRIBUTES) + +# define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ATTRIBUTES) \ + BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ + WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,ATTRIBUTES) + +#endif #endif diff --git a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp index c5721224..26051395 100644 --- a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp +++ b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp @@ -59,16 +59,16 @@ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \ BOOST_PP_TUPLE_EAT(1))(SEQ) + #define BOOST_FUSION_ATTRIBUTE_TYPEOF( \ - NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ - BOOST_TYPEOF( \ - BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ - :: \ - BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)) \ + NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX) \ + BOOST_TYPEOF( \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)::PREFIX() \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)) #define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \ - NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ - BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) + NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, unused) \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ @@ -98,9 +98,10 @@ #endif #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \ - BOOST_PP_TUPLE_ELEM(3,0,DATA)( \ - BOOST_PP_TUPLE_ELEM(3,1,DATA), \ - BOOST_PP_TUPLE_ELEM(3,2,DATA), \ + BOOST_PP_TUPLE_ELEM(4,0,DATA)( \ + BOOST_PP_TUPLE_ELEM(4,1,DATA), \ + BOOST_PP_TUPLE_ELEM(4,2,DATA), \ + BOOST_PP_TUPLE_ELEM(4,3,DATA), \ I, \ ATTRIBUTE) @@ -122,7 +123,8 @@ #endif #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ - TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ + TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, \ + I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ \ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ @@ -135,7 +137,7 @@ typedef \ BOOST_PP_IF(BOOST_PP_LESS(ATTRIBUTE_TUPEL_SIZE,2), \ BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE \ - )(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ + )(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX) \ attribute_type; \ BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ TEMPLATE_PARAMS_SEQ) \ @@ -216,7 +218,7 @@ namespace boost BOOST_PP_TUPLE_EAT(4))( \ 1, \ BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \ - (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ), \ + (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ, IS_VIEW),\ BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \ \ template< \ diff --git a/include/boost/fusion/adapted/struct/detail/proxy_type.hpp b/include/boost/fusion/adapted/struct/detail/proxy_type.hpp index 350137a4..f673a37c 100644 --- a/include/boost/fusion/adapted/struct/detail/proxy_type.hpp +++ b/include/boost/fusion/adapted/struct/detail/proxy_type.hpp @@ -12,6 +12,8 @@ #include #include +#define BOOST_FUSION_PROXY_PREFIX() obj. + #define BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ WRAPPED_TYPE,NAMESPACE_SEQ,NAME) \ \ diff --git a/test/sequence/adapt_struct.cpp b/test/sequence/adapt_struct.cpp index 406030dd..76019644 100644 --- a/test/sequence/adapt_struct.cpp +++ b/test/sequence/adapt_struct.cpp @@ -159,7 +159,7 @@ main() { // conversion from point to list point p = {5, 3, 3}; - list l(p); + list l(p); l = p; } diff --git a/test/sequence/adapt_struct_named.cpp b/test/sequence/adapt_struct_named.cpp index ef859655..aab11d2d 100644 --- a/test/sequence/adapt_struct_named.cpp +++ b/test/sequence/adapt_struct_named.cpp @@ -37,19 +37,39 @@ namespace ns { int x; int y; + int z; }; } -// this creates a fusion view: boost::fusion::adapted::point -BOOST_FUSION_ADAPT_STRUCT_NAMED( - ns::point, point, - (int, x) - (int, y) -) +#if BOOST_PP_VARIADICS -// this creates a fusion view: ns1::s1 -struct s { int m; }; -BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, (int, m)) + // this creates a fusion view: boost::fusion::adapted::point + BOOST_FUSION_ADAPT_STRUCT_NAMED( + ns::point, point, + x, + y, + z + ) + + // this creates a fusion view: ns1::s1 + struct s { int m; }; + BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, m) + +#else // BOOST_PP_VARIADICS + + // this creates a fusion view: boost::fusion::adapted::point + BOOST_FUSION_ADAPT_STRUCT_NAMED( + ns::point, point, + (int, x) + (int, y) + (BOOST_FUSION_ADAPT_AUTO, z) + ) + + // this creates a fusion view: ns1::s1 + struct s { int m; }; + BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, (BOOST_FUSION_ADAPT_AUTO, m)) + +#endif int main() @@ -63,31 +83,33 @@ main() { BOOST_MPL_ASSERT((traits::is_view)); - ns::point basep = {123, 456}; + ns::point basep = {123, 456, 789}; adapted::point p(basep); std::cout << at_c<0>(p) << std::endl; std::cout << at_c<1>(p) << std::endl; + std::cout << at_c<2>(p) << std::endl; std::cout << p << std::endl; - BOOST_TEST(p == make_vector(123, 456)); + BOOST_TEST(p == make_vector(123, 456, 789)); at_c<0>(p) = 6; at_c<1>(p) = 9; - BOOST_TEST(p == make_vector(6, 9)); + at_c<2>(p) = 12; + BOOST_TEST(p == make_vector(6, 9, 12)); - BOOST_STATIC_ASSERT(boost::fusion::result_of::size::value == 2); + BOOST_STATIC_ASSERT(boost::fusion::result_of::size::value == 3); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); BOOST_TEST(front(p) == 6); - BOOST_TEST(back(p) == 9); + BOOST_TEST(back(p) == 12); } { - fusion::vector v1(4, 2); - ns::point p = {5, 3}; + fusion::vector v1(4, 2, 2); + ns::point p = {5, 3, 3}; adapted::point v2(p); - fusion::vector v3(5, 4); + fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -100,17 +122,17 @@ main() { // conversion from adapted::point to vector - ns::point basep = {5, 3}; + ns::point basep = {5, 3, 3}; adapted::point p(basep); - fusion::vector v(p); + fusion::vector v(p); v = p; } { // conversion from adapted::point to list - ns::point basep = {5, 3}; + ns::point basep = {5, 3, 3}; adapted::point p(basep); - fusion::list l(p); + fusion::list l(p); l = p; }