diff --git a/doc/adapted.qbk b/doc/adapted.qbk index c11d733e..9fd6c24a 100644 --- a/doc/adapted.qbk +++ b/doc/adapted.qbk @@ -664,8 +664,8 @@ __random_access_sequence__. BOOST_FUSION_ADAPT_ADT( type_name, - (attribute_type0, attribute_const_type0, get_expr0, set_expr0) - (attribute_type1, attribute_const_type1, get_expr1, set_expr1) + ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0) + ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1) ... ) @@ -674,7 +674,7 @@ __random_access_sequence__. The above macro generates the necessary code to adapt `type_name` as a model of __random_access_sequence__. The sequence of -[^(attribute_type['N], attribute_const_type['N], get_expr['N], set_expr['N])] +[^([attribute_type['N], attribute_const_type['N],] get_expr['N], set_expr['N])] quadruples declares the types, const types, get-expressions and set-expressions of the elements that are part of the adapted fusion sequence. [^get_expr['N]] is the expression that is invoked to get the ['N]th element @@ -682,7 +682,9 @@ of an instance of `type_name`. This expression may access a variable named `obj` of type `type_name&` or `type_name const&` which represents the underlying instance of `type_name`. [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types -that [^get_expr['N]] denotes to. +that [^get_expr['N]] denotes to, when omitted the type is deduced from +[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for +variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type. [^set_expr['N]] is the expression that is invoked to set the ['N]th element of an instance of `type_name`. This expression may access variables named `obj` of type `type_name&`, which represent the corresponding instance of @@ -740,8 +742,8 @@ namespace qualified name of the class type to be adapted. BOOST_FUSION_ADAPT_ADT( demo::employee, - (std::string const&, std::string const&, obj.get_name(), obj.set_name(val)) - (int, int, obj.get_age(), obj.set_age(val))) + (obj.get_name(), obj.set_name(val)) + (obj.get_age(), obj.set_age(val))) demo::employee e; front(e)="Edward Norton"; @@ -766,8 +768,8 @@ __random_access_sequence__. BOOST_FUSION_ADAPT_TPL_ADT( (template_param0)(template_param1)..., (type_name) (specialization_param0)(specialization_param1)..., - (attribute_type0, attribute_const_type0, get_expr0, set_expr0) - (attribute_type1, attribute_const_type1, get_expr1, set_expr1) + ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0) + ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1) ... ) @@ -790,7 +792,9 @@ of an instance of `type_name`. This expression may access a variable named `obj` of type `type_name&` or `type_name const&` which represents the underlying instance of `type_name`. [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types -that [^get_expr['N]] denotes to. +that [^get_expr['N]] denotes to, when omitted the type is deduced from +[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for +variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type. [^set_expr['N]] is the expression that is invoked to set the ['N]th element of an instance of `type_name`. This expression may access variables named `obj` of type `type_name&`, which represent the corresponding instance of @@ -875,8 +879,8 @@ __random_access_sequence__ and __associative_sequence__. BOOST_FUSION_ADAPT_ASSOC_ADT( type_name, - (attribute_type0, attribute_const_type0, get_expr0, set_expr0, key_type0) - (attribute_type1, attribute_const_type1, get_expr1, set_expr1, key_type1) + ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0, key_type0) + ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1, key_type1) ... ) @@ -893,7 +897,9 @@ of an instance of `type_name`. This expression may access a variable named `obj` of type `type_name&` or `type_name const&` which represents the underlying instance of `type_name`. [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types -that [^get_expr['N]] denotes to. +that [^get_expr['N]] denotes to, when omitted the type is deduced from +[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for +variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type. [^set_expr['N]] is the expression that is invoked to set the ['N]th element of an instance of `type_name`. This expression may access variables named `obj` of type `type_name&`, which represent the corresponding instance of @@ -957,8 +963,8 @@ namespace qualified name of the class type to be adapted. BOOST_FUSION_ADAPT_ASSOC_ADT( demo::employee, - (std::string const&, std::string const&, obj.get_name(), obj.set_name(val), keys::name) - (int, int, obj.get_age(), obj.set_age(val), keys::age)) + (obj.get_name(), obj.set_name(val), keys::name) + (obj.get_age(), obj.set_age(val), keys::age)) demo::employee e; at_key(e)="Edward Norton"; @@ -983,8 +989,8 @@ __random_access_sequence__ and __associative_sequence__. BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( (template_param0)(template_param1)..., (type_name) (specialization_param0)(specialization_param1)..., - (attribute_type0, attribute_const_type0, get_expr0, set_expr0, key_type0) - (attribute_type1, attribute_const_type1, get_expr1, set_expr1, key_type1) + ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0, key_type0) + ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1, key_type1) ... ) @@ -999,7 +1005,7 @@ The sequence `(specialization_param0)(specialization_param1)...` declares the template parameters of the actual specialization of `type_name` that is adapted as a fusion sequence. The sequence of -[^(attribute_type['N], attribute_const_type['N], get_expr['N], set_expr['N], key_type['N])] +[^([attribute_type['N], attribute_const_type['N],] get_expr['N], set_expr['N], key_type['N])] 5-tuples declares the types, const types, get-expressions, set-expressions and key types of the elements that are part of the adapted fusion sequence. [^get_expr['N]] is the expression that is invoked to get the ['N]th element @@ -1007,7 +1013,9 @@ of an instance of `type_name`. This expression may access a variable named `obj` of type `type_name&` or `type_name const&` which represents the underlying instance of `type_name`. [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types -that [^get_expr['N]] denotes to. +that [^get_expr['N]] denotes to, when omitted the type is deduced from +[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for +variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type. [^set_expr['N]] is the expression that is invoked to set the ['N]th element of an instance of `type_name`. This expression may access variables named `obj` of type `type_name&`, which represent the corresponding instance of diff --git a/include/boost/fusion/adapted/adt/adapt_adt.hpp b/include/boost/fusion/adapted/adt/adapt_adt.hpp index 88ab177c..37781765 100644 --- a/include/boost/fusion/adapted/adt/adapt_adt.hpp +++ b/include/boost/fusion/adapted/adt/adapt_adt.hpp @@ -2,6 +2,7 @@ Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2009-2010 Hartmut Kaiser Copyright (c) 2010-2011 Christopher Schmidt + 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) @@ -13,6 +14,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -32,18 +36,20 @@ #include #include #include - -#define BOOST_FUSION_ADAPT_ADT_FILLER_0(A, B, C, D)\ - ((A, B, C, D)) BOOST_FUSION_ADAPT_ADT_FILLER_1 -#define BOOST_FUSION_ADAPT_ADT_FILLER_1(A, B, C, D)\ - ((A, B, C, D)) BOOST_FUSION_ADAPT_ADT_FILLER_0 -#define BOOST_FUSION_ADAPT_ADT_FILLER_0_END -#define BOOST_FUSION_ADAPT_ADT_FILLER_1_END +#include #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) + TEMPLATE_PARAMS_SEQ, \ + NAME_SEQ, \ + I, \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE), \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \ + BOOST_PP_IF( \ + BOOST_PP_LESS( \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 4) \ + , 1, 0)) #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 ff33ac59..14eec414 100644 --- a/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp +++ b/include/boost/fusion/adapted/adt/adapt_assoc_adt.hpp @@ -2,6 +2,7 @@ Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2007 Dan Marsden Copyright (c) 2010-2011 Christopher Schmidt + 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) @@ -35,25 +36,28 @@ #include #include #include - -#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(A, B, C, D, E)\ - ((A, B, C, D, E)) BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1 -#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(A, B, C, D, E)\ - ((A, B, C, D, E)) BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0 -#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0_END -#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1_END +#include #define BOOST_FUSION_ADAPT_ASSOC_ADT_C( \ TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \ \ - BOOST_FUSION_ADAPT_ADT_C_BASE(TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,5) \ + BOOST_FUSION_ADAPT_ADT_C_BASE( \ + TEMPLATE_PARAMS_SEQ, \ + NAME_SEQ, \ + I, \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE), \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \ + BOOST_PP_IF( \ + BOOST_PP_LESS( \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 5) \ + , 1, 0)) \ \ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ > \ struct struct_assoc_key \ { \ - typedef BOOST_PP_TUPLE_ELEM(5, 4, ATTRIBUTE) type; \ + typedef BOOST_FUSION_ADAPT_ASSOC_ADT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) type;\ }; #define BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( \ diff --git a/include/boost/fusion/adapted/adt/detail/adapt_base.hpp b/include/boost/fusion/adapted/adt/detail/adapt_base.hpp index 3de396dd..c1c78962 100644 --- a/include/boost/fusion/adapted/adt/detail/adapt_base.hpp +++ b/include/boost/fusion/adapted/adt/detail/adapt_base.hpp @@ -11,11 +11,17 @@ #define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP #include +#include + #include #include #include #include #include +#include +#include + +#include #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \ typename detail::get_identity< \ @@ -28,8 +34,43 @@ \ boost::remove_const::type>::type +#define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \ + ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \ + BOOST_PP_IF(DEDUCE_TYPE, 0, 2), ATTRIBUTE) + +#define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \ + ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \ + BOOST_PP_IF(DEDUCE_TYPE, 1, 3), ATTRIBUTE) + +#define BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF( \ + NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ + \ + struct deduced_attr_type { \ + const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \ + typedef BOOST_TYPEOF( \ + BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \ + ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, 1)) type; \ + }; \ + \ + typedef typename boost::remove_const< \ + typename deduced_attr_type::type \ + >::type type; \ + \ + typedef typename boost::add_const< \ + typename deduced_attr_type::type \ + >::type const_type; + +#define BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE( \ + NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ + \ + typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \ + typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) const_type; + + #define BOOST_FUSION_ADAPT_ADT_C_BASE( \ - TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ + TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \ \ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ @@ -39,6 +80,12 @@ , I \ > \ { \ + \ + BOOST_PP_IF(DEDUCE_TYPE, \ + BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF, \ + BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE \ + )(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \ + \ template \ BOOST_FUSION_GPU_ENABLED \ static void \ @@ -46,23 +93,26 @@ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \ Val const& val) \ { \ - BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 3, ATTRIBUTE); \ + BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \ + ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \ } \ \ BOOST_FUSION_GPU_ENABLED \ - static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ + static type \ boost_fusion_adapt_adt_impl_get( \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \ { \ - return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \ + return BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \ + ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \ } \ \ BOOST_FUSION_GPU_ENABLED \ - static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) \ + static const_type \ boost_fusion_adapt_adt_impl_get( \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \ { \ - return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \ + return BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \ + ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \ } \ }; \ \ @@ -75,7 +125,10 @@ , true \ > \ { \ - typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) type; \ + typedef typename access::adt_attribute_access< \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ + , I \ + >::const_type type; \ \ BOOST_FUSION_GPU_ENABLED \ explicit \ @@ -111,7 +164,10 @@ , false \ > \ { \ - typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \ + typedef typename access::adt_attribute_access< \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ + , I \ + >::type type; \ \ BOOST_FUSION_GPU_ENABLED \ explicit \ @@ -158,7 +214,13 @@ , I \ > \ { \ - typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) lvalue; \ + typedef typename \ + adt_attribute_proxy< \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ + , I \ + , false \ + >::type lvalue; \ + \ BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ TEMPLATE_PARAMS_SEQ) \ \ diff --git a/include/boost/fusion/adapted/adt/detail/adapt_base_assoc_attr_filler.hpp b/include/boost/fusion/adapted/adt/detail/adapt_base_assoc_attr_filler.hpp new file mode 100644 index 00000000..b9c93b7d --- /dev/null +++ b/include/boost/fusion/adapted/adt/detail/adapt_base_assoc_attr_filler.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + 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_ADAPTER_ADT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP +#define BOOST_FUSION_ADAPTER_ADT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP + +#include + +#include + +#include +#include +#include +#include + +#if BOOST_PP_VARIADICS + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(...) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(__VA_ARGS__) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1 + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(...) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(__VA_ARGS__) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0 + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(...) \ + ((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))) + +#else // BOOST_PP_VARIADICS + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(A, B, C, D, E) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1 + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(A, B, C, D, E) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \ + BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0 + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \ + BOOST_PP_IF(BOOST_PP_IS_EMPTY(A), \ + ((3, (C,D,E))), \ + ((5, (A,B,C,D,E))) \ + ) + +#endif // BOOST_PP_VARIADICS + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0_END +#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1_END + + +#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) \ + BOOST_PP_TUPLE_ELEM( \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \ + BOOST_PP_SUB(BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 1), \ + BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE)) + +#endif diff --git a/include/boost/fusion/adapted/adt/detail/adapt_base_attr_filler.hpp b/include/boost/fusion/adapted/adt/detail/adapt_base_attr_filler.hpp new file mode 100644 index 00000000..09bd4014 --- /dev/null +++ b/include/boost/fusion/adapted/adt/detail/adapt_base_attr_filler.hpp @@ -0,0 +1,90 @@ +/*============================================================================= + 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_ADT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP +#define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE) \ + BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) + +#define BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE) \ + BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE) + +#if BOOST_PP_VARIADICS + +# define BOOST_FUSION_ADAPT_ADT_FILLER_0(...) \ + BOOST_FUSION_ADAPT_ADT_FILLER(__VA_ARGS__) \ + BOOST_FUSION_ADAPT_ADT_FILLER_1 + +# define BOOST_FUSION_ADAPT_ADT_FILLER_1(...) \ + BOOST_FUSION_ADAPT_ADT_FILLER(__VA_ARGS__) \ + BOOST_FUSION_ADAPT_ADT_FILLER_0 + +# define BOOST_FUSION_ADAPT_ADT_FILLER_0_END +# define BOOST_FUSION_ADAPT_ADT_FILLER_1_END + +# define BOOST_FUSION_ADAPT_ADT_FILLER(...) \ + BOOST_PP_IF( \ + BOOST_PP_OR( \ + BOOST_PP_IS_EMPTY(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)), \ + BOOST_PP_IS_EMPTY(BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__))), \ + BOOST_FUSION_ADAPT_ADT_WRAP_ATTR( \ + BOOST_PP_VARIADIC_ELEM(2, __VA_ARGS__), \ + BOOST_FUSION_WORKAROUND_VARIADIC_EMPTINESS_LAST_ELEM(__VA_ARGS__) \ + ), \ + BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(__VA_ARGS__)) + +# define BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(...) \ + ((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))) + +# define BOOST_FUSION_WORKAROUND_VARIADIC_EMPTINESS_LAST_ELEM(...) \ + BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REST_N( \ + BOOST_PP_SUB(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1), \ + BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))) + +#else // BOOST_PP_VARIADICS + +# define BOOST_FUSION_ADAPT_ADT_FILLER_0(A, B, C, D) \ + BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A,B,C,D) \ + BOOST_FUSION_ADAPT_ADT_FILLER_1 + +# define BOOST_FUSION_ADAPT_ADT_FILLER_1(A, B, C, D) \ + BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A,B,C,D) \ + BOOST_FUSION_ADAPT_ADT_FILLER_0 + +# define BOOST_FUSION_ADAPT_ADT_FILLER_0_END +# define BOOST_FUSION_ADAPT_ADT_FILLER_1_END + +# define BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A, B, C, D) \ + BOOST_PP_IF(BOOST_PP_IS_EMPTY(A), \ + ((2, (C,D))), \ + ((4, (A,B,C,D))) \ + ) + +#endif // BOOST_PP_VARIADICS + +#endif diff --git a/include/boost/fusion/adapted/struct/adapt_struct.hpp b/include/boost/fusion/adapted/struct/adapt_struct.hpp index 09c9015a..e96e7c76 100644 --- a/include/boost/fusion/adapted/struct/adapt_struct.hpp +++ b/include/boost/fusion/adapted/struct/adapt_struct.hpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -42,10 +44,12 @@ 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), \ + BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR(ATTRIBUTE), \ + BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), \ BOOST_PP_IF( \ - BOOST_PP_LESS(BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE),2), 1, 0)) + BOOST_PP_LESS( \ + BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), 2) \ + , 1, 0)) diff --git a/include/boost/fusion/adapted/struct/detail/adapt_auto.hpp b/include/boost/fusion/adapted/struct/detail/adapt_auto.hpp new file mode 100644 index 00000000..5178150b --- /dev/null +++ b/include/boost/fusion/adapted/struct/detail/adapt_auto.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + 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_AUTO_HPP +#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_AUTO_HPP + +#include + +#define BOOST_FUSION_ADAPT_AUTO BOOST_PP_EMPTY() + +#endif diff --git a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp index ce92db05..dc6ec3ce 100644 --- a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp +++ b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,6 @@ #include -#define BOOST_FUSION_ADAPT_AUTO BOOST_PP_EMPTY() #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \ BOOST_PP_SEQ_HEAD(SEQ) \ @@ -64,13 +64,13 @@ #define BOOST_FUSION_ATTRIBUTE_TYPEOF( \ 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)) + 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, unused) \ - BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) + 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( \ diff --git a/include/boost/fusion/adapted/struct/detail/adapt_base_assoc_attr_filler.hpp b/include/boost/fusion/adapted/struct/detail/adapt_base_assoc_attr_filler.hpp index 725af756..c75e83c3 100644 --- a/include/boost/fusion/adapted/struct/detail/adapt_base_assoc_attr_filler.hpp +++ b/include/boost/fusion/adapted/struct/detail/adapt_base_assoc_attr_filler.hpp @@ -31,7 +31,8 @@ #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(...) \ ((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))) -#else +#else // BOOST_PP_VARIADICS + #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(X, Y, Z) \ BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(X, Y, Z) \ @@ -47,7 +48,7 @@ ((3, (X,Y,Z))) \ ) -#endif +#endif // BOOST_PP_VARIADICS #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0_END #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1_END diff --git a/test/sequence/adapt_adt.cpp b/test/sequence/adapt_adt.cpp index d4f4a8c2..265cfca5 100644 --- a/test/sequence/adapt_adt.cpp +++ b/test/sequence/adapt_adt.cpp @@ -38,18 +38,21 @@ namespace ns { public: - point() : x(0), y(0) {} - point(int in_x, int in_y) : x(in_x), y(in_y) {} + point() : x(0), y(0), z(0) {} + point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {} int get_x() const { return x; } int get_y() const { return y; } + int get_z() const { return z; } void set_x(int x_) { x = x_; } void set_y(int y_) { y = y_; } + void set_z(int z_) { z = z_; } private: int x; int y; + int z; }; #if !BOOST_WORKAROUND(__GNUC__,<4) @@ -58,17 +61,22 @@ namespace ns friend struct boost::fusion::extension::access; public: - point_with_private_members() : x(0), y(0) {} - point_with_private_members(int x, int y) : x(x), y(y) {} - - private: + point_with_private_members() : x(0), y(0), z(0) {} + point_with_private_members(int in_x, int in_y, int in_z) + : x(in_x), y(in_y), z(in_z) {} + int get_x() const { return x; } int get_y() const { return y; } + int get_z() const { return z; } void set_x(int x_) { x = x_; } void set_y(int y_) { y = y_; } - + void set_z(int z_) { z = z_; } + + private: + int x; int y; + int z; }; #endif @@ -91,26 +99,56 @@ namespace ns }; } -BOOST_FUSION_ADAPT_ADT( - ns::point, - (int, int, obj.get_x(), obj.set_x(val)) - (int, int, obj.get_y(), obj.set_y(val)) -) +#if BOOST_PP_VARIADICS + BOOST_FUSION_ADAPT_ADT( + ns::point, + (int, int, obj.get_x(), obj.set_x(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) + (obj.get_z(), obj.set_z(val)) + ) + +# if !BOOST_WORKAROUND(__GNUC__,<4) + BOOST_FUSION_ADAPT_ADT( + ns::point_with_private_members, + (obj.get_x(), obj.set_x(val)) + (obj.get_y(), obj.set_y(val)) + (obj.get_z(), obj.set_z(val)) + ) +# endif + + + BOOST_FUSION_ADAPT_ADT( + ns::name, + (obj.get_last(), obj.set_last(val)) + (obj.get_first(), obj.set_first(val)) + ) + + +#else // BOOST_PP_VARIADICS + BOOST_FUSION_ADAPT_ADT( + ns::point, + (int, int, obj.get_x(), obj.set_x(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val)) + ) + +# if !BOOST_WORKAROUND(__GNUC__,<4) + BOOST_FUSION_ADAPT_ADT( + ns::point_with_private_members, + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_x(), obj.set_x(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val)) + ) +# endif + + BOOST_FUSION_ADAPT_ADT( + ns::name, + (const std::string&, const std::string&, obj.get_last(), obj.set_last(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_first(), obj.set_first(val)) + ) -#if !BOOST_WORKAROUND(__GNUC__,<4) -BOOST_FUSION_ADAPT_ADT( - ns::point_with_private_members, - (int, int, obj.get_x(), obj.set_x(val)) - (int, int, obj.get_y(), obj.set_y(val)) -) #endif -BOOST_FUSION_ADAPT_ADT( - ns::name, - (const std::string&, const std::string&, obj.get_last(), obj.set_last(val)) - (const std::string&, const std::string&, obj.get_first(), obj.set_first(val)) -) - int main() { @@ -123,28 +161,30 @@ main() { BOOST_MPL_ASSERT_NOT((traits::is_view)); - ns::point p(123, 456); + ns::point p(123, 456, 789); 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 v2(5, 3); - fusion::vector v3(5, 4); + fusion::vector v1(4, 2, 2); + ns::point v2(5, 3, 3); + fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -171,15 +211,15 @@ main() { // conversion from ns::point to vector - ns::point p(5, 3); - fusion::vector v(p); + ns::point p(5, 3, 3); + 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, 3); + fusion::list l(p); l = p; } @@ -193,26 +233,29 @@ main() #if !BOOST_WORKAROUND(__GNUC__,<4) { BOOST_MPL_ASSERT_NOT((traits::is_view)); - ns::point_with_private_members p(123, 456); + ns::point_with_private_members p(123, 456, 789); 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); } #endif { + // Check types provided in case it's provided BOOST_MPL_ASSERT(( boost::is_same< boost::fusion::result_of::front::type, @@ -233,6 +276,28 @@ main() boost::fusion::result_of::front::type::type, int >)); + + // Check types provided in case it's deduced + BOOST_MPL_ASSERT(( + boost::is_same< + boost::fusion::result_of::back::type, + boost::fusion::extension::adt_attribute_proxy + >)); + BOOST_MPL_ASSERT(( + boost::is_same< + boost::fusion::result_of::back::type::type, + int + >)); + BOOST_MPL_ASSERT(( + boost::is_same< + boost::fusion::result_of::back::type, + boost::fusion::extension::adt_attribute_proxy + >)); + BOOST_MPL_ASSERT(( + boost::is_same< + boost::fusion::result_of::back::type::type, + const int + >)); } return boost::report_errors(); diff --git a/test/sequence/adapt_adt_named.cpp b/test/sequence/adapt_adt_named.cpp index 38415633..cdb4806f 100644 --- a/test/sequence/adapt_adt_named.cpp +++ b/test/sequence/adapt_adt_named.cpp @@ -37,28 +37,46 @@ namespace ns { public: - point() : x(0), y(0) {} - point(int in_x, int in_y) : x(in_x), y(in_y) {} + point() : x(0), y(0), z(0) {} + point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {} int get_x() const { return x; } int get_y() const { return y; } + int get_z() const { return z; } void set_x(int x_) { x = x_; } void set_y(int y_) { y = y_; } + void set_z(int z_) { z = z_; } private: int x; int y; + int z; }; } +#if BOOST_PP_VARIADICS + // this creates a fusion view: boost::fusion::adapted::point BOOST_FUSION_ADAPT_ADT_NAMED( ns::point, point, (int, int, obj.obj.get_x(), obj.obj.set_x(val)) (int, int, obj.obj.get_y(), obj.obj.set_y(val)) + (obj.obj.get_z(), obj.obj.set_z(val)) ) +#else // BOOST_PP_VARIADICS + +// this creates a fusion view: boost::fusion::adapted::point +BOOST_FUSION_ADAPT_ADT_NAMED( + ns::point, point, + (int, int, obj.obj.get_x(), obj.obj.set_x(val)) + (int, int, obj.obj.get_y(), obj.obj.set_y(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.obj.get_z(), obj.obj.set_z(val)) +) + +#endif // BOOST_PP_VARIADICS + int main() { @@ -71,31 +89,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 basep(5, 3); + fusion::vector v1(4, 2, 2); + ns::point basep(5, 3, 3); adapted::point v2(basep); - fusion::vector v3(5, 4); + fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -108,19 +128,19 @@ main() { // conversion from ns::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 ns::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; } diff --git a/test/sequence/adapt_assoc_adt.cpp b/test/sequence/adapt_assoc_adt.cpp index c97e84b0..a03605f1 100644 --- a/test/sequence/adapt_assoc_adt.cpp +++ b/test/sequence/adapt_assoc_adt.cpp @@ -26,31 +26,50 @@ namespace ns struct y_member; struct z_member; + struct non_member; + class point { public: - point() : x(0), y(0) {} - point(int in_x, int in_y) : x(in_x), y(in_y) {} + point() : x(0), y(0), z(0) {} + point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {} int get_x() const { return x; } int get_y() const { return y; } + int get_z() const { return z; } void set_x(int x_) { x = x_; } void set_y(int y_) { y = y_; } + void set_z(int z_) { z = z_; } private: int x; int y; + int z; }; } +#if BOOST_PP_VARIADICS + BOOST_FUSION_ADAPT_ASSOC_ADT( ns::point, (int, int, obj.get_x(), obj.set_x(val), ns::x_member) (int, int, obj.get_y(), obj.set_y(val), ns::y_member) + (obj.get_z(), obj.set_z(val), ns::z_member) ) +#else // BOOST_PP_VARIADICS + +BOOST_FUSION_ADAPT_ASSOC_ADT( + ns::point, + (int, int, obj.get_x(), obj.set_x(val), ns::x_member) + (int, int, obj.get_y(), obj.set_y(val), ns::y_member) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val), ns::z_member) +) + +#endif + int main() { @@ -62,28 +81,30 @@ main() { BOOST_MPL_ASSERT_NOT((traits::is_view)); - ns::point p(123, 456); + ns::point p(123, 456, 789); 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); } { - boost::fusion::vector v1(4, 2); - ns::point v2(5, 3); - boost::fusion::vector v3(5, 4); + boost::fusion::vector v1(4, 2, 2); + ns::point v2(5, 3, 3); + boost::fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -96,15 +117,15 @@ main() { // conversion from ns::point to vector - ns::point p(5, 3); - boost::fusion::vector v(p); + ns::point p(5, 3, 3); + boost::fusion::vector v(p); v = p; } { // conversion from ns::point to list - ns::point p(5, 3); - boost::fusion::list l(p); + ns::point p(5, 3, 3); + boost::fusion::list l(p); l = p; } @@ -119,15 +140,19 @@ main() // assoc stuff BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); - BOOST_MPL_ASSERT((boost::mpl::not_ >)); + BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); + BOOST_MPL_ASSERT((boost::mpl::not_ >)); + BOOST_MPL_ASSERT((boost::is_same::type, int>)); BOOST_MPL_ASSERT((boost::is_same::type, int>)); + BOOST_MPL_ASSERT((boost::is_same::type, int>)); - ns::point p(5, 3); + ns::point p(5, 3, 1); BOOST_TEST(at_key(p) == 5); BOOST_TEST(at_key(p) == 3); + BOOST_TEST(at_key(p) == 1); } return boost::report_errors(); diff --git a/test/sequence/adapt_assoc_tpl_adt.cpp b/test/sequence/adapt_assoc_tpl_adt.cpp index 15e2124c..8aa600ff 100644 --- a/test/sequence/adapt_assoc_tpl_adt.cpp +++ b/test/sequence/adapt_assoc_tpl_adt.cpp @@ -26,39 +26,57 @@ namespace ns struct y_member; struct z_member; - template + struct non_member; + + template class point { public: - point() : x(0), y(0) {} - point(X in_x, Y in_y) : x(in_x), y(in_y) {} + point() : x(0), y(0), z(0) {} + point(X in_x, Y in_y, Z in_z) : x(in_x), y(in_y), z(in_z) {} X get_x() const { return x; } Y get_y() const { return y; } + Z get_z() const { return z; } void set_x(X x_) { x = x_; } void set_y(Y y_) { y = y_; } + void set_z(Z z_) { z = z_; } private: X x; Y y; + Z z; }; } +#if BOOST_PP_VARIADICS BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( - (X)(Y), - (ns::point)(X)(Y), + (X)(Y)(Z), + (ns::point)(X)(Y)(Z), (X, X, obj.get_x(), obj.set_x(val), ns::x_member) (Y, Y, obj.get_y(), obj.set_y(val), ns::y_member) + (obj.get_z(), obj.set_z(val), ns::z_member) ) + +#else // BOOST_PP_VARIADICS +BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( + (X)(Y)(Z), + (ns::point)(X)(Y)(Z), + (X, X, obj.get_x(), obj.set_x(val), ns::x_member) + (Y, Y, obj.get_y(), obj.set_y(val), ns::y_member) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val), ns::z_member) +) + +#endif int main() { using namespace boost::fusion; - typedef ns::point point; + typedef ns::point point; std::cout << tuple_open('['); std::cout << tuple_close(']'); @@ -66,28 +84,30 @@ main() { BOOST_MPL_ASSERT_NOT((traits::is_view)); - point p(123, 456); + point p(123, 456, 789); 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); } { - boost::fusion::vector v1(4, 2); - point v2(5, 3); - boost::fusion::vector v3(5, 4); + boost::fusion::vector v1(4, 2, 2); + point v2(5, 3, 3); + boost::fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -100,15 +120,15 @@ main() { // conversion from point to vector - point p(5, 3); - boost::fusion::vector v(p); + point p(5, 3, 3); + boost::fusion::vector v(p); v = p; } { // conversion from point to list - point p(5, 3); - boost::fusion::list l(p); + point p(5, 3, 3); + boost::fusion::list l(p); l = p; } @@ -123,15 +143,18 @@ main() // assoc stuff BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); - BOOST_MPL_ASSERT((boost::mpl::not_ >)); + BOOST_MPL_ASSERT((boost::fusion::result_of::has_key)); + BOOST_MPL_ASSERT((boost::mpl::not_ >)); BOOST_MPL_ASSERT((boost::is_same::type, int>)); BOOST_MPL_ASSERT((boost::is_same::type, int>)); + BOOST_MPL_ASSERT((boost::is_same::type, long>)); - point p(5, 3); + point p(5, 3, 1); BOOST_TEST(at_key(p) == 5); BOOST_TEST(at_key(p) == 3); + BOOST_TEST(at_key(p) == 1); } return boost::report_errors(); diff --git a/test/sequence/adapt_tpl_adt.cpp b/test/sequence/adapt_tpl_adt.cpp index aeb0f721..bbd1d07f 100644 --- a/test/sequence/adapt_tpl_adt.cpp +++ b/test/sequence/adapt_tpl_adt.cpp @@ -39,27 +39,45 @@ namespace ns { public: - point() : x(0), y(0) {} - point(X x_, Y y_) : x(x_), y(y_) {} + point() : x(0), y(0), z(0) {} + point(X x_, Y y_, int z_) : x(x_), y(y_), z(z_) {} X get_x() const { return x; } Y get_y() const { return y; } + int get_z() const { return z; } void set_x(X x_) { x = x_; } void set_y(Y y_) { y = y_; } + void set_z(int z_) { z = z_; } private: X x; Y y; + int z; }; } -BOOST_FUSION_ADAPT_TPL_ADT( - (X)(Y), - (ns::point)(X)(Y), - (X, X, obj.get_x(), obj.set_x(val)) - (Y, Y, obj.get_y(), obj.set_y(val)) -) + +#if BOOST_PP_VARIADICS + + BOOST_FUSION_ADAPT_TPL_ADT( + (X)(Y), + (ns::point)(X)(Y), + (X, X, obj.get_x(), obj.set_x(val)) + (Y, Y, obj.get_y(), obj.set_y(val)) + (obj.get_z(), obj.set_z(val)) + ) + +#else // BOOST_PP_VARIADICS + + BOOST_FUSION_ADAPT_TPL_ADT( + (X)(Y), + (ns::point)(X)(Y), + (X, X, obj.get_x(), obj.set_x(val)) + (Y, Y, obj.get_y(), obj.set_y(val)) + (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val)) + ) +#endif int main() @@ -75,28 +93,30 @@ main() { BOOST_MPL_ASSERT_NOT((traits::is_view)); - point p(123, 456); + point p(123, 456, 789); 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); } { - boost::fusion::vector v1(4, 2); - point v2(5, 3); - boost::fusion::vector v3(5, 4); + boost::fusion::vector v1(4, 2, 2); + point v2(5, 3, 3); + boost::fusion::vector v3(5, 4, 4); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -108,9 +128,9 @@ main() } { - boost::fusion::vector v1("Lincoln", "Abraham"); - name v2("Roosevelt", "Franklin"); - name v3("Roosevelt", "Theodore"); + boost::fusion::vector v1("Lincoln", "Abraham", 3); + name v2("Roosevelt", "Franklin", 3); + name v3("Roosevelt", "Theodore", 3); BOOST_TEST(v1 < v2); BOOST_TEST(v1 <= v2); BOOST_TEST(v2 > v1); @@ -123,15 +143,15 @@ main() { // conversion from point to vector - point p(5, 3); - boost::fusion::vector v(p); + point p(5, 3, 3); + boost::fusion::vector v(p); v = p; } { // conversion from point to list - point p(5, 3); - boost::fusion::list l(p); + point p(5, 3, 3); + boost::fusion::list l(p); l = p; }