diff --git a/include/boost/fusion/adapted/struct.hpp b/include/boost/fusion/adapted/struct.hpp index acc12e69..e51b514b 100644 --- a/include/boost/fusion/adapted/struct.hpp +++ b/include/boost/fusion/adapted/struct.hpp @@ -16,5 +16,6 @@ #include #include #include +#include #endif diff --git a/include/boost/fusion/adapted/struct/define_struct_inline.hpp b/include/boost/fusion/adapted/struct/define_struct_inline.hpp new file mode 100644 index 00000000..9dc5b44c --- /dev/null +++ b/include/boost/fusion/adapted/struct/define_struct_inline.hpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2012 Nathan Ridge + + 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_DEFINE_STRUCT_INLINE_HPP +#define BOOST_FUSION_ADAPTED_STRUCT_DEFINE_STRUCT_INLINE_HPP + +#include +#include + +#define BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE( \ + TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES) \ + \ + BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE_IMPL( \ + TEMPLATE_PARAMS_SEQ, \ + NAME, \ + ATTRIBUTES) + +#define BOOST_FUSION_DEFINE_STRUCT_INLINE(NAME, ATTRIBUTES) \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_IMPL(NAME, ATTRIBUTES) \ + +#endif diff --git a/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp new file mode 100644 index 00000000..84eccca6 --- /dev/null +++ b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp @@ -0,0 +1,358 @@ +/*============================================================================= + Copyright (c) 2012 Nathan Ridge + + 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_DEFINE_STRUCT_INLINE_HPP +#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_DEFINE_STRUCT_INLINE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE) \ + BOOST_PP_COMMA_IF(N) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)() + +#define BOOST_FUSION_MAKE_CONST_REF_PARAM(R, DATA, N, ATTRIBUTE) \ + BOOST_PP_COMMA_IF(N) \ + BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) const& \ + BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE) + +#define BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(NAME) NAME(NAME) + +#define BOOST_FUSION_MAKE_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE) \ + BOOST_PP_COMMA_IF(N) \ + BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)) + +// 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 > \ + : boost::mpl::identity< \ + typename boost_fusion_uglified_Sq::t##N##_type \ + > \ + { \ + }; + +#define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC( \ + SPEC_TYPE, CALL_ARG_TYPE, TYPE_QUAL, ATTRIBUTE, N) \ + \ + template \ + struct deref > \ + { \ + typedef typename boost_fusion_uglified_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); \ + } \ + }; + +#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 > \ + { \ + typedef typename boost_fusion_uglified_Sq::t##N##_type type; \ + }; + +#define BOOST_FUSION_MAKE_AT_SPECS(R, DATA, N, ATTRIBUTE) \ + 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& \ + >::type type; \ + \ + static type call(boost_fusion_uglified_Sq& sq) \ + { \ + return sq. BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); \ + } \ + }; + +#define BOOST_FUSION_MAKE_TYPEDEF(R, DATA, N, ATTRIBUTE) \ + typedef BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) t##N##_type; + +#define BOOST_FUSION_MAKE_DATA_MEMBER(R, DATA, N, ATTRIBUTE) \ + BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE); + +#define BOOST_FUSION_DEFINE_STRUCT_INLINE_IMPL(NAME, ATTRIBUTES) \ + struct NAME : boost::fusion::sequence_facade< \ + NAME, \ + boost::fusion::random_access_traversal_tag \ + > \ + { \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ + }; + +#define BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE_IMPL( \ + TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES) \ + \ + template < \ + BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL( \ + (0)TEMPLATE_PARAMS_SEQ) \ + > \ + struct NAME : boost::fusion::sequence_facade< \ + NAME< \ + BOOST_PP_SEQ_ENUM(TEMPLATE_PARAMS_SEQ) \ + >, \ + boost::fusion::random_access_traversal_tag \ + > \ + { \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ + }; + +#define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ + BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL( \ + NAME, \ + BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END)) + +#define BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL(NAME, ATTRIBUTES_SEQ) \ + BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL( \ + NAME, \ + ATTRIBUTES_SEQ, \ + BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)) + +#define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL( \ + NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ + \ + NAME() \ + : BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY, \ + ~, \ + ATTRIBUTES_SEQ) \ + { \ + } \ + \ + NAME(BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_CONST_REF_PARAM, \ + ~, \ + ATTRIBUTES_SEQ)) \ + : BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_INIT_LIST_ENTRY, \ + ~, \ + ATTRIBUTES_SEQ) \ + { \ + } \ + \ + template \ + NAME(const boost_fusion_uglified_Seq& rhs) \ + { \ + boost::fusion::copy(rhs, *this); \ + } \ + \ + template \ + NAME& operator=(const boost_fusion_uglified_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 \ + struct begin \ + { \ + typedef NAME##_iterator type; \ + \ + static type call(boost_fusion_uglified_Sq& sq) \ + { \ + return type(sq); \ + } \ + }; \ + \ + template \ + struct end \ + { \ + typedef NAME##_iterator< \ + boost_fusion_uglified_Sq, \ + ATTRIBUTES_SEQ_SIZE \ + > type; \ + \ + static type call(boost_fusion_uglified_Sq& sq) \ + { \ + return type(sq); \ + } \ + }; \ + \ + template \ + struct size : boost::mpl::int_ \ + { \ + }; \ + \ + template \ + struct empty : boost::mpl::bool_ \ + { \ + }; \ + \ + template < \ + typename boost_fusion_uglified_Sq, \ + typename boost_fusion_uglified_N \ + > \ + struct value_at : value_at< \ + boost_fusion_uglified_Sq, \ + boost::mpl::int_ \ + > \ + { \ + }; \ + \ + BOOST_PP_REPEAT( \ + ATTRIBUTES_SEQ_SIZE, \ + BOOST_FUSION_MAKE_VALUE_AT_SPECS, \ + ~) \ + \ + template < \ + typename boost_fusion_uglified_Sq, \ + typename boost_fusion_uglified_N \ + > \ + struct at : at< \ + boost_fusion_uglified_Sq, \ + boost::mpl::int_ \ + > \ + { \ + }; \ + \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_AT_SPECS, ~, ATTRIBUTES_SEQ) \ + \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_TYPEDEF, ~, ATTRIBUTES_SEQ) \ + \ + BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_DATA_MEMBER, \ + ~, \ + ATTRIBUTES_SEQ) + +#endif diff --git a/include/boost/fusion/include/define_struct_inline.hpp b/include/boost/fusion/include/define_struct_inline.hpp new file mode 100644 index 00000000..141ad4e2 --- /dev/null +++ b/include/boost/fusion/include/define_struct_inline.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2012 Nathan Ridge + + 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_INCLUDE_DEFINE_STRUCT_INLINE_HPP +#define BOOST_FUSION_INCLUDE_DEFINE_STRUCT_INLINE_HPP + +#include + +#endif