source: NonGTP/Boost/boost/spirit/core/composite/impl/directives.ipp @ 857

Revision 857, 12.6 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 1998-2003 Joel de Guzman
3    Copyright (c) 2001 Daniel Nuffer
4    Copyright (c) 2001 Bruce Florman
5    Copyright (c) 2002 Raghavendra Satish
6    http://spirit.sourceforge.net/
7
8    Use, modification and distribution is subject to the Boost Software
9    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10    http://www.boost.org/LICENSE_1_0.txt)
11=============================================================================*/
12#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP)
13#define BOOST_SPIRIT_DIRECTIVES_IPP
14
15///////////////////////////////////////////////////////////////////////////////
16#include <boost/spirit/core/scanner/skipper.hpp>
17
18namespace boost { namespace spirit {
19
20    template <typename BaseT>
21    struct no_skipper_iteration_policy;
22
23    template <typename BaseT>
24    struct inhibit_case_iteration_policy;
25
26    template <typename A, typename B>
27    struct alternative;
28
29    template <typename A, typename B>
30    struct longest_alternative;
31
32    template <typename A, typename B>
33    struct shortest_alternative;
34
35    namespace impl
36    {
37        template <typename RT, typename ST, typename ScannerT, typename BaseT>
38        inline RT
39        contiguous_parser_parse(
40            ST const& s,
41            ScannerT const& scan,
42            skipper_iteration_policy<BaseT> const&)
43        {
44            typedef scanner_policies<
45                no_skipper_iteration_policy<
46                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
47                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
48                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
49            > policies_t;
50
51            scan.skip(scan);
52            RT hit = s.parse(scan.change_policies(policies_t(scan)));
53            // We will not do a post skip!!!
54            return hit;
55        }
56
57        template <typename RT, typename ST, typename ScannerT, typename BaseT>
58        inline RT
59        contiguous_parser_parse(
60            ST const& s,
61            ScannerT const& scan,
62            no_skipper_iteration_policy<BaseT> const&)
63        {
64            return s.parse(scan);
65        }
66
67        template <typename RT, typename ST, typename ScannerT>
68        inline RT
69        contiguous_parser_parse(
70            ST const& s,
71            ScannerT const& scan,
72            iteration_policy const&)
73        {
74            return s.parse(scan);
75        }
76
77        template <
78            typename RT,
79            typename ParserT,
80            typename ScannerT,
81            typename BaseT>
82        inline RT
83        implicit_lexeme_parse(
84            ParserT const& p,
85            ScannerT const& scan,
86            skipper_iteration_policy<BaseT> const&)
87        {
88            typedef scanner_policies<
89                no_skipper_iteration_policy<
90                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
91                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
92                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
93            > policies_t;
94
95            scan.skip(scan);
96            RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
97            // We will not do a post skip!!!
98            return hit;
99        }
100
101        template <
102            typename RT,
103            typename ParserT,
104            typename ScannerT,
105            typename BaseT>
106        inline RT
107        implicit_lexeme_parse(
108            ParserT const& p,
109            ScannerT const& scan,
110            no_skipper_iteration_policy<BaseT> const&)
111        {
112            return p.parse_main(scan);
113        }
114
115        template <typename RT, typename ParserT, typename ScannerT>
116        inline RT
117        implicit_lexeme_parse(
118            ParserT const& p,
119            ScannerT const& scan,
120            iteration_policy const&)
121        {
122            return p.parse_main(scan);
123        }
124
125        template <typename RT, typename ST, typename ScannerT>
126        inline RT
127        inhibit_case_parser_parse(
128            ST const& s,
129            ScannerT const& scan,
130            iteration_policy const&)
131        {
132            typedef scanner_policies<
133                inhibit_case_iteration_policy<
134                    BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
135                BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
136                BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
137            > policies_t;
138
139            return s.parse(scan.change_policies(policies_t(scan)));
140        }
141
142        template <typename RT, typename ST, typename ScannerT, typename BaseT>
143        inline RT
144        inhibit_case_parser_parse(
145            ST const& s,
146            ScannerT const& scan,
147            inhibit_case_iteration_policy<BaseT> const&)
148        {
149            return s.parse(scan);
150        }
151
152#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
153
154        ///////////////////////////////////////////////////////////////////////
155        //
156        //  from spirit 1.1 (copyright (c) 2001 Bruce Florman)
157        //  various workarounds to support longest and shortest directives
158        //
159        ///////////////////////////////////////////////////////////////////////
160        template <typename T>
161        struct is_alternative
162        {
163        //  Determine at compile time (without partial specialization)
164        //  whether a given type is an instance of the alternative<A,B>
165
166            static T t();
167            template <typename A, typename B>
168            static char test_(alternative<A, B> const&);    // no implementation
169            static int  test_(...);                         // no implementation
170            enum { r = sizeof(char) == sizeof(test_(t())) };
171            typedef mpl::bool_<r> value;
172        };
173
174        template <typename T> struct select_to_longest;
175
176        template <typename T>
177        struct to_longest_alternative
178        {
179            typedef typename select_to_longest<T>::result_t result_t;
180            typedef typename select_to_longest<T>::plain_t  plain_t;
181            typedef typename select_to_longest<T>::choose_t choose_t;
182            static result_t convert(T const& a);
183        };
184
185        template <typename T>
186        struct to_longest_generic
187        {
188            typedef T const&        result_t;
189            typedef T               plain_t;
190            typedef mpl::false_    choose_t;
191        };
192
193        template <typename T>
194        inline T const&
195        to_longest_convert(T const& a, mpl::false_)
196        { return a; }
197
198        template <typename T>
199        struct to_longest_recursive
200        {
201            typedef typename to_longest_alternative<
202                typename T::left_t>::plain_t    a_t;
203            typedef typename to_longest_alternative<
204                typename T::right_t>::plain_t   b_t;
205
206            typedef longest_alternative<a_t, b_t>   result_t;
207
208            typedef result_t    plain_t;
209            typedef mpl::true_ choose_t;
210        };
211
212        template <typename A, typename B>
213        inline typename to_longest_alternative<alternative<A, B> >::result_t
214        to_longest_convert(alternative<A, B> const& alt, mpl::true_)
215        {
216            typedef typename to_longest_alternative<
217                alternative<A, B> >::result_t result_t;
218            return result_t(
219                to_longest_alternative<A>::convert(alt.left()),
220                to_longest_alternative<B>::convert(alt.right()));
221        }
222
223        template <typename T>
224        inline typename to_longest_alternative<T>::result_t
225        to_longest_alternative<T>::convert(T const& a)
226        {
227            return to_longest_convert(
228                a, to_longest_alternative<T>::choose_t());
229        }
230
231        template <typename T>
232        struct select_to_longest
233        {
234            typedef typename mpl::if_<
235                is_alternative<T>           //  IF
236                , to_longest_recursive<T>   //  THEN
237                , to_longest_generic<T>     //  ELSE
238            >::type type;
239
240            typedef typename select_to_longest::type::result_t result_t;
241            typedef typename select_to_longest::type::plain_t  plain_t;
242            typedef typename select_to_longest::type::choose_t choose_t;
243        };
244
245        template <typename T> struct select_to_shortest;
246
247        template <typename T>
248        struct to_shortest_alternative
249        {
250            typedef typename select_to_shortest<T>::result_t    result_t;
251            typedef typename select_to_shortest<T>::plain_t     plain_t;
252            typedef typename select_to_shortest<T>::choose_t    choose_t;
253            static result_t convert(T const& a);
254        };
255
256        template <typename T>
257        struct to_shortest_generic
258        {
259            typedef T const&        result_t;
260            typedef T               plain_t;
261            typedef mpl::false_    choose_t;
262        };
263
264        template <typename T>
265        inline T const&
266        to_shortest_convert(T const& a, mpl::false_) { return a; }
267
268        template <typename T>
269        struct to_shortest_recursive
270        {
271            typedef typename to_shortest_alternative<
272                typename T::left_t>::plain_t    a_t;
273            typedef typename to_shortest_alternative<
274                typename T::right_t>::plain_t   b_t;
275
276            typedef shortest_alternative<a_t, b_t>  result_t;
277
278            typedef result_t        plain_t;
279            typedef mpl::true_     choose_t;
280        };
281
282        template <typename A, typename B>
283        inline typename to_shortest_alternative<alternative<A, B> >::result_t
284        to_shortest_convert(alternative<A, B> const& alt, mpl::true_)
285        {
286            typedef typename to_shortest_alternative<
287                alternative<A, B> >::result_t result_t;
288            return result_t(
289                to_shortest_alternative<A>::convert(alt.left()),
290                to_shortest_alternative<B>::convert(alt.right()));
291        }
292
293        template <typename T>
294        inline typename to_shortest_alternative<T>::result_t
295        to_shortest_alternative<T>::convert(T const& a)
296        {
297            return to_shortest_convert(
298                a, to_shortest_alternative<T>::choose_t());
299        }
300
301        template <typename T>
302        struct select_to_shortest
303        {
304            typedef typename mpl::if_<
305                is_alternative<T>           //  IF
306                , to_shortest_recursive<T>  //  THEN
307                , to_shortest_generic<T>    //  ELSE
308            >::type type;
309
310            typedef typename select_to_shortest::type::result_t result_t;
311            typedef typename select_to_shortest::type::plain_t  plain_t;
312            typedef typename select_to_shortest::type::choose_t choose_t;
313        };
314#else
315        template <typename T>
316        struct to_longest_alternative
317        {
318            typedef T result_t;
319            static result_t const&
320            convert(T const& a)  //  Special (end) case
321            { return a; }
322        };
323
324        template <typename A, typename B>
325        struct to_longest_alternative<alternative<A, B> >
326        {
327            typedef typename to_longest_alternative<A>::result_t    a_t;
328            typedef typename to_longest_alternative<B>::result_t    b_t;
329            typedef longest_alternative<a_t, b_t>                   result_t;
330
331            static result_t
332            convert(alternative<A, B> const& alt) // Recursive case
333            {
334                return result_t(
335                    to_longest_alternative<A>::convert(alt.left()),
336                    to_longest_alternative<B>::convert(alt.right()));
337            }
338        };
339
340        template <typename T>
341        struct to_shortest_alternative
342        {
343            typedef T result_t;
344            static result_t const&
345            convert(T const& a) //  Special (end) case
346            { return a; }
347        };
348
349        template <typename A, typename B>
350        struct to_shortest_alternative<alternative<A, B> >
351        {
352            typedef typename to_shortest_alternative<A>::result_t   a_t;
353            typedef typename to_shortest_alternative<B>::result_t   b_t;
354            typedef shortest_alternative<a_t, b_t>                  result_t;
355
356            static result_t
357            convert(alternative<A, B> const& alt) //  Recursive case
358            {
359                return result_t(
360                    to_shortest_alternative<A>::convert(alt.left()),
361                    to_shortest_alternative<B>::convert(alt.right()));
362            }
363        };
364#endif
365    }
366
367}} // namespace boost::spirit
368
369#endif
370
Note: See TracBrowser for help on using the repository browser.