]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/core/composite/actions.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / core / composite / actions.hpp
1 /*=============================================================================
2 Copyright (c) 1998-2003 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_ACTIONS_HPP
9 #define BOOST_SPIRIT_ACTIONS_HPP
10
11 #include <boost/spirit/home/classic/namespace.hpp>
12 #include <boost/spirit/home/classic/core/parser.hpp>
13 #include <boost/spirit/home/classic/core/composite/composite.hpp>
14
15 namespace boost { namespace spirit {
16
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
18
19 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
20 #pragma warning(push)
21 #pragma warning(disable:4512) //assignment operator could not be generated
22 #endif
23
24 ///////////////////////////////////////////////////////////////////////////
25 //
26 // action class
27 //
28 // The action class binds a parser with a user defined semantic
29 // action. Instances of action are never created manually. Instead,
30 // action objects are typically created indirectly through
31 // expression templates of the form:
32 //
33 // p[f]
34 //
35 // where p is a parser and f is a function or functor. The semantic
36 // action may be a function or a functor. When the parser is
37 // successful, the actor calls the scanner's action_policy policy
38 // (see scanner.hpp):
39 //
40 // scan.do_action(actor, attribute, first, last);
41 //
42 // passing in these information:
43 //
44 // actor: The action's function or functor
45 // attribute: The match (returned by the parser) object's
46 // attribute (see match.hpp)
47 // first: Iterator pointing to the start of the matching
48 // portion of the input
49 // last: Iterator pointing to one past the end of the
50 // matching portion of the input
51 //
52 // It is the responsibility of the scanner's action_policy policy to
53 // dispatch the function or functor as it sees fit. The expected
54 // function or functor signature depends on the parser being
55 // wrapped. In general, if the attribute type of the parser being
56 // wrapped is a nil_t, the function or functor expect the signature:
57 //
58 // void func(Iterator first, Iterator last); // functions
59 //
60 // struct ftor // functors
61 // {
62 // void func(Iterator first, Iterator last) const;
63 // };
64 //
65 // where Iterator is the type of the iterator that is being used and
66 // first and last are the iterators pointing to the matching portion
67 // of the input.
68 //
69 // If the attribute type of the parser being wrapped is not a nil_t,
70 // the function or functor usually expect the signature:
71 //
72 // void func(T val); // functions
73 //
74 // struct ftor // functors
75 // {
76 // void func(T val) const;
77 // };
78 //
79 // where T is the attribute type and val is the attribute value
80 // returned by the parser being wrapped.
81 //
82 ///////////////////////////////////////////////////////////////////////////
83 template <typename ParserT, typename ActionT>
84 class action : public unary<ParserT, parser<action<ParserT, ActionT> > >
85 {
86 public:
87
88 typedef action<ParserT, ActionT> self_t;
89 typedef action_parser_category parser_category_t;
90 typedef unary<ParserT, parser<self_t> > base_t;
91 typedef ActionT predicate_t;
92
93 template <typename ScannerT>
94 struct result
95 {
96 typedef typename parser_result<ParserT, ScannerT>::type type;
97 };
98
99 action(ParserT const& p, ActionT const& a)
100 : base_t(p)
101 , actor(a) {}
102
103 template <typename ScannerT>
104 typename parser_result<self_t, ScannerT>::type
105 parse(ScannerT const& scan) const
106 {
107 typedef typename ScannerT::iterator_t iterator_t;
108 typedef typename parser_result<self_t, ScannerT>::type result_t;
109
110 scan.at_end(); // allow skipper to take effect
111 iterator_t save = scan.first;
112 result_t hit = this->subject().parse(scan);
113 if (hit)
114 {
115 typename result_t::return_t val = hit.value();
116 scan.do_action(actor, val, save, scan.first);
117 }
118 return hit;
119 }
120
121 ActionT const& predicate() const { return actor; }
122
123 private:
124
125 ActionT actor;
126 };
127
128 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
129 #pragma warning(pop)
130 #endif
131
132 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
133
134 }} // namespace BOOST_SPIRIT_CLASSIC_NS
135
136 #endif