Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2009 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2005-2006 Dan Marsden
|
Chris@16
|
4 Copyright (c) 2009-2011 Christopher Schmidt
|
Chris@101
|
5 Copyright (c) 2013-2014 Damien Buhl
|
Chris@16
|
6
|
Chris@16
|
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 ==============================================================================*/
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP
|
Chris@16
|
12 #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #include <boost/fusion/support/config.hpp>
|
Chris@16
|
15 #include <boost/config.hpp>
|
Chris@16
|
16 #include <boost/fusion/support/tag_of_fwd.hpp>
|
Chris@101
|
17 #include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
|
Chris@101
|
18 #include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/preprocessor/empty.hpp>
|
Chris@16
|
21 #include <boost/preprocessor/stringize.hpp>
|
Chris@16
|
22 #include <boost/preprocessor/control/if.hpp>
|
Chris@16
|
23 #include <boost/preprocessor/seq/size.hpp>
|
Chris@16
|
24 #include <boost/preprocessor/seq/for_each.hpp>
|
Chris@16
|
25 #include <boost/preprocessor/seq/for_each_i.hpp>
|
Chris@16
|
26 #include <boost/preprocessor/seq/enum.hpp>
|
Chris@16
|
27 #include <boost/preprocessor/seq/seq.hpp>
|
Chris@16
|
28 #include <boost/preprocessor/tuple/eat.hpp>
|
Chris@16
|
29 #include <boost/preprocessor/tuple/elem.hpp>
|
Chris@16
|
30 #include <boost/preprocessor/arithmetic/dec.hpp>
|
Chris@101
|
31 #include <boost/preprocessor/comparison/less.hpp>
|
Chris@16
|
32 #include <boost/mpl/bool.hpp>
|
Chris@16
|
33 #include <boost/mpl/tag.hpp>
|
Chris@16
|
34 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
35 #include <boost/mpl/identity.hpp>
|
Chris@16
|
36 #include <boost/type_traits/add_const.hpp>
|
Chris@16
|
37
|
Chris@101
|
38 #include <boost/typeof/typeof.hpp>
|
Chris@101
|
39
|
Chris@101
|
40
|
Chris@16
|
41 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \
|
Chris@16
|
42 BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \
|
Chris@16
|
43 BOOST_PP_EMPTY()
|
Chris@16
|
44
|
Chris@16
|
45 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(SEQ) \
|
Chris@16
|
46 BOOST_PP_IF( \
|
Chris@16
|
47 BOOST_PP_SEQ_HEAD(SEQ), \
|
Chris@16
|
48 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS, \
|
Chris@16
|
49 BOOST_PP_SEQ_HEAD)(BOOST_PP_SEQ_TAIL(SEQ))
|
Chris@16
|
50
|
Chris@16
|
51 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C(R, _, ELEM) \
|
Chris@16
|
52 (typename ELEM)
|
Chris@16
|
53 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(SEQ) \
|
Chris@16
|
54 BOOST_PP_SEQ_ENUM( \
|
Chris@16
|
55 BOOST_PP_SEQ_FOR_EACH( \
|
Chris@16
|
56 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C, \
|
Chris@16
|
57 _, \
|
Chris@16
|
58 BOOST_PP_SEQ_TAIL(SEQ)))
|
Chris@16
|
59 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(SEQ) \
|
Chris@16
|
60 BOOST_PP_IF( \
|
Chris@16
|
61 BOOST_PP_SEQ_HEAD(SEQ), \
|
Chris@16
|
62 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
|
Chris@16
|
63 BOOST_PP_TUPLE_EAT(1))(SEQ)
|
Chris@16
|
64
|
Chris@101
|
65 #ifdef BOOST_MSVC
|
Chris@101
|
66 # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
|
Chris@101
|
67 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
|
Chris@101
|
68 \
|
Chris@101
|
69 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
|
Chris@101
|
70 TEMPLATE_PARAMS_SEQ) \
|
Chris@101
|
71 \
|
Chris@101
|
72 struct deduced_attr_type { \
|
Chris@101
|
73 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
|
Chris@101
|
74 typedef \
|
Chris@101
|
75 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
|
Chris@101
|
76 BOOST_TYPEOF( PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
|
Chris@101
|
77 0, ATTRIBUTE)) \
|
Chris@101
|
78 type; \
|
Chris@101
|
79 }; \
|
Chris@101
|
80 \
|
Chris@101
|
81 typedef \
|
Chris@101
|
82 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
|
Chris@101
|
83 deduced_attr_type::type attribute_type;
|
Chris@101
|
84
|
Chris@101
|
85 #else
|
Chris@101
|
86 # define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
|
Chris@101
|
87 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
|
Chris@101
|
88 \
|
Chris@101
|
89 struct deduced_attr_type { \
|
Chris@101
|
90 static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
|
Chris@101
|
91 typedef BOOST_TYPEOF( \
|
Chris@101
|
92 PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)) \
|
Chris@101
|
93 type; \
|
Chris@101
|
94 }; \
|
Chris@101
|
95 \
|
Chris@101
|
96 typedef \
|
Chris@101
|
97 BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
|
Chris@101
|
98 deduced_attr_type::type attribute_type;
|
Chris@101
|
99
|
Chris@101
|
100 #endif
|
Chris@101
|
101
|
Chris@101
|
102 #define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \
|
Chris@101
|
103 NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
|
Chris@101
|
104 typedef \
|
Chris@101
|
105 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) attribute_type;
|
Chris@101
|
106
|
Chris@101
|
107
|
Chris@16
|
108 #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
|
Chris@16
|
109 # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
|
Chris@16
|
110 MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
|
Chris@16
|
111 \
|
Chris@16
|
112 template< \
|
Chris@16
|
113 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
114 > \
|
Chris@16
|
115 struct tag_of< \
|
Chris@16
|
116 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER \
|
Chris@16
|
117 , void \
|
Chris@16
|
118 > \
|
Chris@16
|
119 { \
|
Chris@16
|
120 typedef TAG type; \
|
Chris@16
|
121 };
|
Chris@16
|
122 #else
|
Chris@16
|
123 # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
|
Chris@16
|
124 MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
|
Chris@16
|
125 \
|
Chris@16
|
126 template< \
|
Chris@16
|
127 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
128 > \
|
Chris@16
|
129 struct tag_of<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER> \
|
Chris@16
|
130 { \
|
Chris@16
|
131 typedef TAG type; \
|
Chris@16
|
132 };
|
Chris@16
|
133 #endif
|
Chris@16
|
134
|
Chris@16
|
135 #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \
|
Chris@101
|
136 BOOST_PP_TUPLE_ELEM(4,0,DATA)( \
|
Chris@101
|
137 BOOST_PP_TUPLE_ELEM(4,1,DATA), \
|
Chris@101
|
138 BOOST_PP_TUPLE_ELEM(4,2,DATA), \
|
Chris@101
|
139 BOOST_PP_TUPLE_ELEM(4,3,DATA), \
|
Chris@16
|
140 I, \
|
Chris@16
|
141 ATTRIBUTE)
|
Chris@16
|
142
|
Chris@16
|
143 #ifdef BOOST_MSVC
|
Chris@16
|
144 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM(R,_,ELEM) \
|
Chris@16
|
145 typedef ELEM ELEM;
|
Chris@16
|
146 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL(SEQ) \
|
Chris@16
|
147 BOOST_PP_SEQ_FOR_EACH( \
|
Chris@16
|
148 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAM, \
|
Chris@16
|
149 _, \
|
Chris@16
|
150 BOOST_PP_SEQ_TAIL(SEQ))
|
Chris@16
|
151 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ) \
|
Chris@16
|
152 BOOST_PP_IF( \
|
Chris@16
|
153 BOOST_PP_SEQ_HEAD(SEQ), \
|
Chris@16
|
154 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS_IMPL, \
|
Chris@16
|
155 BOOST_PP_TUPLE_EAT(1))(SEQ)
|
Chris@16
|
156 #else
|
Chris@16
|
157 # define BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS(SEQ)
|
Chris@16
|
158 #endif
|
Chris@16
|
159
|
Chris@16
|
160 #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
|
Chris@101
|
161 TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, \
|
Chris@101
|
162 I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE, \
|
Chris@101
|
163 DEDUCE_TYPE) \
|
Chris@16
|
164 \
|
Chris@16
|
165 template< \
|
Chris@16
|
166 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
167 > \
|
Chris@16
|
168 struct access::struct_member< \
|
Chris@16
|
169 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
|
Chris@16
|
170 , I \
|
Chris@16
|
171 > \
|
Chris@16
|
172 { \
|
Chris@101
|
173 BOOST_PP_IF(DEDUCE_TYPE, \
|
Chris@101
|
174 BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE)( \
|
Chris@101
|
175 NAME_SEQ, \
|
Chris@101
|
176 ATTRIBUTE, \
|
Chris@101
|
177 ATTRIBUTE_TUPEL_SIZE, \
|
Chris@101
|
178 PREFIX, \
|
Chris@101
|
179 TEMPLATE_PARAMS_SEQ) \
|
Chris@101
|
180 \
|
Chris@16
|
181 BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
|
Chris@16
|
182 TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
183 \
|
Chris@16
|
184 typedef attribute_type type; \
|
Chris@16
|
185 \
|
Chris@16
|
186 template<typename Seq> \
|
Chris@16
|
187 struct apply \
|
Chris@16
|
188 { \
|
Chris@16
|
189 typedef typename \
|
Chris@16
|
190 add_reference< \
|
Chris@16
|
191 typename mpl::eval_if< \
|
Chris@16
|
192 is_const<Seq> \
|
Chris@16
|
193 , add_const<attribute_type> \
|
Chris@16
|
194 , mpl::identity<attribute_type> \
|
Chris@16
|
195 >::type \
|
Chris@16
|
196 >::type \
|
Chris@16
|
197 type; \
|
Chris@16
|
198 \
|
Chris@101
|
199 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
|
Chris@16
|
200 static type \
|
Chris@16
|
201 call(Seq& seq) \
|
Chris@16
|
202 { \
|
Chris@16
|
203 return seq.PREFIX() \
|
Chris@101
|
204 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
|
Chris@101
|
205 BOOST_PP_IF(DEDUCE_TYPE, 0, 1), ATTRIBUTE); \
|
Chris@16
|
206 } \
|
Chris@16
|
207 }; \
|
Chris@16
|
208 }; \
|
Chris@16
|
209 \
|
Chris@16
|
210 template< \
|
Chris@16
|
211 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
212 > \
|
Chris@16
|
213 struct struct_member_name< \
|
Chris@16
|
214 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
|
Chris@16
|
215 , I \
|
Chris@16
|
216 > \
|
Chris@16
|
217 { \
|
Chris@16
|
218 typedef char const* type; \
|
Chris@16
|
219 \
|
Chris@101
|
220 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED \
|
Chris@16
|
221 static type \
|
Chris@16
|
222 call() \
|
Chris@16
|
223 { \
|
Chris@16
|
224 return BOOST_PP_STRINGIZE( \
|
Chris@101
|
225 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
|
Chris@101
|
226 BOOST_PP_IF(DEDUCE_TYPE, 0, 1), \
|
Chris@101
|
227 ATTRIBUTE)); \
|
Chris@16
|
228 } \
|
Chris@16
|
229 };
|
Chris@16
|
230
|
Chris@16
|
231 #define BOOST_FUSION_ADAPT_STRUCT_BASE( \
|
Chris@16
|
232 TEMPLATE_PARAMS_SEQ, \
|
Chris@16
|
233 NAME_SEQ, \
|
Chris@16
|
234 TAG, \
|
Chris@16
|
235 IS_VIEW, \
|
Chris@16
|
236 ATTRIBUTES_SEQ, \
|
Chris@16
|
237 ATTRIBUTES_CALLBACK) \
|
Chris@16
|
238 \
|
Chris@16
|
239 namespace boost \
|
Chris@16
|
240 { \
|
Chris@16
|
241 namespace fusion \
|
Chris@16
|
242 { \
|
Chris@16
|
243 namespace traits \
|
Chris@16
|
244 { \
|
Chris@16
|
245 BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
|
Chris@16
|
246 BOOST_PP_EMPTY(), TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
|
Chris@16
|
247 BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
|
Chris@16
|
248 const, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
|
Chris@16
|
249 } \
|
Chris@16
|
250 \
|
Chris@16
|
251 namespace extension \
|
Chris@16
|
252 { \
|
Chris@16
|
253 BOOST_PP_IF( \
|
Chris@16
|
254 BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)), \
|
Chris@16
|
255 BOOST_PP_SEQ_FOR_EACH_I_R, \
|
Chris@16
|
256 BOOST_PP_TUPLE_EAT(4))( \
|
Chris@16
|
257 1, \
|
Chris@16
|
258 BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \
|
Chris@101
|
259 (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ, IS_VIEW),\
|
Chris@16
|
260 BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \
|
Chris@16
|
261 \
|
Chris@16
|
262 template< \
|
Chris@16
|
263 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
|
Chris@16
|
264 TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
265 > \
|
Chris@16
|
266 struct struct_size<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
|
Chris@16
|
267 : mpl::int_<BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ))> \
|
Chris@16
|
268 {}; \
|
Chris@16
|
269 \
|
Chris@16
|
270 template< \
|
Chris@16
|
271 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
|
Chris@16
|
272 TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
273 > \
|
Chris@16
|
274 struct struct_is_view< \
|
Chris@16
|
275 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
|
Chris@16
|
276 > \
|
Chris@16
|
277 : mpl::BOOST_PP_IF(IS_VIEW,true_,false_) \
|
Chris@16
|
278 {}; \
|
Chris@16
|
279 } \
|
Chris@16
|
280 } \
|
Chris@16
|
281 \
|
Chris@16
|
282 namespace mpl \
|
Chris@16
|
283 { \
|
Chris@16
|
284 template<typename> \
|
Chris@16
|
285 struct sequence_tag; \
|
Chris@16
|
286 \
|
Chris@16
|
287 template< \
|
Chris@16
|
288 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
|
Chris@16
|
289 TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
290 > \
|
Chris@16
|
291 struct sequence_tag<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
|
Chris@16
|
292 { \
|
Chris@16
|
293 typedef fusion::fusion_sequence_tag type; \
|
Chris@16
|
294 }; \
|
Chris@16
|
295 \
|
Chris@16
|
296 template< \
|
Chris@16
|
297 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS( \
|
Chris@16
|
298 TEMPLATE_PARAMS_SEQ) \
|
Chris@16
|
299 > \
|
Chris@16
|
300 struct sequence_tag< \
|
Chris@16
|
301 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const \
|
Chris@16
|
302 > \
|
Chris@16
|
303 { \
|
Chris@16
|
304 typedef fusion::fusion_sequence_tag type; \
|
Chris@16
|
305 }; \
|
Chris@16
|
306 } \
|
Chris@16
|
307 }
|
Chris@16
|
308
|
Chris@16
|
309 #endif
|