Merge pull request #9 from daminetreg/fusion_adapters

Version of ADAPT_STRUCT that does not require specifying the types of the fields
This commit is contained in:
Joel de Guzman
2014-06-15 08:42:32 +08:00
7 changed files with 361 additions and 99 deletions

View File

@@ -185,10 +185,20 @@ necessary boilerplate to make an arbitrary struct a model of
__random_access_sequence__. __random_access_sequence__.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_STRUCT(
struct_name,
member_name0,
member_name1,
member_name2,
...
)
// When BOOST_PP_VARIADICS is missing :
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
struct_name, struct_name,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2)
... ...
) )
@@ -196,9 +206,13 @@ __random_access_sequence__.
The above macro generates the necessary code to adapt `struct_name` The above macro generates the necessary code to adapt `struct_name`
as a model of __random_access_sequence__. as a model of __random_access_sequence__.
The sequence of `(member_typeN, member_nameN)`
pairs declares the type and names of each of the struct members that are The sequence of `member_nameN,` arguments or `(member_typeN, member_nameN)`
part of the sequence. 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 macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@@ -208,7 +222,7 @@ namespace qualified name of the struct to be adapted.
#include <boost/fusion/adapted/struct/adapt_struct.hpp> #include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
[heading Example] [heading Example: BOOST_FUSION_ADAPT_STRUCT ]
namespace demo namespace demo
{ {
struct employee struct employee
@@ -221,8 +235,15 @@ namespace qualified name of the struct to be adapted.
// demo::employee is now a Fusion sequence // demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
demo::employee, demo::employee,
(std::string, name) name,
(int, age)) age)
// When BOOST_PP_VARIADICS is missing :
BOOST_FUSION_ADAPT_STRUCT(
demo::employee,
(BOOST_FUSION_ADAPT_AUTO, name)
(BOOST_FUSION_ADAPT_AUTO, age)
)
[endsect] [endsect]
@@ -234,11 +255,21 @@ necessary boilerplate to make an arbitrary template struct a model of
__random_access_sequence__. __random_access_sequence__.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_TPL_STRUCT(
(template_param0)(template_param1)...,
(struct_name) (specialization_param0)(specialization_param1)...,
member_name0,
member_name1
...
)
// When BOOST_PP_VARIADICS is missing :
BOOST_FUSION_ADAPT_TPL_STRUCT( BOOST_FUSION_ADAPT_TPL_STRUCT(
(template_param0)(template_param1)..., (template_param0)(template_param1)...,
(struct_name) (specialization_param0)(specialization_param1)..., (struct_name) (specialization_param0)(specialization_param1)...,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2),
... ...
) )
@@ -252,9 +283,12 @@ the template type parameters used.
The sequence `(specialization_param0)(specialization_param1)...` The sequence `(specialization_param0)(specialization_param1)...`
declares the template parameters of the actual specialization of `struct_name` declares the template parameters of the actual specialization of `struct_name`
that is adapted as a fusion sequence. that is adapted as a fusion sequence.
The sequence of `(member_typeN, member_nameN)` 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 pairs declares the type and names of each of the struct members that are part of
part of the sequence. the sequence.
Omitting the type or using BOOST_FUSION_ADAPT_AUTO can be used to infer the type,
as with decltype.
The macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@@ -272,6 +306,7 @@ namespace qualified name of the struct to be adapted.
{ {
Name name; Name name;
Age age; Age age;
int employment_timestamp;
}; };
} }
@@ -280,7 +315,16 @@ namespace qualified name of the struct to be adapted.
(Name)(Age), (Name)(Age),
(demo::employee) (Name)(Age), (demo::employee) (Name)(Age),
(Name, name) (Name, name)
(Age, age)) (Age, age)
(BOOST_FUSION_ADAPT_AUTO, employment_timestamp))
// Or by infering type completely
BOOST_FUSION_ADAPT_TPL_STRUCT(
(Name)(Age),
(demo::employee) (Name)(Age),
name,
age,
employment_timestamp)
[endsect] [endsect]

View File

