diff --git a/include/boost/fusion/adapted/class/detail/adapt_base.hpp b/include/boost/fusion/adapted/class/detail/adapt_base.hpp index 264390a6..9906535e 100644 --- a/include/boost/fusion/adapted/class/detail/adapt_base.hpp +++ b/include/boost/fusion/adapted/class/detail/adapt_base.hpp @@ -37,7 +37,7 @@ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ > \ - struct class_member_proxy< \ + struct access::class_member_proxy< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ , I \ > \ @@ -71,9 +71,14 @@ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ > \ - struct struct_member \ + struct access::struct_member< \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ + , I \ + > \ { \ typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) lvalue; \ + BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ + TEMPLATE_PARAMS_SEQ) \ \ typedef \ BOOST_PP_IF( \ @@ -87,7 +92,7 @@ struct apply \ { \ typedef \ - class_member_proxy< \ + access::class_member_proxy< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ , I \ > \ diff --git a/include/boost/fusion/adapted/class/detail/extension.hpp b/include/boost/fusion/adapted/class/detail/extension.hpp index 0ad7c66e..ae800275 100644 --- a/include/boost/fusion/adapted/class/detail/extension.hpp +++ b/include/boost/fusion/adapted/class/detail/extension.hpp @@ -13,21 +13,12 @@ #include #include -namespace boost { namespace fusion +namespace boost { namespace fusion { namespace detail { - namespace detail - { - template - struct get_identity - : remove_const::type> - {}; - } - - namespace extension - { - template - struct class_member_proxy; - } -}} + template + struct get_identity + : remove_const::type> + {}; +}}} #endif diff --git a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp index b2d81cf8..503fc236 100644 --- a/include/boost/fusion/adapted/struct/detail/adapt_base.hpp +++ b/include/boost/fusion/adapted/struct/detail/adapt_base.hpp @@ -87,15 +87,41 @@ I, \ ATTRIBUTE) +#ifdef BOOST_MSVC +# define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM(R,_,ELEM) \ + typedef ELEM ELEM; +# define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL(SEQ) \ + BOOST_PP_SEQ_FOR_EACH( \ + BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM, \ + _, \ + BOOST_PP_SEQ_TAIL(SEQ)) +# define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) \ + BOOST_PP_IF( \ + BOOST_PP_SEQ_HEAD(SEQ), \ + BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL, \ + BOOST_PP_TUPLE_EAT(1))(SEQ) +#else +# define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) +#endif + #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ \ template< \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ > \ - struct struct_member \ + struct access::struct_member< \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ + , I \ + > \ { \ - typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \ + typedef \ + BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ + attribute_type; \ + BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ + TEMPLATE_PARAMS_SEQ) \ + \ + typedef attribute_type type; \ \ template \ struct apply \ @@ -104,12 +130,8 @@ add_reference< \ typename mpl::eval_if< \ is_const \ - , add_const \ - , mpl::identity \ + , add_const \ + , mpl::identity \ >::type \ >::type \ type; \ diff --git a/include/boost/fusion/adapted/struct/detail/at_impl.hpp b/include/boost/fusion/adapted/struct/detail/at_impl.hpp index febb6335..99c63e9a 100644 --- a/include/boost/fusion/adapted/struct/detail/at_impl.hpp +++ b/include/boost/fusion/adapted/struct/detail/at_impl.hpp @@ -22,7 +22,7 @@ namespace boost { namespace fusion { namespace extension { template struct apply - : extension::struct_member< + : access::struct_member< typename remove_const::type , N::value >::template apply diff --git a/include/boost/fusion/adapted/struct/detail/deref_impl.hpp b/include/boost/fusion/adapted/struct/detail/deref_impl.hpp index 498617a3..3f25efef 100644 --- a/include/boost/fusion/adapted/struct/detail/deref_impl.hpp +++ b/include/boost/fusion/adapted/struct/detail/deref_impl.hpp @@ -20,7 +20,7 @@ namespace boost { namespace fusion { namespace extension struct apply { typedef typename - extension::struct_member< + access::struct_member< typename remove_const::type , It::index::value >::template apply diff --git a/include/boost/fusion/adapted/struct/detail/extension.hpp b/include/boost/fusion/adapted/struct/detail/extension.hpp index 1f9f4f75..302952b1 100644 --- a/include/boost/fusion/adapted/struct/detail/extension.hpp +++ b/include/boost/fusion/adapted/struct/detail/extension.hpp @@ -27,8 +27,14 @@ namespace boost { namespace fusion { struct no_such_member; - template - struct struct_member; + struct access + { + template + struct struct_member; + + template + struct class_member_proxy; + }; template struct struct_member_name; diff --git a/include/boost/fusion/adapted/struct/detail/value_at_impl.hpp b/include/boost/fusion/adapted/struct/detail/value_at_impl.hpp index 5ecf4ac7..08c82fc0 100644 --- a/include/boost/fusion/adapted/struct/detail/value_at_impl.hpp +++ b/include/boost/fusion/adapted/struct/detail/value_at_impl.hpp @@ -20,7 +20,7 @@ namespace boost { namespace fusion { namespace extension { template struct apply - : struct_member::type, N::value> + : access::struct_member::type, N::value> {}; }; diff --git a/include/boost/fusion/adapted/struct/detail/value_of_impl.hpp b/include/boost/fusion/adapted/struct/detail/value_of_impl.hpp index 55d37ed7..63dcbe52 100644 --- a/include/boost/fusion/adapted/struct/detail/value_of_impl.hpp +++ b/include/boost/fusion/adapted/struct/detail/value_of_impl.hpp @@ -18,7 +18,7 @@ namespace boost { namespace fusion { namespace extension { template struct apply - : extension::struct_member< + : access::struct_member< typename remove_const::type , It::index::value > diff --git a/test/sequence/adapt_class.cpp b/test/sequence/adapt_class.cpp index a584f49f..a1016ee3 100644 --- a/test/sequence/adapt_class.cpp +++ b/test/sequence/adapt_class.cpp @@ -50,6 +50,26 @@ namespace ns int x; int y; }; + +#if !BOOST_WORKAROUND(__GNUC__,<4) + class point_with_private_members + { + 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: + int get_x() const { return x; } + int get_y() const { return y; } + void set_x(int x_) { x = x_; } + void set_y(int y_) { y = y_; } + + int x; + int y; + }; +#endif } BOOST_FUSION_ADAPT_CLASS( @@ -58,6 +78,14 @@ BOOST_FUSION_ADAPT_CLASS( (int, int, obj.get_y(), obj.set_y(val)) ) +#if !BOOST_WORKAROUND(__GNUC__,<4) +BOOST_FUSION_ADAPT_CLASS( + ns::point_with_private_members, + (int, int, obj.get_x(), obj.set_x(val)) + (int, int, obj.get_y(), obj.set_y(val)) +) +#endif + int main() { @@ -124,6 +152,28 @@ main() , mpl::front::type>)); } +#if !BOOST_WORKAROUND(__GNUC__,<4) + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + ns::point_with_private_members p(123, 456); + + 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)); + + at_c<0>(p) = 6; + at_c<1>(p) = 9; + BOOST_TEST(p == make_vector(6, 9)); + + BOOST_STATIC_ASSERT(result_of::size::value == 2); + BOOST_STATIC_ASSERT(!result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 9); + } +#endif + return boost::report_errors(); } diff --git a/test/sequence/adapt_struct.cpp b/test/sequence/adapt_struct.cpp index 7fd5cac0..10b7a89a 100644 --- a/test/sequence/adapt_struct.cpp +++ b/test/sequence/adapt_struct.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,21 @@ namespace ns int x; int y; }; + +#if !BOOST_WORKAROUND(__GNUC__,<4) + struct point_with_private_attributes + { + friend struct boost::fusion::extension::access; + + private: + int x; + int y; + + public: + point_with_private_attributes(int x, int y):x(x),y(y) + {} + }; +#endif } BOOST_FUSION_ADAPT_STRUCT( @@ -46,6 +62,14 @@ BOOST_FUSION_ADAPT_STRUCT( (int, y) ) +#if !BOOST_WORKAROUND(__GNUC__,<4) +BOOST_FUSION_ADAPT_STRUCT( + ns::point_with_private_attributes, + (int, x) + (int, y) +) +#endif + struct s { int m; }; BOOST_FUSION_ADAPT_STRUCT(s, (int, m)) @@ -118,7 +142,6 @@ main() BOOST_MPL_ASSERT((is_same::type, e>)); } - { BOOST_MPL_ASSERT((mpl::is_sequence)); BOOST_MPL_ASSERT((boost::is_same< @@ -126,6 +149,17 @@ main() , mpl::front::type>)); } +#if !BOOST_WORKAROUND(__GNUC__,<4) + { + ns::point_with_private_attributes p(123, 456); + + 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)); + } +#endif + return boost::report_errors(); }