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