1 // Copyright (c) 2001-2011 Hartmut Kaiser
2 // Copyright (c) 2001-2011 Joel de Guzman
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)
7 #if !defined(BOOST_SPIRIT_KARMA_DEBUG_HANDLER_APR_21_2010_0148PM)
8 #define BOOST_SPIRIT_KARMA_DEBUG_HANDLER_APR_21_2010_0148PM
14 #include <boost/spirit/home/support/unused.hpp>
15 #include <boost/spirit/home/karma/nonterminal/rule.hpp>
16 #include <boost/spirit/home/karma/nonterminal/debug_handler_state.hpp>
17 #include <boost/function.hpp>
18 #include <boost/fusion/include/at.hpp>
19 #include <boost/fusion/include/vector.hpp>
20 #include <boost/fusion/include/out.hpp>
23 namespace boost { namespace spirit { namespace karma
26 typename OutputIterator, typename Context, typename Delimiter
27 , typename Properties, typename F>
30 typedef detail::output_iterator<OutputIterator, Properties>
32 typedef detail::enable_buffering<output_iterator> buffer_type;
34 typedef function<bool(output_iterator&, Context&, Delimiter const&)>
37 debug_handler(function_type subject, F f, std::string const& rule_name)
40 , rule_name(rule_name)
43 bool operator()(output_iterator& sink, Context& context
44 , Delimiter const& delim) const
46 buffer_type buffer(sink);
49 f (sink, context, pre_generate, rule_name, buffer);
51 detail::disable_counting<output_iterator> nocount(sink);
52 r = subject(sink, context, delim);
57 f (sink, context, successful_generate, rule_name, buffer);
61 f (sink, context, failed_generate, rule_name, buffer);
65 function_type subject;
67 std::string rule_name;
70 template <typename OutputIterator
71 , typename T1, typename T2, typename T3, typename T4, typename F>
72 void debug(rule<OutputIterator, T1, T2, T3, T4>& r, F f)
74 typedef rule<OutputIterator, T1, T2, T3, T4> rule_type;
79 , typename rule_type::context_type
80 , typename rule_type::delimiter_type
81 , typename rule_type::properties
84 r.f = debug_handler(r.f, f, r.name());
91 // This class provides an extra level of indirection through a
92 // template to produce the simple_trace type. This way, the use
93 // of simple_trace below is hidden behind a dependent type, so
94 // that compilers eagerly type-checking template definitions
95 // won't complain that simple_trace is incomplete.
97 struct get_simple_trace
99 typedef simple_trace type;
103 template <typename OutputIterator
104 , typename T1, typename T2, typename T3, typename T4>
105 void debug(rule<OutputIterator, T1, T2, T3, T4>& r)
107 typedef rule<OutputIterator, T1, T2, T3, T4> rule_type;
112 , typename rule_type::context_type
113 , typename rule_type::delimiter_type
114 , typename rule_type::properties
117 typedef typename karma::detail::get_simple_trace<OutputIterator>::type
119 r.f = debug_handler(r.f, trace(), r.name());
124 ///////////////////////////////////////////////////////////////////////////////
125 // Utility macro for easy enabling of rule and grammar debugging
126 #if !defined(BOOST_SPIRIT_DEBUG_NODE)
127 #if defined(BOOST_SPIRIT_KARMA_DEBUG)
128 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
130 #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r);