From 02b776360ae1b69eda9745ede2c07e6a7187c6b1 Mon Sep 17 00:00:00 2001 From: "Damien Buhl (alias daminetreg)" Date: Wed, 4 Jun 2014 01:36:15 +0200 Subject: [PATCH] FEATURE: BOOST_FUSION_ADAPT_STRUCT can now also be called completely with variadics arguments. The following signature is possible : BOOST_FUSION_ADAPT_STRUCT( struct_name, member_name0, (BOOST_FUSION_ADAPT_AUTO, member_name1) (member_type2, member_name2) member_name3, ... ) --- .../fusion/adapted/struct/adapt_struct.hpp | 30 ++++++++++++++ .../struct/detail/preprocessor/is_seq.hpp | 41 +++++++++++++++++++ test/sequence/adapt_struct.cpp | 30 ++++++++------ 3 files changed, 88 insertions(+), 13 deletions(-) create mode 100644 include/boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp diff --git a/include/boost/fusion/adapted/struct/adapt_struct.hpp b/include/boost/fusion/adapted/struct/adapt_struct.hpp index 06927e9e..bc2c56e4 100644 --- a/include/boost/fusion/adapted/struct/adapt_struct.hpp +++ b/include/boost/fusion/adapted/struct/adapt_struct.hpp @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -34,6 +37,7 @@ #include #include #include +#include #if BOOST_PP_VARIADICS @@ -98,6 +102,30 @@ BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END), \ BOOST_FUSION_ADAPT_STRUCT_C) + +#if BOOST_PP_VARIADICS + +#define BOOST_FUSION_ADAPT_STRUCT_PROCESS_PARAM(r, data, elem) \ + BOOST_PP_IF(BOOST_FUSION_PP_IS_SEQ(elem), \ + BOOST_PP_CAT( BOOST_FUSION_ADAPT_STRUCT_FILLER_0 elem ,_END), \ + BOOST_FUSION_ADAPT_STRUCT_CREATE_MEMBER_TUPLE(elem) \ + ) + +#define BOOST_FUSION_ADAPT_STRUCT_CREATE_MEMBER_TUPLE_FROM_VARIADICS(...) \ + BOOST_PP_SEQ_PUSH_FRONT( \ + BOOST_PP_SEQ_FOR_EACH(BOOST_FUSION_ADAPT_STRUCT_PROCESS_PARAM, unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), (0,0)) + +#define BOOST_FUSION_ADAPT_STRUCT(NAME, ...) \ + BOOST_FUSION_ADAPT_STRUCT_BASE( \ + (0), \ + (0)(NAME), \ + struct_tag, \ + 0, \ + BOOST_FUSION_ADAPT_STRUCT_CREATE_MEMBER_TUPLE_FROM_VARIADICS(__VA_ARGS__), \ + BOOST_FUSION_ADAPT_STRUCT_C) + +#else // BOOST_PP_VARIADICS + #define BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \ BOOST_FUSION_ADAPT_STRUCT_BASE( \ (0), \ @@ -107,6 +135,8 @@ BOOST_PP_CAT( BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_FUSION_ADAPT_STRUCT_C) +#endif // BOOST_PP_VARIADICS + #define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \ BOOST_FUSION_ADAPT_STRUCT_BASE( \ (0), \ diff --git a/include/boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp b/include/boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp new file mode 100644 index 00000000..95f11050 --- /dev/null +++ b/include/boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp @@ -0,0 +1,41 @@ +/*============================================================================= + BOOST_PP_VARIADICS version of BOOST_PP_IS_SEQ inspired from + boost/mpl/aux_/preprocessor/is_seq.hpp, original copyrights goes to : + + Copyright Paul Mensonides 2003 + Copyright Aleksey Gurtovoy 2003-2004 + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +==============================================================================*/ + +#ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_PREPROCESSOR_IS_SEQ_HPP +#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_PREPROCESSOR_IS_SEQ_HPP + +#include +#include +#include +#include +#include + +#if BOOST_PP_VARIADICS + +#define BOOST_FUSION_PP_IS_SEQ(seq) BOOST_PP_CAT(BOOST_FUSION_PP_IS_SEQ_, \ + BOOST_FUSION_PP_IS_SEQ_0 seq BOOST_PP_RPAREN()) + +#define BOOST_FUSION_PP_IS_SEQ_0(...) \ + BOOST_FUSION_PP_IS_SEQ_1(__VA_ARGS__ + +#define BOOST_FUSION_PP_IS_SEQ_ALWAYS_0(...) \ + 0 + +#define BOOST_FUSION_PP_IS_SEQ_BOOST_FUSION_PP_IS_SEQ_0 \ + BOOST_FUSION_PP_IS_SEQ_ALWAYS_0( + +#define BOOST_FUSION_PP_IS_SEQ_BOOST_FUSION_PP_IS_SEQ_1(...) \ + 1 + +#endif // BOOST_PP_VARIADICS + +#endif diff --git a/test/sequence/adapt_struct.cpp b/test/sequence/adapt_struct.cpp index f2da12f7..ca1770a4 100644 --- a/test/sequence/adapt_struct.cpp +++ b/test/sequence/adapt_struct.cpp @@ -4,6 +4,8 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ +#define BOOST_PP_VARIADICS 1 + #include #include #include @@ -38,6 +40,7 @@ namespace ns { int x; int y; + int z; }; #if !BOOST_WORKAROUND(__GNUC__,<4) @@ -58,8 +61,9 @@ namespace ns BOOST_FUSION_ADAPT_STRUCT( ns::point, - (x) - (int, y) + (int, x) + (int, y), + z ) #if !BOOST_WORKAROUND(__GNUC__,<4) @@ -71,7 +75,7 @@ BOOST_FUSION_ADAPT_STRUCT( #endif struct s { int m; }; -BOOST_FUSION_ADAPT_STRUCT(s, (m)) +BOOST_FUSION_ADAPT_STRUCT(s, (int, m)) int main() @@ -90,13 +94,13 @@ main() std::cout << at_c<0>(p) << std::endl; std::cout << at_c<1>(p) << std::endl; std::cout << p << std::endl; - BOOST_TEST(p == make_vector(123, 456)); + BOOST_TEST(p == make_vector(123, 456, 4)); at_c<0>(p) = 6; at_c<1>(p) = 9; - BOOST_TEST(p == make_vector(6, 9)); + 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); @@ -104,9 +108,9 @@ main() } { - fusion::vector v1(4, 2); - ns::point v2 = {5, 3}; - fusion::vector v3(5, 4); + fusion::vector v1(4, 2, 3); + ns::point v2 = {5, 3, 2}; + fusion::vector v3(5, 4, 2); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -119,15 +123,15 @@ main() { // conversion from ns::point to vector - ns::point p = {5, 3}; - fusion::vector v(p); + ns::point p = {5, 3, 4}; + fusion::vector v(p); v = p; } { // conversion from ns::point to list - ns::point p = {5, 3}; - fusion::list l(p); + ns::point p = {5, 3, 4}; + fusion::list l(p); l = p; }