@@ -1,6 +1,7 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2009-2011 Christopher Schmidt Copyright (c) 2009-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,8 +11,10 @@
#define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP #define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/preprocessor/config/config.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/type_traits/add_reference.hpp> #include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
@@ -19,6 +22,7 @@
#include <boost/fusion/adapted/struct/detail/extension.hpp> #include <boost/fusion/adapted/struct/detail/extension.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base.hpp> #include <boost/fusion/adapted/struct/detail/adapt_base.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp>
#include <boost/fusion/adapted/struct/detail/at_impl.hpp> #include <boost/fusion/adapted/struct/detail/at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_view_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp>
@@ -30,43 +34,83 @@
#include <boost/fusion/adapted/struct/detail/value_of_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_of_impl.hpp>
#include <boost/fusion/adapted/struct/detail/deref_impl.hpp> #include <boost/fusion/adapted/struct/detail/deref_impl.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0(X, Y) \
((X, Y)) BOOST_FUSION_ADAPT_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1(X, Y) \
((X, Y)) BOOST_FUSION_ADAPT_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0_END
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1_END
#define BOOST_FUSION_ADAPT_STRUCT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE)\ #define BOOST_FUSION_ADAPT_STRUCT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE)\
BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,BOOST_PP_EMPTY,ATTRIBUTE,2) 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_TPL_STRUCT(TEMPLATE_PARAMS_SEQ,NAME_SEQ, ATTRIBUTES) \
#define BOOST_FUSION_ADAPT_AUTO BOOST_PP_EMPTY()
#if BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_TPL_STRUCT(TEMPLATE_PARAMS_SEQ,NAME_SEQ, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \ BOOST_FUSION_ADAPT_STRUCT_BASE( \
(1)TEMPLATE_PARAMS_SEQ, \ (1)TEMPLATE_PARAMS_SEQ, \
(1)NAME_SEQ, \ (1)NAME_SEQ, \
struct_tag, \ struct_tag, \
0, \ 0, \
((0,0)) BOOST_PP_CAT( \ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C) BOOST_FUSION_ADAPT_STRUCT_C)
#define BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \ # define BOOST_FUSION_ADAPT_STRUCT(NAME, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \ BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \ (0), \
(0)(NAME), \ (0)(NAME), \
struct_tag, \ struct_tag, \
0, \ 0, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_C) BOOST_FUSION_ADAPT_STRUCT_C)
#define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \ # define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \ BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \ (0), \
(0)(NAME), \ (0)(NAME), \
struct_tag, \ struct_tag, \
1, \ 1, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_C) BOOST_FUSION_ADAPT_STRUCT_C)
#else // BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_TPL_STRUCT( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(1)TEMPLATE_PARAMS_SEQ, \
(1)NAME_SEQ, \
struct_tag, \
0, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
0, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES, \
_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
1, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES, \
_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
#endif // BOOST_PP_VARIADICS
#endif #endif

View File

@@ -2,6 +2,7 @@
Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2001-2009 Joel de Guzman
Copyright (c) 2005-2006 Dan Marsden Copyright (c) 2005-2006 Dan Marsden
Copyright (c) 2009-2011 Christopher Schmidt Copyright (c) 2009-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -25,12 +26,15 @@
#include <boost/preprocessor/tuple/eat.hpp> #include <boost/preprocessor/tuple/eat.hpp>
#include <boost/preprocessor/tuple/elem.hpp> #include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp> #include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/tag.hpp> #include <boost/mpl/tag.hpp>
#include <boost/mpl/eval_if.hpp> #include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp> #include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
#include <boost/typeof/typeof.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \ #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \
BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \ BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \
BOOST_PP_EMPTY() BOOST_PP_EMPTY()
@@ -55,6 +59,17 @@
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
BOOST_PP_TUPLE_EAT(1))(SEQ) 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)) \
#define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)
#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
# define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
@@ -118,7 +133,9 @@
> \ > \
{ \ { \
typedef \ typedef \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ BOOST_PP_IF(BOOST_PP_LESS(ATTRIBUTE_TUPEL_SIZE,2), \
BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE \
)(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \
attribute_type; \ attribute_type; \
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \ TEMPLATE_PARAMS_SEQ) \
@@ -143,7 +160,9 @@
call(Seq& seq) \ call(Seq& seq) \
{ \ { \
return seq.PREFIX() \ return seq.PREFIX() \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE); \ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(BOOST_PP_LESS(ATTRIBUTE_TUPEL_SIZE,2), 0, 1),\
ATTRIBUTE); \
} \ } \
}; \ }; \
}; \ }; \
@@ -163,7 +182,9 @@
call() \ call() \
{ \ { \
return BOOST_PP_STRINGIZE( \ return BOOST_PP_STRINGIZE( \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE,1,ATTRIBUTE)); \ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(BOOST_PP_LESS(ATTRIBUTE_TUPEL_SIZE,2), 0, 1),\
ATTRIBUTE)); \
} \ } \
}; };

View File

