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_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/test/sequence/adapt_assoc_adt.cpp b/test/sequence/adapt_assoc_adt.cpp index c97e84b0..70d70ba4 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 unavailable_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,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>)); - 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();