Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / xpressive / detail / static / transforms / as_independent.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // as_independent.hpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_INDEPENDENT_HPP_EAN_04_05_2007
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_INDEPENDENT_HPP_EAN_04_05_2007
10
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER)
13 # pragma once
14 #endif
15
16 #include <boost/mpl/sizeof.hpp>
17 #include <boost/xpressive/detail/detail_fwd.hpp>
18 #include <boost/xpressive/detail/static/static.hpp>
19 #include <boost/proto/core.hpp>
20 #include <boost/proto/transform/arg.hpp>
21 #include <boost/proto/transform/when.hpp>
22 #include <boost/proto/transform/fold.hpp>
23 #include <boost/proto/transform/fold_tree.hpp>
24
25 namespace boost { namespace xpressive { namespace detail
26 {
27     struct keeper_tag
28     {};
29
30     struct lookahead_tag
31     {};
32
33     struct lookbehind_tag
34     {};
35 }}}
36
37 namespace boost { namespace xpressive { namespace grammar_detail
38 {
39     // A grammar that only accepts static regexes that
40     // don't have semantic actions.
41     struct NotHasAction
42       : proto::switch_<struct NotHasActionCases>
43     {};
44
45     struct NotHasActionCases
46     {
47         template<typename Tag, int Dummy = 0>
48         struct case_
49           : proto::nary_expr<Tag, proto::vararg<NotHasAction> >
50         {};
51
52         template<int Dummy>
53         struct case_<proto::tag::terminal, Dummy>
54           : not_< or_<
55                 proto::terminal<detail::tracking_ptr<detail::regex_impl<_> > >,
56                 proto::terminal<reference_wrapper<_> >
57             > >
58         {};
59
60         template<int Dummy>
61         struct case_<proto::tag::comma, Dummy>
62           : proto::_    // because (set='a','b') can't contain an action
63         {};
64
65         template<int Dummy>
66         struct case_<proto::tag::complement, Dummy>
67           : proto::_    // because in ~X, X can't contain an unscoped action
68         {};
69
70         template<int Dummy>
71         struct case_<detail::lookahead_tag, Dummy>
72           : proto::_    // because actions in lookaheads are scoped
73         {};
74
75         template<int Dummy>
76         struct case_<detail::lookbehind_tag, Dummy>
77           : proto::_    // because actions in lookbehinds are scoped
78         {};
79
80         template<int Dummy>
81         struct case_<detail::keeper_tag, Dummy>
82           : proto::_    // because actions in keepers are scoped
83         {};
84
85         template<int Dummy>
86         struct case_<proto::tag::subscript, Dummy>
87           : proto::subscript<detail::set_initializer_type, _>
88         {}; // only accept set[...], not actions!
89     };
90
91     struct IndependentEndXpression
92       : or_<
93             when<NotHasAction, detail::true_xpression()>
94           , otherwise<detail::independent_end_xpression()>
95         >
96     {};
97
98     template<typename Grammar, typename Callable = proto::callable>
99     struct as_lookahead : proto::transform<as_lookahead<Grammar, Callable> >
100     {
101         template<typename Expr, typename State, typename Data>
102         struct impl : proto::transform_impl<Expr, State, Data>
103         {
104             typedef typename proto::result_of::child<Expr>::type arg_type;
105
106             typedef
107                 typename IndependentEndXpression::impl<arg_type, int, int>::result_type
108             end_xpr_type;
109
110             typedef
111                 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
112             xpr_type;
113
114             typedef
115                 detail::lookahead_matcher<xpr_type>
116             result_type;
117
118             result_type operator ()(
119                 typename impl::expr_param expr
120               , typename impl::state_param
121               , typename impl::data_param data
122             ) const
123             {
124                 int i = 0;
125                 return result_type(
126                     typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
127                         proto::child(expr)
128                       , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
129                       , data
130                     )
131                   , false
132                 );
133             }
134         };
135     };
136
137     template<typename Grammar, typename Callable = proto::callable>
138     struct as_lookbehind : proto::transform<as_lookbehind<Grammar, Callable> >
139     {
140         template<typename Expr, typename State, typename Data>
141         struct impl : proto::transform_impl<Expr, State, Data>
142         {
143             typedef typename proto::result_of::child<Expr>::type arg_type;
144
145             typedef
146                 typename IndependentEndXpression::impl<arg_type, int, int>::result_type
147             end_xpr_type;
148
149             typedef
150                 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
151             xpr_type;
152
153             typedef
154                 detail::lookbehind_matcher<xpr_type>
155             result_type;
156
157             result_type operator ()(
158                 typename impl::expr_param expr
159               , typename impl::state_param
160               , typename impl::data_param data
161             ) const
162             {
163                 int i = 0;
164                 xpr_type expr2 = typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
165                     proto::child(expr)
166                   , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
167                   , data
168                 );
169                 std::size_t width = expr2.get_width().value();
170                 return result_type(expr2, width, false);
171             }
172         };
173     };
174
175     template<typename Grammar, typename Callable = proto::callable>
176     struct as_keeper : proto::transform<as_keeper<Grammar, Callable> >
177     {
178         template<typename Expr, typename State, typename Data>
179         struct impl : proto::transform_impl<Expr, State, Data>
180         {
181             typedef typename proto::result_of::child<Expr>::type arg_type;
182
183             typedef
184                 typename IndependentEndXpression::impl<arg_type, int, int>::result_type
185             end_xpr_type;
186
187             typedef
188                 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
189             xpr_type;
190
191             typedef
192                 detail::keeper_matcher<xpr_type>
193             result_type;
194
195             result_type operator ()(
196                 typename impl::expr_param expr
197               , typename impl::state_param
198               , typename impl::data_param data
199             ) const
200             {
201                 int i = 0;
202                 return result_type(
203                     typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
204                         proto::child(expr)
205                       , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
206                       , data
207                     )
208                 );
209             }
210         };
211     };
212
213 }}}
214
215 #endif