]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/qi/nonterminal/debug_handler.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / qi / nonterminal / debug_handler.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
8 #define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
9
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13
14 #include <boost/spirit/home/support/unused.hpp>
15 #include <boost/spirit/home/qi/nonterminal/rule.hpp>
16 #include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
17 #include <boost/spirit/home/qi/detail/expectation_failure.hpp>
18 #include <boost/function.hpp>
19 #include <boost/fusion/include/at.hpp>
20 #include <boost/fusion/include/vector.hpp>
21 #include <boost/fusion/include/out.hpp>
22 #include <iostream>
23
24 namespace boost { namespace spirit { namespace qi
25 {
26 template <
27 typename Iterator, typename Context
28 , typename Skipper, typename F>
29 struct debug_handler
30 {
31 typedef function<
32 bool(Iterator& first, Iterator const& last
33 , Context& context
34 , Skipper const& skipper
35 )>
36 function_type;
37
38 debug_handler(
39 function_type subject_
40 , F f_
41 , std::string const& rule_name_)
42 : subject(subject_)
43 , f(f_)
44 , rule_name(rule_name_)
45 {
46 }
47
48 bool operator()(
49 Iterator& first, Iterator const& last
50 , Context& context, Skipper const& skipper) const
51 {
52 f(first, last, context, pre_parse, rule_name);
53 try // subject might throw an exception
54 {
55 if (subject(first, last, context, skipper))
56 {
57 f(first, last, context, successful_parse, rule_name);
58 return true;
59 }
60 f(first, last, context, failed_parse, rule_name);
61 }
62 catch (expectation_failure<Iterator> const& e)
63 {
64 f(first, last, context, failed_parse, rule_name);
65 boost::throw_exception(e);
66 }
67 return false;
68 }
69
70 function_type subject;
71 F f;
72 std::string rule_name;
73 };
74
75 template <typename Iterator
76 , typename T1, typename T2, typename T3, typename T4, typename F>
77 void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
78 {
79 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
80
81 typedef
82 debug_handler<
83 Iterator
84 , typename rule_type::context_type
85 , typename rule_type::skipper_type
86 , F>
87 debug_handler;
88 r.f = debug_handler(r.f, f, r.name());
89 }
90
91 struct simple_trace;
92
93 namespace detail
94 {
95 // This class provides an extra level of indirection through a
96 // template to produce the simple_trace type. This way, the use
97 // of simple_trace below is hidden behind a dependent type, so
98 // that compilers eagerly type-checking template definitions
99 // won't complain that simple_trace is incomplete.
100 template<typename T>
101 struct get_simple_trace
102 {
103 typedef simple_trace type;
104 };
105 }
106
107 template <typename Iterator
108 , typename T1, typename T2, typename T3, typename T4>
109 void debug(rule<Iterator, T1, T2, T3, T4>& r)
110 {
111 typedef rule<Iterator, T1, T2, T3, T4> rule_type;
112
113 typedef
114 debug_handler<
115 Iterator
116 , typename rule_type::context_type
117 , typename rule_type::skipper_type
118 , simple_trace>
119 debug_handler;
120
121 typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
122 r.f = debug_handler(r.f, trace(), r.name());
123 }
124
125 }}}
126
127 ///////////////////////////////////////////////////////////////////////////////
128 // Utility macro for easy enabling of rule and grammar debugging
129 #if !defined(BOOST_SPIRIT_DEBUG_NODE)
130 #if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
131 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
132 #else
133 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
134 #endif
135 #endif
136
137 #define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
138 BOOST_SPIRIT_DEBUG_NODE(name); \
139 /***/
140
141 #define BOOST_SPIRIT_DEBUG_NODES(seq) \
142 BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
143 /***/
144
145 #endif