Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2002-2003 Martin Wille
|
Chris@16
|
3 http://spirit.sourceforge.net/
|
Chris@16
|
4
|
Chris@16
|
5 Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 =============================================================================*/
|
Chris@16
|
9 #ifndef BOOST_SPIRIT_CONDITIONS_IPP
|
Chris@16
|
10 #define BOOST_SPIRIT_CONDITIONS_IPP
|
Chris@16
|
11
|
Chris@16
|
12 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
13 #include <boost/spirit/home/classic/meta/parser_traits.hpp>
|
Chris@16
|
14 #include <boost/spirit/home/classic/core/composite/epsilon.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
17 namespace boost { namespace spirit {
|
Chris@16
|
18
|
Chris@16
|
19 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
Chris@16
|
20
|
Chris@16
|
21 namespace impl {
|
Chris@16
|
22
|
Chris@16
|
23 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24 //
|
Chris@16
|
25 // condition evaluation
|
Chris@16
|
26 //
|
Chris@16
|
27 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
28 //////////////////////////////////
|
Chris@16
|
29 // condition_parser_selector, decides which parser to use for a condition
|
Chris@16
|
30 // If the template argument is a parser then that parser is used.
|
Chris@16
|
31 // If the template argument is a functor then a condition parser using
|
Chris@16
|
32 // the functor is chosen
|
Chris@16
|
33
|
Chris@16
|
34 template <typename T> struct embed_t_accessor
|
Chris@16
|
35 {
|
Chris@16
|
36 typedef typename T::embed_t type;
|
Chris@16
|
37 };
|
Chris@16
|
38
|
Chris@16
|
39 template <typename ConditionT>
|
Chris@16
|
40 struct condition_parser_selector
|
Chris@16
|
41 {
|
Chris@16
|
42 typedef
|
Chris@16
|
43 typename mpl::if_<
|
Chris@16
|
44 is_parser<ConditionT>,
|
Chris@16
|
45 ConditionT,
|
Chris@16
|
46 condition_parser<ConditionT>
|
Chris@16
|
47 >::type
|
Chris@16
|
48 type;
|
Chris@16
|
49
|
Chris@16
|
50 typedef typename embed_t_accessor<type>::type embed_t;
|
Chris@16
|
51 };
|
Chris@16
|
52
|
Chris@16
|
53 //////////////////////////////////
|
Chris@16
|
54 // condition_evaluator, uses a parser to check wether a condition is met
|
Chris@16
|
55 // takes a parser or a functor that can be evaluated in boolean context
|
Chris@16
|
56 // as template parameter.
|
Chris@16
|
57
|
Chris@16
|
58 // JDG 4-15-03 refactored
|
Chris@16
|
59 template <typename ConditionT>
|
Chris@16
|
60 struct condition_evaluator
|
Chris@16
|
61 {
|
Chris@16
|
62 typedef condition_parser_selector<ConditionT> selector_t;
|
Chris@16
|
63 typedef typename selector_t::type selected_t;
|
Chris@16
|
64 typedef typename selector_t::embed_t cond_embed_t;
|
Chris@16
|
65
|
Chris@16
|
66 typedef typename boost::call_traits<cond_embed_t>::param_type
|
Chris@16
|
67 param_t;
|
Chris@16
|
68
|
Chris@16
|
69 condition_evaluator(param_t s) : cond(s) {}
|
Chris@16
|
70
|
Chris@16
|
71 /////////////////////////////
|
Chris@16
|
72 // evaluate, checks wether condition is met
|
Chris@16
|
73 // returns length of a match or a negative number for no-match
|
Chris@16
|
74 template <typename ScannerT>
|
Chris@16
|
75 std::ptrdiff_t
|
Chris@16
|
76 evaluate(ScannerT const &scan) const
|
Chris@16
|
77 {
|
Chris@16
|
78 typedef typename ScannerT::iterator_t iterator_t;
|
Chris@16
|
79 typedef typename parser_result<selected_t, ScannerT>::type cres_t;
|
Chris@16
|
80 iterator_t save(scan.first);
|
Chris@16
|
81 cres_t result = cond.parse(scan);
|
Chris@16
|
82 if (!result) // reset the position if evaluation
|
Chris@16
|
83 scan.first = save; // fails.
|
Chris@16
|
84 return result.length();
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 cond_embed_t cond;
|
Chris@16
|
88 };
|
Chris@16
|
89
|
Chris@16
|
90 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
91 } // namespace impl
|
Chris@16
|
92
|
Chris@16
|
93 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
Chris@16
|
94
|
Chris@16
|
95 }} // namespace boost::spirit
|
Chris@16
|
96
|
Chris@16
|
97 #endif
|