File indexing completed on 2025-01-31 10:02:38
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
0009 #define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
0010
0011 #include <boost/variant.hpp>
0012 #include <boost/optional/optional.hpp>
0013 #include <boost/fusion/include/is_sequence.hpp>
0014 #include <boost/fusion/include/for_each.hpp>
0015 #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
0016 #include <boost/spirit/home/x3/support/traits/is_variant.hpp>
0017 #ifdef BOOST_SPIRIT_X3_UNICODE
0018 # include <boost/spirit/home/support/char_encoding/unicode.hpp>
0019 #endif
0020
0021 namespace boost { namespace spirit { namespace x3 { namespace traits
0022 {
0023 template <typename Out, typename T>
0024 void print_attribute(Out& out, T const& val);
0025
0026 template <typename Out>
0027 inline void print_attribute(Out&, unused_type) {}
0028
0029
0030 namespace detail
0031 {
0032 template <typename Out>
0033 struct print_fusion_sequence
0034 {
0035 print_fusion_sequence(Out& out)
0036 : out(out), is_first(true) {}
0037
0038 typedef void result_type;
0039
0040 template <typename T>
0041 void operator()(T const& val) const
0042 {
0043 if (is_first)
0044 is_first = false;
0045 else
0046 out << ", ";
0047 x3::traits::print_attribute(out, val);
0048 }
0049
0050 Out& out;
0051 mutable bool is_first;
0052 };
0053
0054
0055 template <typename Out>
0056 struct print_visitor : static_visitor<>
0057 {
0058 print_visitor(Out& out) : out(out) {}
0059
0060 template <typename T>
0061 void operator()(T const& val) const
0062 {
0063 x3::traits::print_attribute(out, val);
0064 }
0065
0066 Out& out;
0067 };
0068 }
0069
0070 template <typename Out, typename T, typename Enable = void>
0071 struct print_attribute_debug
0072 {
0073
0074 static void call(Out& out, unused_type, unused_attribute)
0075 {
0076 out << "unused";
0077 }
0078
0079
0080 template <typename T_>
0081 static void call(Out& out, T_ const& val, plain_attribute)
0082 {
0083 out << val;
0084 }
0085
0086 #ifdef BOOST_SPIRIT_X3_UNICODE
0087 static void call(Out& out, char_encoding::unicode::char_type val, plain_attribute)
0088 {
0089 if (val >= 0 && val < 127)
0090 {
0091 if (iscntrl(val))
0092 out << "\\" << std::oct << int(val) << std::dec;
0093 else if (isprint(val))
0094 out << char(val);
0095 else
0096 out << "\\x" << std::hex << int(val) << std::dec;
0097 }
0098 else
0099 out << "\\x" << std::hex << int(val) << std::dec;
0100 }
0101
0102 static void call(Out& out, char val, plain_attribute tag)
0103 {
0104 call(out, static_cast<char_encoding::unicode::char_type>(val), tag);
0105 }
0106 #endif
0107
0108
0109 template <typename T_>
0110 static void call(Out& out, T_ const& val, tuple_attribute)
0111 {
0112 out << '[';
0113 fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
0114 out << ']';
0115 }
0116
0117
0118 template <typename T_>
0119 static void call(Out& out, T_ const& val, container_attribute)
0120 {
0121 out << '[';
0122 if (!traits::is_empty(val))
0123 {
0124 bool first = true;
0125 typename container_iterator<T_ const>::type iend = traits::end(val);
0126 for (typename container_iterator<T_ const>::type i = traits::begin(val);
0127 !traits::compare(i, iend); traits::next(i))
0128 {
0129 if (!first)
0130 out << ", ";
0131 first = false;
0132 x3::traits::print_attribute(out, traits::deref(i));
0133 }
0134 }
0135 out << ']';
0136 }
0137
0138
0139 template <typename T_>
0140 static void call(Out& out, T_ const& val, variant_attribute)
0141 {
0142 apply_visitor(detail::print_visitor<Out>(out), val);
0143 }
0144
0145
0146 template <typename T_>
0147 static void call(Out& out, T_ const& val, optional_attribute)
0148 {
0149 if (val)
0150 x3::traits::print_attribute(out, *val);
0151 else
0152 out << "[empty]";
0153 }
0154
0155
0156 static void call(Out& out, T const& val)
0157 {
0158 call(out, val, typename attribute_category<T>::type());
0159 }
0160 };
0161
0162
0163 template <typename Out, typename T>
0164 inline void print_attribute(Out& out, T const& val)
0165 {
0166 print_attribute_debug<Out, T>::call(out, val);
0167 }
0168 }}}}
0169
0170 #endif