@@ -0,0 +1,56 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_ADAPT_BASE_ATTR_FILLER_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP
#include <boost/config.hpp>
#include <boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/push_front.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0(X, Y) \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTE_FILLER(X,Y) \
BOOST_FUSION_ADAPT_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1(X, Y) \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTE_FILLER(X,Y) \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0_END
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1_END
#define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTE_FILLER(X, Y) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(X), \
((1, (Y))), \
((2, (X,Y))) \
)
#if BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP(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_ATTRIBUTE_FILLER(BOOST_FUSION_ADAPT_AUTO, \
elem) \
)
# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(...) \
BOOST_PP_SEQ_PUSH_FRONT( \
BOOST_PP_SEQ_FOR_EACH( \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP, \
unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), \
(0,0) \
)
#endif // BOOST_PP_VARIADICS
#endif

View File

@@ -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 <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/config/config.hpp>
#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

View File

@@ -38,6 +38,7 @@ namespace ns
{ {
int x; int x;
int y; int y;
int z;
}; };
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
@@ -48,65 +49,96 @@ namespace ns
private: private:
int x; int x;
int y; int y;
int z;
public: public:
point_with_private_attributes(int x, int y):x(x),y(y) point_with_private_attributes(int x, int y, int z):x(x),y(y),z(z)
{} {}
}; };
#endif #endif
} }
BOOST_FUSION_ADAPT_STRUCT( #if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_STRUCT(
ns::point,
x,
y,
z
)
# if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT(
ns::point_with_private_attributes,
x,
y,
z
)
# endif
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, m)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_STRUCT(
ns::point, ns::point,
(int, x) (int, x)
(int, y) (int, y)
) (BOOST_FUSION_ADAPT_AUTO, z)
)
#if !BOOST_WORKAROUND(__GNUC__,<4) # if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
ns::point_with_private_attributes, ns::point_with_private_attributes,
(int, x) (int, x)
(int, y) (int, y)
) (BOOST_FUSION_ADAPT_AUTO, z)
#endif )
# endif
struct s { int m; }; struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, (int, m)) BOOST_FUSION_ADAPT_STRUCT(s, (BOOST_FUSION_ADAPT_AUTO, m))
#endif
int int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
using namespace boost; using namespace boost;
using ns::point;
std::cout << tuple_open('['); std::cout << tuple_open('[');
std::cout << tuple_close(']'); std::cout << tuple_close(']');
std::cout << tuple_delimiter(", "); std::cout << tuple_delimiter(", ");
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
ns::point p = {123, 456}; point p = {123, 456, 789};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << 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<0>(p) = 6;
at_c<1>(p) = 9; 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<ns::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); vector<int, float, int> v1(4, 2, 2);
ns::point v2 = {5, 3}; point v2 = {5, 3, 3};
fusion::vector<long, double> v3(5, 4); vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@@ -118,16 +150,16 @@ main()
} }
{ {
// conversion from ns::point to vector // conversion from point to vector
ns::point p = {5, 3}; point p = {5, 3, 3};
fusion::vector<int, long> v(p); vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from point to list
ns::point p = {5, 3}; point p = {5, 3, 3};
fusion::list<int, long> l(p); list<int, long> l(p);
l = p; l = p;
} }
@@ -150,12 +182,13 @@ main()
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
{ {
ns::point_with_private_attributes p(123, 456); ns::point_with_private_attributes p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
} }
#endif #endif

View File

@@ -35,19 +35,40 @@ namespace ns
{ {
X x; X x;
Y y; Y y;
int z;
}; };
} }
BOOST_FUSION_ADAPT_TPL_STRUCT( #if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_TPL_STRUCT(
(X)(Y),
(ns::point)(X)(Y),
x,
(BOOST_FUSION_ADAPT_AUTO, y)
(int, z)
)
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), m)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_TPL_STRUCT(
(X)(Y), (X)(Y),
(ns::point)(X)(Y), (ns::point)(X)(Y),
(X, x) (X, x)
(Y, y) (Y, y)
) (BOOST_FUSION_ADAPT_AUTO, z)
)
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), (BOOST_FUSION_ADAPT_AUTO, m))
#endif
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), (M, m))
int int
main() main()
@@ -62,28 +83,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
point p = {123, 456}; point p = {123, 456, 789};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << 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<0>(p) = 6;
at_c<1>(p) = 9; 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<point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
vector<int, float> v1(4, 2); vector<int, float, int> v1(4, 2, 2);
point v2 = {5, 3}; point v2 = {5, 3, 3};
vector<long, double> v3(5, 4); vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@@ -96,14 +119,14 @@ main()
{ {
// conversion from point to vector // conversion from point to vector
point p = {5, 3}; point p = {5, 3, 3};
vector<int, long> v(p); vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from point to list // conversion from point to list
point p = {5, 3}; point p = {5, 3, 3};
list<int, long> l(p); list<int, long> l(p);
l = p; l = p;
} }