diff --git a/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp index a7961ec3..a27957c0 100644 --- a/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp +++ b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp @@ -61,15 +61,20 @@ BOOST_PP_COMMA_IF(N) \ BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)) +#define BOOST_FUSION_ITERATOR_NAME(NAME) \ + BOOST_PP_CAT(boost_fusion_detail_, BOOST_PP_CAT(NAME, _iterator)) + // Note: all template parameter names need to be uglified, otherwise they might // shadow a template parameter of the struct when used with // BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE #define BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS(Z, N, NAME) \ - template \ - struct value_of > \ + template \ + struct value_of< \ + BOOST_FUSION_ITERATOR_NAME(NAME) \ + > \ : boost::mpl::identity< \ - typename boost_fusion_uglified_Sq::t##N##_type \ + typename boost_fusion_detail_Sq::t##N##_type \ > \ { \ }; @@ -77,10 +82,10 @@ #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ SPEC_TYPE, CALL_ARG_TYPE, TYPE_QUAL, ATTRIBUTE, N) \ \ - template \ + template \ struct deref > \ { \ - typedef typename boost_fusion_uglified_Sq::t##N##_type TYPE_QUAL& type; \ + typedef typename boost_fusion_detail_Sq::t##N##_type TYPE_QUAL& type; \ static type call(CALL_ARG_TYPE, N> const& iter) \ { \ return iter.seq_.BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); \ @@ -89,48 +94,48 @@ #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS(R, NAME, N, ATTRIBUTE) \ BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ - BOOST_PP_CAT(NAME, _iterator) \ - struct value_at > \ + template \ + struct value_at > \ { \ - typedef typename boost_fusion_uglified_Sq::t##N##_type type; \ + typedef typename boost_fusion_detail_Sq::t##N##_type type; \ }; #define BOOST_FUSION_MAKE_AT_SPECS(R, DATA, N, ATTRIBUTE) \ - template \ - struct at > \ + template \ + struct at > \ { \ typedef typename boost::mpl::if_< \ - boost::is_const, \ - typename boost_fusion_uglified_Sq::t##N##_type const&, \ - typename boost_fusion_uglified_Sq::t##N##_type& \ + boost::is_const, \ + typename boost_fusion_detail_Sq::t##N##_type const&, \ + typename boost_fusion_detail_Sq::t##N##_type& \ >::type type; \ \ - static type call(boost_fusion_uglified_Sq& sq) \ + static type call(boost_fusion_detail_Sq& sq) \ { \ return sq. BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); \ } \ @@ -142,7 +147,11 @@ #define BOOST_FUSION_MAKE_DATA_MEMBER(R, DATA, N, ATTRIBUTE) \ BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); +// Note: We can't nest the iterator inside the struct because we run into +// a MSVC10 bug involving partial specializations of nested templates. + #define BOOST_FUSION_DEFINE_STRUCT_INLINE_IMPL(NAME, ATTRIBUTES) \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ struct NAME : boost::fusion::sequence_facade< \ NAME, \ boost::fusion::random_access_traversal_tag \ @@ -154,6 +163,8 @@ #define BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE_IMPL( \ TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES) \ \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ + \ template < \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL( \ (0)TEMPLATE_PARAMS_SEQ) \ @@ -179,6 +190,113 @@ ATTRIBUTES_SEQ, \ BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)) +#define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ + BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL( \ + NAME, \ + BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END)) + +#define BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(NAME, ATTRIBUTES_SEQ) \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \ + NAME, \ + ATTRIBUTES_SEQ, \ + BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)) + +#define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ + \ + template \ + struct BOOST_FUSION_ITERATOR_NAME(NAME) \ + : boost::fusion::iterator_facade< \ + BOOST_FUSION_ITERATOR_NAME(NAME), \ + boost::fusion::random_access_traversal_tag \ + > \ + { \ + typedef boost::mpl::int_ index; \ + typedef boost_fusion_detail_Seq sequence_type; \ + \ + BOOST_FUSION_ITERATOR_NAME(NAME)(boost_fusion_detail_Seq& seq) \ + : seq_(seq) {} \ + \ + boost_fusion_detail_Seq& seq_; \ + \ + template struct value_of; \ + BOOST_PP_REPEAT( \ + ATTRIBUTES_SEQ_SIZE, \ + BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS, \ + NAME) \ + \ + template struct deref; \ + BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS, \ + NAME, \ + ATTRIBUTES_SEQ) \ + \ + template \ + struct next \ + { \ + typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ + typename boost_fusion_detail_It::sequence_type, \ + boost_fusion_detail_It::index::value + 1 \ + > type; \ + \ + static type call(boost_fusion_detail_It const& it) \ + { \ + return type(it.seq_); \ + } \ + }; \ + \ + template \ + struct prior \ + { \ + typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ + typename boost_fusion_detail_It::sequence_type, \ + boost_fusion_detail_It::index::value - 1 \ + > type; \ + \ + static type call(boost_fusion_detail_It const& it) \ + { \ + return type(it.seq_); \ + } \ + }; \ + \ + template < \ + typename boost_fusion_detail_It1, \ + typename boost_fusion_detail_It2 \ + > \ + struct distance \ + { \ + typedef typename boost::mpl::minus< \ + typename boost_fusion_detail_It2::index, \ + typename boost_fusion_detail_It1::index \ + >::type type; \ + \ + static type call(boost_fusion_detail_It1 const& it1, \ + boost_fusion_detail_It2 const& it2) \ + { \ + return type(); \ + } \ + }; \ + \ + template < \ + typename boost_fusion_detail_It, \ + typename boost_fusion_detail_M \ + > \ + struct advance \ + { \ + typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ + typename boost_fusion_detail_It::sequence_type, \ + boost_fusion_detail_It::index::value \ + + boost_fusion_detail_M::value \ + > type; \ + \ + static type call(boost_fusion_detail_It const& it) \ + { \ + return type(it.seq_); \ + } \ + }; \ + }; + + #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL( \ NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ \ @@ -197,152 +315,62 @@ BOOST_FUSION_IGNORE_2) \ (NAME, ATTRIBUTES_SEQ) \ \ - template \ - NAME(const boost_fusion_uglified_Seq& rhs) \ + template \ + NAME(const boost_fusion_detail_Seq& rhs) \ { \ boost::fusion::copy(rhs, *this); \ } \ \ - template \ - NAME& operator=(const boost_fusion_uglified_Seq& rhs) \ + template \ + NAME& operator=(const boost_fusion_detail_Seq& rhs) \ { \ boost::fusion::copy(rhs, *this); \ return *this; \ } \ \ - template \ - struct NAME##_iterator \ - : boost::fusion::iterator_facade< \ - NAME##_iterator, \ - boost::fusion::random_access_traversal_tag \ - > \ - { \ - typedef boost::mpl::int_ index; \ - typedef boost_fusion_uglified_Seq sequence_type; \ - \ - NAME##_iterator(boost_fusion_uglified_Seq& seq) : seq_(seq) {} \ - \ - boost_fusion_uglified_Seq& seq_; \ - \ - template struct value_of; \ - BOOST_PP_REPEAT( \ - ATTRIBUTES_SEQ_SIZE, \ - BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS, \ - NAME) \ - \ - template struct deref; \ - BOOST_PP_SEQ_FOR_EACH_I( \ - BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS, \ - NAME, \ - ATTRIBUTES_SEQ) \ - \ - template \ - struct next \ - { \ - typedef NAME##_iterator< \ - typename boost_fusion_uglified_It::sequence_type, \ - boost_fusion_uglified_It::index::value + 1 \ - > type; \ - \ - static type call(boost_fusion_uglified_It const& it) \ - { \ - return type(it.seq_); \ - } \ - }; \ - \ - template \ - struct prior \ - { \ - typedef NAME##_iterator< \ - typename boost_fusion_uglified_It::sequence_type, \ - boost_fusion_uglified_It::index::value - 1 \ - > type; \ - \ - static type call(boost_fusion_uglified_It const& it) \ - { \ - return type(it.seq_); \ - } \ - }; \ - \ - template < \ - typename boost_fusion_uglified_It1, \ - typename boost_fusion_uglified_It2 \ - > \ - struct distance \ - { \ - typedef typename boost::mpl::minus< \ - typename boost_fusion_uglified_It2::index, \ - typename boost_fusion_uglified_It1::index \ - >::type type; \ - \ - static type call(boost_fusion_uglified_It1 const& it1, \ - boost_fusion_uglified_It2 const& it2) \ - { \ - return type(); \ - } \ - }; \ - \ - template < \ - typename boost_fusion_uglified_It, \ - typename boost_fusion_uglified_M \ - > \ - struct advance \ - { \ - typedef NAME##_iterator< \ - typename boost_fusion_uglified_It::sequence_type, \ - boost_fusion_uglified_It::index::value \ - + boost_fusion_uglified_M::value \ - > type; \ - \ - static type call(boost_fusion_uglified_It const& it) \ - { \ - return type(it.seq_); \ - } \ - }; \ - }; \ - \ - template \ + template \ struct begin \ { \ - typedef NAME##_iterator type; \ + typedef BOOST_FUSION_ITERATOR_NAME(NAME) \ + type; \ \ - static type call(boost_fusion_uglified_Sq& sq) \ + static type call(boost_fusion_detail_Sq& sq) \ { \ return type(sq); \ } \ }; \ \ - template \ + template \ struct end \ { \ - typedef NAME##_iterator< \ - boost_fusion_uglified_Sq, \ + typedef BOOST_FUSION_ITERATOR_NAME(NAME)< \ + boost_fusion_detail_Sq, \ ATTRIBUTES_SEQ_SIZE \ > type; \ \ - static type call(boost_fusion_uglified_Sq& sq) \ + static type call(boost_fusion_detail_Sq& sq) \ { \ return type(sq); \ } \ }; \ \ - template \ + template \ struct size : boost::mpl::int_ \ { \ }; \ \ - template \ + template \ struct empty : boost::mpl::bool_ \ { \ }; \ \ template < \ - typename boost_fusion_uglified_Sq, \ - typename boost_fusion_uglified_N \ + typename boost_fusion_detail_Sq, \ + typename boost_fusion_detail_N \ > \ struct value_at : value_at< \ - boost_fusion_uglified_Sq, \ - boost::mpl::int_ \ + boost_fusion_detail_Sq, \ + boost::mpl::int_ \ > \ { \ }; \ @@ -353,12 +381,12 @@ ~) \ \ template < \ - typename boost_fusion_uglified_Sq, \ - typename boost_fusion_uglified_N \ + typename boost_fusion_detail_Sq, \ + typename boost_fusion_detail_N \ > \ struct at : at< \ - boost_fusion_uglified_Sq, \ - boost::mpl::int_ \ + boost_fusion_detail_Sq, \ + boost::mpl::int_ \ > \ { \ }; \