Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2009 Joel de Guzman Chris@16: Copyright (c) 2005-2006 Dan Marsden Chris@16: Copyright (c) 2009-2011 Christopher Schmidt Chris@101: Copyright (c) 2013-2014 Damien Buhl Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: Chris@16: #ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP Chris@16: #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP Chris@16: Chris@101: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@101: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@101: #include Chris@101: Chris@101: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \ Chris@16: BOOST_PP_SEQ_HEAD(SEQ) \ Chris@16: BOOST_PP_EMPTY() Chris@16: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(SEQ) \ Chris@16: BOOST_PP_IF( \ Chris@16: BOOST_PP_SEQ_HEAD(SEQ), \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS, \ Chris@16: BOOST_PP_SEQ_HEAD)(BOOST_PP_SEQ_TAIL(SEQ)) Chris@16: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C(R, _, ELEM) \ Chris@16: (typename ELEM) Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(SEQ) \ Chris@16: BOOST_PP_SEQ_ENUM( \ Chris@16: BOOST_PP_SEQ_FOR_EACH( \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C, \ Chris@16: _, \ Chris@16: BOOST_PP_SEQ_TAIL(SEQ))) Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(SEQ) \ Chris@16: BOOST_PP_IF( \ Chris@16: BOOST_PP_SEQ_HEAD(SEQ), \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \ Chris@16: BOOST_PP_TUPLE_EAT(1))(SEQ) Chris@16: Chris@101: #ifdef BOOST_MSVC Chris@101: # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \ Chris@101: NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \ Chris@101: \ Chris@101: BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ Chris@101: TEMPLATE_PARAMS_SEQ) \ Chris@101: \ Chris@101: struct deduced_attr_type { \ Chris@101: static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \ Chris@101: typedef \ Chris@101: BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \ Chris@101: BOOST_TYPEOF( PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \ Chris@101: 0, ATTRIBUTE)) \ Chris@101: type; \ Chris@101: }; \ Chris@101: \ Chris@101: typedef \ Chris@101: BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \ Chris@101: deduced_attr_type::type attribute_type; Chris@101: Chris@101: #else Chris@101: # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \ Chris@101: NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \ Chris@101: \ Chris@101: struct deduced_attr_type { \ Chris@101: static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \ Chris@101: typedef BOOST_TYPEOF( \ Chris@101: PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)) \ Chris@101: type; \ Chris@101: }; \ Chris@101: \ Chris@101: typedef \ Chris@101: BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \ Chris@101: deduced_attr_type::type attribute_type; Chris@101: Chris@101: #endif Chris@101: Chris@101: #define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \ Chris@101: NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \ Chris@101: typedef \ Chris@101: BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) attribute_type; Chris@101: Chris@101: Chris@16: #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ Chris@16: MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct tag_of< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER \ Chris@16: , void \ Chris@16: > \ Chris@16: { \ Chris@16: typedef TAG type; \ Chris@16: }; Chris@16: #else Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ Chris@16: MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct tag_of \ Chris@16: { \ Chris@16: typedef TAG type; \ Chris@16: }; Chris@16: #endif Chris@16: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \ Chris@101: BOOST_PP_TUPLE_ELEM(4,0,DATA)( \ Chris@101: BOOST_PP_TUPLE_ELEM(4,1,DATA), \ Chris@101: BOOST_PP_TUPLE_ELEM(4,2,DATA), \ Chris@101: BOOST_PP_TUPLE_ELEM(4,3,DATA), \ Chris@16: I, \ Chris@16: ATTRIBUTE) Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM(R,_,ELEM) \ Chris@16: typedef ELEM ELEM; Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL(SEQ) \ Chris@16: BOOST_PP_SEQ_FOR_EACH( \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM, \ Chris@16: _, \ Chris@16: BOOST_PP_SEQ_TAIL(SEQ)) Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) \ Chris@16: BOOST_PP_IF( \ Chris@16: BOOST_PP_SEQ_HEAD(SEQ), \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL, \ Chris@16: BOOST_PP_TUPLE_EAT(1))(SEQ) Chris@16: #else Chris@16: # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) Chris@16: #endif Chris@16: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ Chris@101: TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, \ Chris@101: I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE, \ Chris@101: DEDUCE_TYPE) \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct access::struct_member< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ Chris@16: , I \ Chris@16: > \ Chris@16: { \ Chris@101: BOOST_PP_IF(DEDUCE_TYPE, \ Chris@101: BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE)( \ Chris@101: NAME_SEQ, \ Chris@101: ATTRIBUTE, \ Chris@101: ATTRIBUTE_TUPEL_SIZE, \ Chris@101: PREFIX, \ Chris@101: TEMPLATE_PARAMS_SEQ) \ Chris@101: \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ Chris@16: TEMPLATE_PARAMS_SEQ) \ Chris@16: \ Chris@16: typedef attribute_type type; \ Chris@16: \ Chris@16: template \ Chris@16: struct apply \ Chris@16: { \ Chris@16: typedef typename \ Chris@16: add_reference< \ Chris@16: typename mpl::eval_if< \ Chris@16: is_const \ Chris@16: , add_const \ Chris@16: , mpl::identity \ Chris@16: >::type \ Chris@16: >::type \ Chris@16: type; \ Chris@16: \ Chris@101: BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ Chris@16: static type \ Chris@16: call(Seq& seq) \ Chris@16: { \ Chris@16: return seq.PREFIX() \ Chris@101: BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \ Chris@101: BOOST_PP_IF(DEDUCE_TYPE, 0, 1), ATTRIBUTE); \ Chris@16: } \ Chris@16: }; \ Chris@16: }; \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct struct_member_name< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ Chris@16: , I \ Chris@16: > \ Chris@16: { \ Chris@16: typedef char const* type; \ Chris@16: \ Chris@101: BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \ Chris@16: static type \ Chris@16: call() \ Chris@16: { \ Chris@16: return BOOST_PP_STRINGIZE( \ Chris@101: BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \ Chris@101: BOOST_PP_IF(DEDUCE_TYPE, 0, 1), \ Chris@101: ATTRIBUTE)); \ Chris@16: } \ Chris@16: }; Chris@16: Chris@16: #define BOOST_FUSION_ADAPT_STRUCT_BASE( \ Chris@16: TEMPLATE_PARAMS_SEQ, \ Chris@16: NAME_SEQ, \ Chris@16: TAG, \ Chris@16: IS_VIEW, \ Chris@16: ATTRIBUTES_SEQ, \ Chris@16: ATTRIBUTES_CALLBACK) \ Chris@16: \ Chris@16: namespace boost \ Chris@16: { \ Chris@16: namespace fusion \ Chris@16: { \ Chris@16: namespace traits \ Chris@16: { \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ Chris@16: BOOST_PP_EMPTY(), TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ Chris@16: const, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ Chris@16: } \ Chris@16: \ Chris@16: namespace extension \ Chris@16: { \ Chris@16: BOOST_PP_IF( \ Chris@16: BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)), \ Chris@16: BOOST_PP_SEQ_FOR_EACH_I_R, \ Chris@16: BOOST_PP_TUPLE_EAT(4))( \ Chris@16: 1, \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \ Chris@101: (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ, IS_VIEW),\ Chris@16: BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \ Chris@16: TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct struct_size \ Chris@16: : mpl::int_ \ Chris@16: {}; \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \ Chris@16: TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct struct_is_view< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \ Chris@16: > \ Chris@16: : mpl::BOOST_PP_IF(IS_VIEW,true_,false_) \ Chris@16: {}; \ Chris@16: } \ Chris@16: } \ Chris@16: \ Chris@16: namespace mpl \ Chris@16: { \ Chris@16: template \ Chris@16: struct sequence_tag; \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \ Chris@16: TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct sequence_tag \ Chris@16: { \ Chris@16: typedef fusion::fusion_sequence_tag type; \ Chris@16: }; \ Chris@16: \ Chris@16: template< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \ Chris@16: TEMPLATE_PARAMS_SEQ) \ Chris@16: > \ Chris@16: struct sequence_tag< \ Chris@16: BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const \ Chris@16: > \ Chris@16: { \ Chris@16: typedef fusion::fusion_sequence_tag type; \ Chris@16: }; \ Chris@16: } \ Chris@16: } Chris@16: Chris@16: #endif