PageRenderTime 71ms CodeModel.GetById 14ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/boost/spirit/home/support/make_component.hpp

http://pythonocc.googlecode.com/
C++ Header | 364 lines | 296 code | 52 blank | 16 comment | 0 complexity | c8894e15238d50a6e1e8e0a513ffb29c MD5 | raw file
  1/*=============================================================================
  2  Copyright (c) 2001-2010 Joel de Guzman
  3  http://spirit.sourceforge.net/
  4
  5  Distributed under the Boost Software License, Version 1.0. (See accompanying
  6  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7=============================================================================*/
  8#ifndef BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
  9#define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
 10
 11#if defined(_MSC_VER)
 12#pragma once
 13#endif
 14
 15#include <boost/proto/proto.hpp>
 16#include <boost/spirit/home/support/detail/make_cons.hpp>
 17#include <boost/spirit/home/support/modify.hpp>
 18
 19namespace boost { namespace spirit
 20{
 21    // There is no real "component" class. Each domain is responsible
 22    // for creating its own components. You need to specialize this for
 23    // each component in your domain. Use this as a guide.
 24
 25    template <typename Domain, typename Tag, typename Enable = void>
 26    struct make_component
 27    {
 28        template <typename Sig>
 29        struct result;
 30
 31        template <typename This, typename Elements, typename Modifiers>
 32        struct result<This(Elements, Modifiers)>;
 33
 34        template <typename Elements, typename Modifiers>
 35        typename result<make_component(Elements, Modifiers)>::type
 36        operator()(Elements const& elements, Modifiers const& modifiers) const;
 37    };
 38
 39    namespace tag
 40    {
 41        // Normally, we use proto tags as-is to distinguish operators.
 42        // The special case is proto::tag::subscript. Spirit uses this
 43        // as either sementic actions or directives. To distinguish between
 44        // the two, we use these special tags below.
 45
 46        struct directive;
 47        struct action;
 48    }
 49
 50    template <typename Domain, typename T, typename Enable = void>
 51    struct flatten_tree;
 52}}
 53
 54namespace boost { namespace spirit { namespace detail
 55{
 56    template <typename Domain>
 57    struct make_terminal : proto::transform<make_terminal<Domain> >
 58    {
 59        template<typename Expr, typename State, typename Data>
 60        struct impl : proto::transform_impl<Expr, State, Data>
 61        {
 62            typedef typename
 63                proto::result_of::value<Expr>::type 
 64            value;
 65
 66            typedef typename result_of::make_cons<value>::type elements;
 67
 68            typedef
 69                make_component<Domain, proto::tag::terminal>
 70            make_component_;
 71
 72            typedef typename
 73                make_component_::template
 74                    result<make_component_(elements, Data)>::type
 75            result_type;
 76
 77            result_type operator()(
 78                typename impl::expr_param expr
 79              , typename impl::state_param /*state*/
 80              , typename impl::data_param data
 81            ) const
 82            {
 83                return typename impl::make_component_()(
 84                    detail::make_cons(proto::value(expr))
 85                  , data
 86                );
 87            }
 88        };
 89    };
 90
 91    template <typename Domain, typename Tag, typename Grammar>
 92    struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
 93    {
 94        template<typename Expr, typename State, typename Data>
 95        struct impl : proto::transform_impl<Expr, State, Data>
 96        {
 97            typedef typename
 98                proto::result_of::child_c<Expr, 0>::type
 99            child;
100
101            typedef typename Grammar::
102                template result<Grammar(child, State, Data)>::type
103            child_component;
104
105            typedef typename
106                result_of::make_cons<child_component>::type
107            elements;
108
109            typedef make_component<Domain, Tag> make_component_;
110
111            typedef typename
112                make_component_::template
113                    result<make_component_(elements, Data)>::type
114            result_type;
115
116            result_type operator()(
117                typename impl::expr_param expr
118              , typename impl::state_param state
119              , typename impl::data_param data
120            ) const
121            {
122                return typename impl::make_component_()(
123                    detail::make_cons(
124                        Grammar()(proto::child(expr), state, data))
125                  , data
126                );
127            }
128        };
129    };
130
131    // un-flattened version
132    template <typename Domain, typename Tag, typename Grammar,
133        bool flatten = flatten_tree<Domain, Tag>::value>
134    struct make_binary
135    {
136        template<typename Expr, typename State, typename Data>
137        struct impl : proto::transform_impl<Expr, State, Data>
138        {
139            typedef typename Grammar::
140                template result<Grammar(
141                    typename proto::result_of::child_c<Expr, 0>::type
142                  , State, Data)>::type
143            lhs_component;
144
145            typedef typename Grammar::
146                template result<Grammar(
147                    typename proto::result_of::child_c<Expr, 1>::type
148                  , State, Data)>::type
149            rhs_component;
150
151            typedef typename
152                result_of::make_cons<
153                    lhs_component
154                  , typename result_of::make_cons<rhs_component>::type
155                >::type
156            elements_type;
157
158            typedef make_component<Domain, Tag> make_component_;
159
160            typedef typename
161                make_component_::template
162                    result<make_component_(elements_type, Data)>::type
163            result_type;
164
165            result_type operator()(
166                typename impl::expr_param expr
167              , typename impl::state_param state
168              , typename impl::data_param data
169            ) const
170            {
171                elements_type elements =
172                    detail::make_cons(
173                        Grammar()(
174                            proto::child_c<0>(expr), state, data)       // LHS
175                      , detail::make_cons(
176                            Grammar()(
177                                proto::child_c<1>(expr), state, data)   // RHS
178                        )
179                    );
180
181                return make_component_()(elements, data);
182            }
183        };
184    };
185
186    template <typename Grammar>
187    struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
188    {
189        template<typename Expr, typename State, typename Data>
190        struct impl : proto::transform_impl<Expr, State, Data>
191        {
192            typedef typename Grammar::
193                template result<Grammar(Expr, State, Data)>::type
194            lhs;
195
196            typedef typename result_of::make_cons<lhs, State>::type result_type;
197
198            result_type operator()(
199                typename impl::expr_param expr
200              , typename impl::state_param state
201              , typename impl::data_param data
202            ) const
203            {
204                return detail::make_cons(Grammar()(expr, state, data), state);
205            }
206        };
207    };
208
209    // Flattened version
210    template <typename Domain, typename Tag, typename Grammar>
211    struct make_binary<Domain, Tag, Grammar, true>
212      : proto::transform<make_binary<Domain, Tag, Grammar> >
213    {
214        template<typename Expr, typename State, typename Data>
215        struct impl : proto::transform_impl<Expr, State, Data>
216        {
217            typedef typename
218                proto::reverse_fold_tree<
219                    proto::_
220                  , proto::make<fusion::nil>
221                  , make_binary_helper<Grammar>
222                >::template impl<Expr, State, Data>
223            reverse_fold_tree;
224
225            typedef typename reverse_fold_tree::result_type elements;
226            typedef make_component<Domain, Tag> make_component_;
227
228            typedef typename
229                make_component_::template
230                    result<make_component_(elements, Data)>::type
231            result_type;
232
233            result_type operator()(
234                typename impl::expr_param expr
235              , typename impl::state_param state
236              , typename impl::data_param data
237            ) const
238            {
239                return make_component_()(
240                    reverse_fold_tree()(expr, state, data), data);
241            }
242        };
243    };
244
245    template <typename Domain, typename Grammar>
246    struct make_directive : proto::transform<make_directive<Domain, Grammar> >
247    {
248        template<typename Expr, typename State, typename Data>
249        struct impl : proto::transform_impl<Expr, State, Data>
250        {
251            typedef typename
252                proto::result_of::child_c<Expr, 0>::type
253            lhs;
254
255            typedef typename
256                proto::result_of::value<lhs>::type
257            tag_type;
258
259            typedef typename modify<Domain>::
260                template result<modify<Domain>(tag_type, Data)>::type
261            modifier_type;
262
263            typedef typename Grammar::
264                template result<Grammar(
265                    typename proto::result_of::child_c<Expr, 1>::type
266                  , State
267                  , modifier_type
268                )>::type
269            rhs_component;
270
271            typedef typename
272                result_of::make_cons<
273                    tag_type
274                  , typename result_of::make_cons<rhs_component>::type
275                >::type
276            elements_type;
277
278            typedef make_component<Domain, tag::directive> make_component_;
279
280            typedef typename
281                make_component_::template
282                    result<make_component_(elements_type, Data)>::type
283            result_type;
284
285            result_type operator()(
286                typename impl::expr_param expr
287              , typename impl::state_param state
288              , typename impl::data_param data
289            ) const
290            {
291                tag_type tag = proto::value(proto::child_c<0>(expr));
292                typename remove_reference<modifier_type>::type
293                    modifier = modify<Domain>()(tag, data);
294
295                elements_type elements =
296                    detail::make_cons(
297                        tag                                 // LHS
298                      , detail::make_cons(
299                            Grammar()(
300                                proto::child_c<1>(expr)     // RHS
301                              , state, modifier)
302                        )
303                    );
304
305                return make_component_()(elements, data);
306            }
307        };
308    };
309
310    template <typename Domain, typename Grammar>
311    struct make_action : proto::transform<make_action<Domain, Grammar> >
312    {
313        template<typename Expr, typename State, typename Data>
314        struct impl : proto::transform_impl<Expr, State, Data>
315        {
316            typedef typename Grammar::
317                template result<Grammar(
318                    typename proto::result_of::child_c<Expr, 0>::type
319                  , State
320                  , Data
321                )>::type
322            lhs_component;
323
324            typedef typename
325                proto::result_of::value<
326                    typename proto::result_of::child_c<Expr, 1>::type
327                >::type
328            rhs_component;
329
330            typedef typename
331                result_of::make_cons<
332                    lhs_component
333                  , typename result_of::make_cons<rhs_component>::type
334                >::type
335            elements_type;
336
337            typedef make_component<Domain, tag::action> make_component_;
338
339            typedef typename
340                make_component_::template
341                    result<make_component_(elements_type, Data)>::type
342            result_type;
343
344            result_type operator()(
345                typename impl::expr_param expr
346              , typename impl::state_param state
347              , typename impl::data_param data
348            ) const
349            {
350                elements_type elements =
351                    detail::make_cons(
352                        Grammar()(
353                            proto::child_c<0>(expr), state, data)   // LHS
354                      , detail::make_cons(
355                            proto::value(proto::child_c<1>(expr)))  // RHS
356                    );
357
358                return make_component_()(elements, data);
359            }
360        };
361    };
362}}}
363
364#endif