File indexing completed on 2025-01-18 09:31:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP
0012 #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP
0013
0014 #include <boost/fusion/support/config.hpp>
0015 #include <boost/config.hpp>
0016 #include <boost/fusion/support/tag_of_fwd.hpp>
0017 #include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
0018 #include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
0019
0020 #include <boost/preprocessor/empty.hpp>
0021 #include <boost/preprocessor/stringize.hpp>
0022 #include <boost/preprocessor/control/if.hpp>
0023 #include <boost/preprocessor/seq/size.hpp>
0024 #include <boost/preprocessor/seq/for_each.hpp>
0025 #include <boost/preprocessor/seq/for_each_i.hpp>
0026 #include <boost/preprocessor/seq/enum.hpp>
0027 #include <boost/preprocessor/seq/seq.hpp>
0028 #include <boost/preprocessor/tuple/eat.hpp>
0029 #include <boost/preprocessor/tuple/elem.hpp>
0030 #include <boost/preprocessor/arithmetic/dec.hpp>
0031 #include <boost/preprocessor/comparison/less.hpp>
0032 #include <boost/preprocessor/logical/not.hpp>
0033 #include <boost/mpl/bool.hpp>
0034 #include <boost/mpl/tag.hpp>
0035 #include <boost/mpl/eval_if.hpp>
0036 #include <boost/mpl/identity.hpp>
0037 #include <boost/type_traits/is_const.hpp>
0038 #include <boost/type_traits/add_const.hpp>
0039 #include <boost/type_traits/add_reference.hpp>
0040
0041 #include <boost/typeof/typeof.hpp>
0042
0043
0044 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \
0045 BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \
0046 BOOST_PP_EMPTY()
0047
0048 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(SEQ) \
0049 BOOST_PP_IF( \
0050 BOOST_PP_SEQ_HEAD(SEQ), \
0051 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS, \
0052 BOOST_PP_SEQ_HEAD)(BOOST_PP_SEQ_TAIL(SEQ))
0053
0054 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C(R, _, ELEM) \
0055 (typename ELEM)
0056 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(SEQ) \
0057 BOOST_PP_SEQ_ENUM( \
0058 BOOST_PP_SEQ_FOR_EACH( \
0059 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C, \
0060 _, \
0061 BOOST_PP_SEQ_TAIL(SEQ)))
0062 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(SEQ) \
0063 BOOST_PP_IF( \
0064 BOOST_PP_SEQ_HEAD(SEQ), \
0065 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
0066 BOOST_PP_TUPLE_EAT(1))(SEQ)
0067
0068 #ifdef BOOST_MSVC
0069 # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
0070 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
0071 \
0072 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
0073 TEMPLATE_PARAMS_SEQ) \
0074 \
0075 struct deduced_attr_type { \
0076 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
0077 typedef \
0078 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
0079 BOOST_TYPEOF( PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
0080 0, ATTRIBUTE)) \
0081 type; \
0082 }; \
0083 \
0084 typedef \
0085 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
0086 deduced_attr_type::type attribute_type;
0087
0088 #else
0089 # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
0090 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
0091 \
0092 struct deduced_attr_type { \
0093 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
0094 typedef BOOST_TYPEOF( \
0095 PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 0, ATTRIBUTE)) \
0096 type; \
0097 }; \
0098 \
0099 typedef \
0100 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
0101 deduced_attr_type::type attribute_type;
0102
0103 #endif
0104
0105 #define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \
0106 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPLE_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
0107 typedef \
0108 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, 0, ATTRIBUTE) attribute_type;
0109
0110
0111 #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
0112 # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
0113 MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
0114 \
0115 template< \
0116 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
0117 > \
0118 struct tag_of< \
0119 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER \
0120 , void \
0121 > \
0122 { \
0123 typedef TAG type; \
0124 };
0125 #else
0126 # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
0127 MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
0128 \
0129 template< \
0130 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
0131 > \
0132 struct tag_of<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER> \
0133 { \
0134 typedef TAG type; \
0135 };
0136 #endif
0137
0138 #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \
0139 BOOST_PP_TUPLE_ELEM(4,0,DATA)( \
0140 BOOST_PP_TUPLE_ELEM(4,1,DATA), \
0141 BOOST_PP_TUPLE_ELEM(4,2,DATA), \
0142 BOOST_PP_TUPLE_ELEM(4,3,DATA), \
0143 I, \
0144 ATTRIBUTE)
0145
0146 #if defined(BOOST_MSVC) && (BOOST_MSVC < 1935)
0147 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM(R,_,ELEM) \
0148 typedef ELEM ELEM;
0149 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL(SEQ) \
0150 BOOST_PP_SEQ_FOR_EACH( \
0151 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM, \
0152 _, \
0153 BOOST_PP_SEQ_TAIL(SEQ))
0154 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) \
0155 BOOST_PP_IF( \
0156 BOOST_PP_SEQ_HEAD(SEQ), \
0157 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL, \
0158 BOOST_PP_TUPLE_EAT(1))(SEQ)
0159 #else
0160 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ)
0161 #endif
0162
0163 #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
0164 TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, \
0165 I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPLE_SIZE, \
0166 DEDUCE_TYPE) \
0167 \
0168 template< \
0169 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
0170 > \
0171 struct access::struct_member< \
0172 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
0173 , I \
0174 > \
0175 { \
0176 BOOST_PP_IF(DEDUCE_TYPE, \
0177 BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE)( \
0178 NAME_SEQ, \
0179 ATTRIBUTE, \
0180 ATTRIBUTE_TUPLE_SIZE, \
0181 PREFIX, \
0182 TEMPLATE_PARAMS_SEQ) \
0183 \
0184 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
0185 TEMPLATE_PARAMS_SEQ) \
0186 \
0187 typedef attribute_type type; \
0188 \
0189 template<typename Seq> \
0190 struct apply \
0191 { \
0192 typedef typename \
0193 add_reference< \
0194 typename mpl::eval_if< \
0195 is_const<Seq> \
0196 , add_const<attribute_type> \
0197 , mpl::identity<attribute_type> \
0198 >::type \
0199 >::type \
0200 type; \
0201 \
0202 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
0203 static type \
0204 call(Seq& seq) \
0205 { \
0206 return seq.PREFIX() \
0207 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
0208 BOOST_PP_NOT(DEDUCE_TYPE), ATTRIBUTE); \
0209 } \
0210 }; \
0211 }; \
0212 \
0213 template< \
0214 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
0215 > \
0216 struct struct_member_name< \
0217 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
0218 , I \
0219 > \
0220 { \
0221 typedef char const* type; \
0222 \
0223 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
0224 static type \
0225 call() \
0226 { \
0227 return BOOST_PP_STRINGIZE( \
0228 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPLE_SIZE, \
0229 BOOST_PP_NOT(DEDUCE_TYPE), ATTRIBUTE)); \
0230 } \
0231 };
0232
0233 #define BOOST_FUSION_ADAPT_STRUCT_BASE( \
0234 TEMPLATE_PARAMS_SEQ, \
0235 NAME_SEQ, \
0236 TAG, \
0237 IS_VIEW, \
0238 ATTRIBUTES_SEQ, \
0239 ATTRIBUTES_CALLBACK) \
0240 \
0241 namespace boost \
0242 { \
0243 namespace fusion \
0244 { \
0245 namespace traits \
0246 { \
0247 BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
0248 BOOST_PP_EMPTY(), TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
0249 BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
0250 const, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
0251 } \
0252 \
0253 namespace extension \
0254 { \
0255 BOOST_PP_IF( \
0256 BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)), \
0257 BOOST_PP_SEQ_FOR_EACH_I_R, \
0258 BOOST_PP_TUPLE_EAT(4))( \
0259 1, \
0260 BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \
0261 (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ, IS_VIEW),\
0262 BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \
0263 \
0264 template< \
0265 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
0266 TEMPLATE_PARAMS_SEQ) \
0267 > \
0268 struct struct_size<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
0269 : mpl::int_<BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ))> \
0270 {}; \
0271 \
0272 template< \
0273 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
0274 TEMPLATE_PARAMS_SEQ) \
0275 > \
0276 struct struct_is_view< \
0277 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
0278 > \
0279 : mpl::BOOST_PP_IIF(IS_VIEW,true_,false_) \
0280 {}; \
0281 } \
0282 } \
0283 \
0284 namespace mpl \
0285 { \
0286 template<typename> \
0287 struct sequence_tag; \
0288 \
0289 template< \
0290 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
0291 TEMPLATE_PARAMS_SEQ) \
0292 > \
0293 struct sequence_tag<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
0294 { \
0295 typedef fusion::fusion_sequence_tag type; \
0296 }; \
0297 \
0298 template< \
0299 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
0300 TEMPLATE_PARAMS_SEQ) \
0301 > \
0302 struct sequence_tag< \
0303 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const \
0304 > \
0305 { \
0306 typedef fusion::fusion_sequence_tag type; \
0307 }; \
0308 } \
0309 }
0310
0311 #endif