]> git.donarmstrong.com Git - rsem.git/blob - boost/fusion/adapted/struct/detail/adapt_base.hpp
b2d81cf8cbdbb85509de43f3d7bc9244c94ec32b
[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-2010 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/mpl/bool.hpp>
27 #include <boost/mpl/tag.hpp>
28 #include <boost/mpl/eval_if.hpp>
29 #include <boost/mpl/identity.hpp>
30 #include <boost/type_traits/add_const.hpp>
31
32 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ)              \
33     BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))>           \
34     BOOST_PP_EMPTY()
35
36 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(SEQ)                              \
37     BOOST_PP_IF(                                                                \
38         BOOST_PP_SEQ_HEAD(SEQ),                                                 \
39         BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS,                  \
40         BOOST_PP_SEQ_HEAD)(BOOST_PP_SEQ_TAIL(SEQ))
41
42 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C(R, _, ELEM)     \
43     (typename ELEM)
44 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL(SEQ)              \
45     BOOST_PP_SEQ_ENUM(                                                          \
46         BOOST_PP_SEQ_FOR_EACH(                                                  \
47             BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL_C,            \
48             _,                                                                  \
49             BOOST_PP_SEQ_TAIL(SEQ)))
50 #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(SEQ)                   \
51     BOOST_PP_IF(                                                                \
52         BOOST_PP_SEQ_HEAD(SEQ),                                                 \
53         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL,                  \
54         BOOST_PP_TUPLE_EAT(1))(SEQ)
55
56 #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
57 #   define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION(                     \
58         MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG)                           \
59                                                                                 \
60     template<                                                                   \
61         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ)   \
62     >                                                                           \
63     struct tag_of<                                                              \
64         BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER                \
65       , void                                                                    \
66     >                                                                           \
67     {                                                                           \
68         typedef TAG type;                                                       \
69     };
70 #else
71 #   define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION(                     \
72         MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG)                           \
73                                                                                 \
74     template<                                                                   \
75         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ)   \
76     >                                                                           \
77     struct tag_of<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) MODIFIER>     \
78     {                                                                           \
79         typedef TAG type;                                                       \
80     };
81 #endif
82
83 #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE)      \
84     BOOST_PP_TUPLE_ELEM(3,0,DATA)(                                              \
85         BOOST_PP_TUPLE_ELEM(3,1,DATA),                                          \
86         BOOST_PP_TUPLE_ELEM(3,2,DATA),                                          \
87         I,                                                                      \
88         ATTRIBUTE)
89
90 #define BOOST_FUSION_ADAPT_STRUCT_C_BASE(                                       \
91     TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE)       \
92                                                                                 \
93     template<                                                                   \
94         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ)   \
95     >                                                                           \
96     struct struct_member<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ), I>    \
97     {                                                                           \
98         typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type;   \
99                                                                                 \
100         template<typename Seq>                                                  \
101         struct apply                                                            \
102         {                                                                       \
103             typedef typename                                                    \
104                 add_reference<                                                  \
105                     typename mpl::eval_if<                                      \
106                         is_const<Seq>                                           \
107                       , add_const<BOOST_PP_TUPLE_ELEM(                          \
108                             ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)                 \
109                         >                                                       \
110                       , mpl::identity<BOOST_PP_TUPLE_ELEM(                      \
111                           ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)                   \
112                         >                                                       \
113                     >::type                                                     \
114                 >::type                                                         \
115             type;                                                               \
116                                                                                 \
117             static type                                                         \
118             call(Seq& seq)                                                      \
119             {                                                                   \
120                 return seq.PREFIX()                                             \
121                     BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE);    \
122             }                                                                   \
123         };                                                                      \
124     };                                                                          \
125                                                                                 \
126     template<                                                                   \
127         BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ)   \
128     >                                                                           \
129     struct struct_member_name<                                                  \
130         BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)                         \
131       , I                                                                       \
132     >                                                                           \
133     {                                                                           \
134         typedef char const* type;                                               \
135                                                                                 \
136         static type                                                             \
137         call()                                                                  \
138         {                                                                       \
139             return BOOST_PP_STRINGIZE(                                          \
140                 BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE,1,ATTRIBUTE));         \
141         }                                                                       \
142     };
143
144 #define BOOST_FUSION_ADAPT_STRUCT_BASE(                                         \
145     TEMPLATE_PARAMS_SEQ,                                                        \
146     NAME_SEQ,                                                                   \
147     TAG,                                                                        \
148     IS_VIEW,                                                                    \
149     ATTRIBUTES_SEQ,                                                             \
150     ATTRIBUTES_CALLBACK)                                                        \
151                                                                                 \
152 namespace boost                                                                 \
153 {                                                                               \
154     namespace fusion                                                            \
155     {                                                                           \
156         namespace traits                                                        \
157         {                                                                       \
158             BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION(                    \
159                 BOOST_PP_EMPTY(), TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG)           \
160             BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION(                    \
161                 const, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG)                      \
162         }                                                                       \
163                                                                                 \
164         namespace extension                                                     \
165         {                                                                       \
166             BOOST_PP_SEQ_FOR_EACH_I_R(                                          \
167                 1,                                                              \
168                 BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL,                 \
169                 (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ),             \
170                 ATTRIBUTES_SEQ)                                                 \
171                                                                                 \
172             template<                                                           \
173                 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(               \
174                     TEMPLATE_PARAMS_SEQ)                                        \
175             >                                                                   \
176             struct struct_size<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)> \
177               : mpl::int_<BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ)>                    \
178             {};                                                                 \
179                                                                                 \
180             template<                                                           \
181                 BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(               \
182                     TEMPLATE_PARAMS_SEQ)                                        \
183             >                                                                   \
184             struct struct_is_view<                                              \
185                 BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)                 \
186             >                                                                   \
187               : mpl::BOOST_PP_IF(IS_VIEW,true_,false_)                          \
188             {};                                                                 \
189         }                                                                       \
190     }                                                                           \
191                                                                                 \
192     namespace mpl                                                               \
193     {                                                                           \
194         template<typename>                                                      \
195         struct sequence_tag;                                                    \
196                                                                                 \
197         template<                                                               \
198             BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(                   \
199                 TEMPLATE_PARAMS_SEQ)                                            \
200         >                                                                       \
201         struct sequence_tag<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)>    \
202         {                                                                       \
203             typedef fusion::fusion_sequence_tag type;                           \
204         };                                                                      \
205                                                                                 \
206         template<                                                               \
207             BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(                   \
208                 TEMPLATE_PARAMS_SEQ)                                            \
209         >                                                                       \
210         struct sequence_tag<                                                    \
211             BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const               \
212         >                                                                       \
213         {                                                                       \
214             typedef fusion::fusion_sequence_tag type;                           \
215         };                                                                      \
216     }                                                                           \
217 }
218
219 #endif