1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3     Copyright (c) 2001-2011 Hartmut Kaiser
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 #if !defined(BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)
9 #define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
10 
11 #include <boost/mpl/if.hpp>
12 #include <boost/mpl/and.hpp>
13 #include <boost/type_traits/is_convertible.hpp>
14 #include <cctype>
15 
16 namespace boost { namespace spirit { namespace x3 { namespace traits
17 {
18     ///////////////////////////////////////////////////////////////////////////
19     // generate debug output for lookahead token (character) stream
20     namespace detail
21     {
22         struct token_printer_debug_for_chars
23         {
24             template<typename Out, typename Char>
printboost::spirit::x3::traits::detail::token_printer_debug_for_chars25             static void print(Out& o, Char c)
26             {
27                 using namespace std;    // allow for ADL to find the proper iscntrl
28 
29                 switch (c)
30                 {
31                     case '\a': o << "\\a"; break;
32                     case '\b': o << "\\b"; break;
33                     case '\f': o << "\\f"; break;
34                     case '\n': o << "\\n"; break;
35                     case '\r': o << "\\r"; break;
36                     case '\t': o << "\\t"; break;
37                     case '\v': o << "\\v"; break;
38                     default:
39                         if (c >= 0 && c < 127 && iscntrl(c))
40                             o << "\\" << std::oct << int(c);
41                         else
42                             o << Char(c);
43                 }
44             }
45         };
46 
47         // for token types where the comparison with char constants wouldn't work
48         struct token_printer_debug
49         {
50             template<typename Out, typename T>
printboost::spirit::x3::traits::detail::token_printer_debug51             static void print(Out& o, T const& val)
52             {
53                 o << val;
54             }
55         };
56     }
57 
58     template <typename T, typename Enable = void>
59     struct token_printer_debug
60       : mpl::if_<
61             mpl::and_<
62                 is_convertible<T, char>, is_convertible<char, T> >
63           , detail::token_printer_debug_for_chars
64           , detail::token_printer_debug>::type
65     {};
66 
67     template <typename Out, typename T>
print_token(Out & out,T const & val)68     inline void print_token(Out& out, T const& val)
69     {
70         // allow to customize the token printer routine
71         token_printer_debug<T>::print(out, val);
72     }
73 }}}}
74 
75 #endif
76