Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / fusion / adapted / struct / detail / define_struct_inline.hpp
1 /*=============================================================================
2     Copyright (c) 2012 Nathan Ridge
3
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7
8 #ifndef BOOST_FUSION_ADAPTED_STRUCT_DETAIL_DEFINE_STRUCT_INLINE_HPP
9 #define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_DEFINE_STRUCT_INLINE_HPP
10
11 #include <boost/fusion/support/config.hpp>
12 #include <boost/config.hpp>
13 #include <boost/fusion/support/category_of.hpp>
14 #include <boost/fusion/sequence/sequence_facade.hpp>
15 #include <boost/fusion/iterator/iterator_facade.hpp>
16 #include <boost/fusion/algorithm/auxiliary/copy.hpp>
17 #include <boost/fusion/adapted/struct/detail/define_struct.hpp>
18 #include <boost/mpl/int.hpp>
19 #include <boost/mpl/bool.hpp>
20 #include <boost/mpl/identity.hpp>
21 #include <boost/mpl/minus.hpp>
22 #include <boost/mpl/if.hpp>
23 #include <boost/type_traits/is_const.hpp>
24 #include <boost/preprocessor/comma_if.hpp>
25 #include <boost/preprocessor/facilities/is_empty.hpp>
26 #include <boost/preprocessor/repeat.hpp>
27 #include <boost/preprocessor/seq/for_each_i.hpp>
28 #include <boost/preprocessor/seq/size.hpp>
29 #include <boost/preprocessor/seq/enum.hpp>
30 #include <boost/preprocessor/seq/seq.hpp>
31 #include <boost/preprocessor/tuple/elem.hpp>
32
33 // MSVC and GCC <= 4.4 have a bug that affects partial specializations of
34 // nested templates under some circumstances. This affects the implementation
35 // of BOOST_FUSION_DEFINE_STRUCT_INLINE, which uses such specializations for
36 // the iterator class's 'deref' and 'value_of' metafunctions. On these compilers
37 // an alternate implementation for these metafunctions is used that does not 
38 // require such specializations. The alternate implementation takes longer
39 // to compile so its use is restricted to the offending compilers.
40 // For MSVC, the bug was reported at https://connect.microsoft.com/VisualStudio/feedback/details/757891/c-compiler-error-involving-partial-specializations-of-nested-templates
41 // For GCC, 4.4 and earlier are no longer maintained so there is no need
42 // to report a bug.
43 #if defined(BOOST_MSVC) || (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 4)))
44     #define BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND 
45 #endif
46
47 #ifdef BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND
48 #include <boost/type_traits/add_const.hpp>
49 #include <boost/type_traits/remove_const.hpp>
50 #include <boost/mpl/if.hpp>
51 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
52 #include <boost/fusion/container/vector.hpp>
53 #endif
54
55
56 #define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE)        \
57     BOOST_PP_COMMA_IF(N) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)()
58
59 #define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST(ATTRIBUTES_SEQ)                     \
60             : BOOST_PP_SEQ_FOR_EACH_I(                                          \
61               BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY,                        \
62               ~,                                                                \
63               ATTRIBUTES_SEQ)                                                   \
64
65 #define BOOST_FUSION_IGNORE_1(ARG1)
66 #define BOOST_FUSION_IGNORE_2(ARG1, ARG2)
67
68 #define BOOST_FUSION_MAKE_COPY_CONSTRUCTOR(NAME, ATTRIBUTES_SEQ)                \
69     NAME(BOOST_PP_SEQ_FOR_EACH_I(                                               \
70             BOOST_FUSION_MAKE_CONST_REF_PARAM,                                  \
71             ~,                                                                  \
72             ATTRIBUTES_SEQ))                                                    \
73         : BOOST_PP_SEQ_FOR_EACH_I(                                              \
74               BOOST_FUSION_MAKE_INIT_LIST_ENTRY,                                \
75               ~,                                                                \
76               ATTRIBUTES_SEQ)                                                   \
77     {                                                                           \
78     }                                                                           \
79
80 #define BOOST_FUSION_MAKE_CONST_REF_PARAM(R, DATA, N, ATTRIBUTE)                \
81     BOOST_PP_COMMA_IF(N)                                                        \
82     BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) const&                                 \
83     BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)
84
85 #define BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(NAME) NAME(NAME)
86
87 #define BOOST_FUSION_MAKE_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE)                \
88     BOOST_PP_COMMA_IF(N)                                                        \
89     BOOST_FUSION_MAKE_INIT_LIST_ENTRY_I(BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE))
90
91 #define BOOST_FUSION_ITERATOR_NAME(NAME)                                        \
92     BOOST_PP_CAT(boost_fusion_detail_, BOOST_PP_CAT(NAME, _iterator))
93
94 // Note: all template parameter names need to be uglified, otherwise they might
95 //       shadow a template parameter of the struct when used with
96 //       BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE
97
98 #define BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS(Z, N, NAME)                   \
99     template <typename boost_fusion_detail_Sq>                                  \
100     struct value_of<                                                            \
101                BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, N>      \
102            >                                                                    \
103         : boost::mpl::identity<                                                 \
104               typename boost_fusion_detail_Sq::t##N##_type                      \
105           >                                                                     \
106     {                                                                           \
107     };
108
109 #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC(                                  \
110     SPEC_TYPE, CALL_ARG_TYPE, TYPE_QUAL, ATTRIBUTE, N)                          \
111                                                                                 \
112     template <typename boost_fusion_detail_Sq>                                  \
113     struct deref<SPEC_TYPE, N> >                                                \
114     {                                                                           \
115         typedef typename boost_fusion_detail_Sq::t##N##_type TYPE_QUAL& type;   \
116         BOOST_FUSION_GPU_ENABLED                                                \
117         static type call(CALL_ARG_TYPE, N> const& iter)                         \
118         {                                                                       \
119             return iter.seq_.BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE);              \
120         }                                                                       \
121     };
122
123 #define BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS(R, NAME, N, ATTRIBUTE)           \
124     BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC(                                      \
125         BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq,                \
126         BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq,                \
127         ,                                                                       \
128         ATTRIBUTE,                                                              \
129         N)                                                                      \
130     BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC(                                      \
131         BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq,          \
132         BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq,          \
133         const,                                                                  \
134         ATTRIBUTE,                                                              \
135         N)                                                                      \
136     BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC(                                      \
137         const BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq,          \
138         BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq,                \
139         ,                                                                       \
140         ATTRIBUTE,                                                              \
141         N)                                                                      \
142     BOOST_FUSION_MAKE_ITERATOR_DEREF_SPEC(                                      \
143         const BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq,    \
144         BOOST_FUSION_ITERATOR_NAME(NAME)<const boost_fusion_detail_Sq,          \
145         const,                                                                  \
146         ATTRIBUTE,                                                              \
147         N)                                                                      \
148
149 #define BOOST_FUSION_MAKE_VALUE_AT_SPECS(Z, N, DATA)                            \
150     template <typename boost_fusion_detail_Sq>                                  \
151     struct value_at<boost_fusion_detail_Sq, boost::mpl::int_<N> >               \
152     {                                                                           \
153         typedef typename boost_fusion_detail_Sq::t##N##_type type;              \
154     };
155
156 #define BOOST_FUSION_MAKE_AT_SPECS(R, DATA, N, ATTRIBUTE)                       \
157     template <typename boost_fusion_detail_Sq>                                  \
158     struct at<boost_fusion_detail_Sq, boost::mpl::int_<N> >                     \
159     {                                                                           \
160         typedef typename boost::mpl::if_<                                       \
161             boost::is_const<boost_fusion_detail_Sq>,                            \
162             typename boost_fusion_detail_Sq::t##N##_type const&,                \
163             typename boost_fusion_detail_Sq::t##N##_type&                       \
164         >::type type;                                                           \
165                                                                                 \
166         BOOST_FUSION_GPU_ENABLED                                                \
167         static type call(boost_fusion_detail_Sq& sq)                            \
168         {                                                                       \
169             return sq. BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE);                    \
170         }                                                                       \
171     };
172
173 #define BOOST_FUSION_MAKE_TYPEDEF(R, DATA, N, ATTRIBUTE)                        \
174     typedef BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) t##N##_type;
175
176 #define BOOST_FUSION_MAKE_DATA_MEMBER(R, DATA, N, ATTRIBUTE)                    \
177     BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE);
178
179 #ifdef BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND
180
181 #define BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTE_SEQ_SIZE)         \
182         template <typename boost_fusion_detail_Iterator>                        \
183         struct value_of : boost::fusion::result_of::at_c<                       \
184                               ref_vec_t,                                        \
185                               boost_fusion_detail_Iterator::index::value        \
186                           >                                                     \
187         {                                                                       \
188         };
189
190 #define BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ)                \
191         template <typename boost_fusion_detail_Iterator>                        \
192         struct deref                                                            \
193         {                                                                       \
194             typedef typename boost::remove_const<                               \
195                 boost_fusion_detail_Iterator                                    \
196             >::type iterator_raw_type;                                          \
197                                                                                 \
198             static const int index = iterator_raw_type::index::value;           \
199                                                                                 \
200             typedef typename boost::fusion::result_of::at_c<                    \
201                 ref_vec_t,                                                      \
202                 index                                                           \
203             >::type result_raw_type;                                            \
204                                                                                 \
205             typedef typename boost::mpl::if_<                                   \
206                 boost::is_const<typename iterator_raw_type::sequence_type>,     \
207                 typename boost::add_const<result_raw_type>::type,               \
208                 result_raw_type                                                 \
209             >::type type;                                                       \
210                                                                                 \
211             BOOST_FUSION_GPU_ENABLED                                            \
212             static type call(iterator_raw_type const& iter)                     \
213             {                                                                   \
214                 return boost::fusion::at_c<index>(iter.ref_vec);                \
215             }                                                                   \
216         };
217
218 #define BOOST_FUSION_MAKE_ITERATOR_WKND_FIELD_NAME(R, DATA, N, ATTRIBUTE)       \
219         BOOST_PP_COMMA_IF(N) seq.BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)
220
221 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES(ATTRIBUTES_SEQ)     \
222         , ref_vec(BOOST_PP_SEQ_FOR_EACH_I(                                      \
223                           BOOST_FUSION_MAKE_ITERATOR_WKND_FIELD_NAME,           \
224                           ~,                                                    \
225                           BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)))
226
227 #define BOOST_FUSION_MAKE_ITERATOR_WKND_REF(Z, N, DATA)                         \
228         BOOST_PP_COMMA_IF(N)                                                    \
229         typename boost::mpl::if_<                                               \
230                 boost::is_const<boost_fusion_detail_Seq>,                       \
231                 typename boost::add_const<                                      \
232                         typename boost_fusion_detail_Seq::t##N##_type           \
233                 >::type,                                                        \
234                 typename boost_fusion_detail_Seq::t##N##_type                   \
235         >::type&
236
237 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE)          \
238         typedef boost::fusion::vector<                                          \
239             BOOST_PP_REPEAT(                                                    \
240                     ATTRIBUTES_SEQ_SIZE,                                        \
241                     BOOST_FUSION_MAKE_ITERATOR_WKND_REF,                        \
242                     ~)                                                          \
243         > ref_vec_t;                                                            \
244                                                                                 \
245         ref_vec_t ref_vec;
246
247 #else
248
249 #define BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTES_SEQ_SIZE)        \
250         template <typename boost_fusion_detail_T> struct value_of;              \
251         BOOST_PP_REPEAT(                                                        \
252             ATTRIBUTES_SEQ_SIZE,                                                \
253             BOOST_FUSION_MAKE_ITERATOR_VALUE_OF_SPECS,                          \
254             NAME)
255
256 #define BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ)                \
257         template <typename boost_fusion_detail_T> struct deref;                 \
258         BOOST_PP_SEQ_FOR_EACH_I(                                                \
259             BOOST_FUSION_MAKE_ITERATOR_DEREF_SPECS,                             \
260             NAME,                                                               \
261             ATTRIBUTES_SEQ)
262
263 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES(ATTRIBUTES_SEQ)
264
265 #define BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE)
266
267 #endif  // BOOST_FUSION_NEED_NESTED_TEMPLATE_PARTIAL_SPEC_WKND
268
269 // Note: We can't nest the iterator inside the struct because we run into
270 //       a MSVC10 bug involving partial specializations of nested templates.
271
272 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_IMPL(NAME, ATTRIBUTES)                \
273     BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES)                \
274     struct NAME : boost::fusion::sequence_facade<                               \
275                       NAME,                                                     \
276                       boost::fusion::random_access_traversal_tag                \
277                   >                                                             \
278     {                                                                           \
279         BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES)             \
280     };
281
282 #define BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE_IMPL(                             \
283     TEMPLATE_PARAMS_SEQ, NAME, ATTRIBUTES)                                      \
284                                                                                 \
285     BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES)                \
286                                                                                 \
287     template <                                                                  \
288         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(                  \
289             (0)TEMPLATE_PARAMS_SEQ)                                             \
290     >                                                                           \
291     struct NAME : boost::fusion::sequence_facade<                               \
292                       NAME<                                                     \
293                           BOOST_PP_SEQ_ENUM(TEMPLATE_PARAMS_SEQ)                \
294                       >,                                                        \
295                       boost::fusion::random_access_traversal_tag                \
296                   >                                                             \
297     {                                                                           \
298         BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES)             \
299     };
300
301 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES)             \
302     BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL(                                    \
303         NAME,                                                                   \
304         BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END))
305
306 // Note: can't compute BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ) directly because
307 //       ATTRIBUTES_SEQ may be empty and calling BOOST_PP_SEQ_SIZE on an empty
308 //       sequence produces warnings on MSVC.
309 #define BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL(NAME, ATTRIBUTES_SEQ)           \
310     BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL(                        \
311         NAME,                                                                   \
312         ATTRIBUTES_SEQ,                                                         \
313         BOOST_PP_DEC(BOOST_PP_SEQ_SIZE((0)ATTRIBUTES_SEQ)))
314
315 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES)            \
316     BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(                                   \
317         NAME,                                                                   \
318         BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END))
319
320 #define BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(NAME, ATTRIBUTES_SEQ)          \
321     BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL(                       \
322         NAME,                                                                   \
323         ATTRIBUTES_SEQ,                                                         \
324         BOOST_PP_DEC(BOOST_PP_SEQ_SIZE((0)ATTRIBUTES_SEQ)))
325
326 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL(                   \
327     NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE)                                  \
328                                                                                 \
329     template <typename boost_fusion_detail_Seq, int N>                          \
330     struct BOOST_FUSION_ITERATOR_NAME(NAME)                                     \
331         : boost::fusion::iterator_facade<                                       \
332               BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Seq, N>,     \
333               boost::fusion::random_access_traversal_tag                        \
334           >                                                                     \
335     {                                                                           \
336         typedef boost::mpl::int_<N> index;                                      \
337         typedef boost_fusion_detail_Seq sequence_type;                          \
338                                                                                 \
339         BOOST_FUSION_GPU_ENABLED                                                \
340         BOOST_FUSION_ITERATOR_NAME(NAME)(boost_fusion_detail_Seq& seq)          \
341             : seq_(seq)                                                         \
342               BOOST_FUSION_DEFINE_ITERATOR_WKND_INIT_LIST_ENTRIES(              \
343                       (0)ATTRIBUTES_SEQ)                                        \
344         {}                                                                      \
345                                                                                 \
346         boost_fusion_detail_Seq& seq_;                                          \
347                                                                                 \
348         BOOST_FUSION_DEFINE_ITERATOR_WKND_MEMBERS(ATTRIBUTES_SEQ_SIZE)          \
349                                                                                 \
350         BOOST_FUSION_DEFINE_ITERATOR_VALUE_OF(NAME, ATTRIBUTES_SEQ_SIZE)        \
351                                                                                 \
352         BOOST_FUSION_DEFINE_ITERATOR_DEREF(NAME, ATTRIBUTES_SEQ)                \
353                                                                                 \
354         template <typename boost_fusion_detail_It>                              \
355         struct next                                                             \
356         {                                                                       \
357             typedef BOOST_FUSION_ITERATOR_NAME(NAME)<                           \
358                 typename boost_fusion_detail_It::sequence_type,                 \
359                 boost_fusion_detail_It::index::value + 1                        \
360             > type;                                                             \
361                                                                                 \
362             BOOST_FUSION_GPU_ENABLED                                            \
363             static type call(boost_fusion_detail_It const& it)                  \
364             {                                                                   \
365                 return type(it.seq_);                                           \
366             }                                                                   \
367         };                                                                      \
368                                                                                 \
369         template <typename boost_fusion_detail_It>                              \
370         struct prior                                                            \
371         {                                                                       \
372             typedef BOOST_FUSION_ITERATOR_NAME(NAME)<                           \
373                 typename boost_fusion_detail_It::sequence_type,                 \
374                 boost_fusion_detail_It::index::value - 1                        \
375             > type;                                                             \
376                                                                                 \
377             BOOST_FUSION_GPU_ENABLED                                            \
378             static type call(boost_fusion_detail_It const& it)                  \
379             {                                                                   \
380                 return type(it.seq_);                                           \
381             }                                                                   \
382         };                                                                      \
383                                                                                 \
384         template <                                                              \
385             typename boost_fusion_detail_It1,                                   \
386             typename boost_fusion_detail_It2                                    \
387         >                                                                       \
388         struct distance                                                         \
389         {                                                                       \
390             typedef typename boost::mpl::minus<                                 \
391                 typename boost_fusion_detail_It2::index,                        \
392                 typename boost_fusion_detail_It1::index                         \
393             >::type type;                                                       \
394                                                                                 \
395             BOOST_FUSION_GPU_ENABLED                                            \
396             static type call(boost_fusion_detail_It1 const& /* it1 */,          \
397                              boost_fusion_detail_It2 const& /* it2 */)          \
398             {                                                                   \
399                 return type();                                                  \
400             }                                                                   \
401         };                                                                      \
402                                                                                 \
403         template <                                                              \
404             typename boost_fusion_detail_It,                                    \
405             typename boost_fusion_detail_M                                      \
406         >                                                                       \
407         struct advance                                                          \
408         {                                                                       \
409             typedef BOOST_FUSION_ITERATOR_NAME(NAME)<                           \
410                 typename boost_fusion_detail_It::sequence_type,                 \
411                 boost_fusion_detail_It::index::value                            \
412                     + boost_fusion_detail_M::value                              \
413             > type;                                                             \
414                                                                                 \
415             BOOST_FUSION_GPU_ENABLED                                            \
416             static type call(boost_fusion_detail_It const& it)                  \
417             {                                                                   \
418                 return type(it.seq_);                                           \
419             }                                                                   \
420         };                                                                      \
421     };
422
423
424 #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS_IMPL_IMPL(                    \
425     NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE)                                  \
426                                                                                 \
427     /* Note: second BOOST_PP_IF is necessary to avoid MSVC warning when */      \
428     /*       calling BOOST_FUSION_IGNORE_1 with no arguments.           */      \
429     NAME()                                                                      \
430         BOOST_PP_IF(                                                            \
431             ATTRIBUTES_SEQ_SIZE,                                                \
432             BOOST_FUSION_MAKE_DEFAULT_INIT_LIST,                                \
433             BOOST_FUSION_IGNORE_1)                                              \
434                 (BOOST_PP_IF(                                                   \
435                     ATTRIBUTES_SEQ_SIZE,                                        \
436                     ATTRIBUTES_SEQ,                                             \
437                     0))                                                         \
438     {                                                                           \
439     }                                                                           \
440                                                                                 \
441     BOOST_PP_IF(                                                                \
442         ATTRIBUTES_SEQ_SIZE,                                                    \
443         BOOST_FUSION_MAKE_COPY_CONSTRUCTOR,                                     \
444         BOOST_FUSION_IGNORE_2)                                                  \
445             (NAME, ATTRIBUTES_SEQ)                                              \
446                                                                                 \
447     template <typename boost_fusion_detail_Seq>                                 \
448     BOOST_FUSION_GPU_ENABLED                                                    \
449     NAME(const boost_fusion_detail_Seq& rhs)                                    \
450     {                                                                           \
451         boost::fusion::copy(rhs, *this);                                        \
452     }                                                                           \
453                                                                                 \
454     template <typename boost_fusion_detail_Seq>                                 \
455     BOOST_FUSION_GPU_ENABLED                                                    \
456     NAME& operator=(const boost_fusion_detail_Seq& rhs)                         \
457     {                                                                           \
458         boost::fusion::copy(rhs, *this);                                        \
459         return *this;                                                           \
460     }                                                                           \
461                                                                                 \
462     template <typename boost_fusion_detail_Sq>                                  \
463     struct begin                                                                \
464     {                                                                           \
465         typedef BOOST_FUSION_ITERATOR_NAME(NAME)<boost_fusion_detail_Sq, 0>     \
466              type;                                                              \
467                                                                                 \
468         BOOST_FUSION_GPU_ENABLED                                                \
469         static type call(boost_fusion_detail_Sq& sq)                            \
470         {                                                                       \
471             return type(sq);                                                    \
472         }                                                                       \
473     };                                                                          \
474                                                                                 \
475     template <typename boost_fusion_detail_Sq>                                  \
476     struct end                                                                  \
477     {                                                                           \
478         typedef BOOST_FUSION_ITERATOR_NAME(NAME)<                               \
479             boost_fusion_detail_Sq,                                             \
480             ATTRIBUTES_SEQ_SIZE                                                 \
481         > type;                                                                 \
482                                                                                 \
483         BOOST_FUSION_GPU_ENABLED                                                \
484         static type call(boost_fusion_detail_Sq& sq)                            \
485         {                                                                       \
486             return type(sq);                                                    \
487         }                                                                       \
488     };                                                                          \
489                                                                                 \
490     template <typename boost_fusion_detail_Sq>                                  \
491     struct size : boost::mpl::int_<ATTRIBUTES_SEQ_SIZE>                         \
492     {                                                                           \
493     };                                                                          \
494                                                                                 \
495     template <typename boost_fusion_detail_Sq>                                  \
496     struct empty : boost::mpl::bool_<ATTRIBUTES_SEQ_SIZE == 0>                  \
497     {                                                                           \
498     };                                                                          \
499                                                                                 \
500     template <                                                                  \
501         typename boost_fusion_detail_Sq,                                        \
502         typename boost_fusion_detail_N                                          \
503     >                                                                           \
504     struct value_at : value_at<                                                 \
505                           boost_fusion_detail_Sq,                               \
506                           boost::mpl::int_<boost_fusion_detail_N::value>        \
507                       >                                                         \
508     {                                                                           \
509     };                                                                          \
510                                                                                 \
511     BOOST_PP_REPEAT(                                                            \
512         ATTRIBUTES_SEQ_SIZE,                                                    \
513         BOOST_FUSION_MAKE_VALUE_AT_SPECS,                                       \
514         ~)                                                                      \
515                                                                                 \
516     template <                                                                  \
517         typename boost_fusion_detail_Sq,                                        \
518         typename boost_fusion_detail_N                                          \
519     >                                                                           \
520     struct at : at<                                                             \
521                     boost_fusion_detail_Sq,                                     \
522                     boost::mpl::int_<boost_fusion_detail_N::value>              \
523                 >                                                               \
524     {                                                                           \
525     };                                                                          \
526                                                                                 \
527     BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_AT_SPECS, ~, ATTRIBUTES_SEQ)      \
528                                                                                 \
529     BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_MAKE_TYPEDEF, ~, ATTRIBUTES_SEQ)       \
530                                                                                 \
531     BOOST_PP_SEQ_FOR_EACH_I(                                                    \
532         BOOST_FUSION_MAKE_DATA_MEMBER,                                          \
533         ~,                                                                      \
534         ATTRIBUTES_SEQ)
535
536 #endif