File indexing completed on 2025-12-15 10:08:59
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM)
0008 #define BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM
0009
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013
0014 #include <boost/variant/variant.hpp>
0015 #include <boost/variant/recursive_variant.hpp>
0016 #include <boost/variant/apply_visitor.hpp>
0017 #include <boost/spirit/home/support/utf8.hpp>
0018 #include <list>
0019 #include <iterator>
0020 #include <utility>
0021
0022 namespace boost { namespace spirit
0023 {
0024
0025
0026
0027
0028 struct info
0029 {
0030 struct nil_ {};
0031
0032 typedef
0033 boost::variant<
0034 nil_
0035 , utf8_string
0036 , recursive_wrapper<info>
0037 , recursive_wrapper<std::pair<info, info> >
0038 , recursive_wrapper<std::list<info> >
0039 >
0040 value_type;
0041
0042 explicit info(utf8_string const& tag_)
0043 : tag(tag_), value(nil_()) {}
0044
0045 template <typename T>
0046 info(utf8_string const& tag_, T const& value_)
0047 : tag(tag_), value(value_) {}
0048
0049 info(utf8_string const& tag_, char value_)
0050 : tag(tag_), value(utf8_string(1, value_)) {}
0051
0052 info(utf8_string const& tag_, wchar_t value_)
0053 : tag(tag_), value(to_utf8(value_)) {}
0054
0055 info(utf8_string const& tag_, ucs4_char value_)
0056 : tag(tag_), value(to_utf8(value_)) {}
0057
0058 template <typename Char>
0059 info(utf8_string const& tag_, Char const* str)
0060 : tag(tag_), value(to_utf8(str)) {}
0061
0062 template <typename Char, typename Traits, typename Allocator>
0063 info(utf8_string const& tag_
0064 , std::basic_string<Char, Traits, Allocator> const& str)
0065 : tag(tag_), value(to_utf8(str)) {}
0066
0067 utf8_string tag;
0068 value_type value;
0069 };
0070
0071 #ifdef _MSC_VER
0072 # pragma warning(push)
0073 # pragma warning(disable: 4512)
0074 #endif
0075 template <typename Callback>
0076 struct basic_info_walker
0077 {
0078 typedef void result_type;
0079 typedef basic_info_walker<Callback> this_type;
0080
0081 basic_info_walker(Callback& callback_, utf8_string const& tag_, int depth_)
0082 : callback(callback_), tag(tag_), depth(depth_) {}
0083
0084 void operator()(info::nil_) const
0085 {
0086 callback.element(tag, "", depth);
0087 }
0088
0089 void operator()(utf8_string const& str) const
0090 {
0091 callback.element(tag, str, depth);
0092 }
0093
0094 void operator()(info const& what) const
0095 {
0096 boost::apply_visitor(
0097 this_type(callback, what.tag, depth+1), what.value);
0098 }
0099
0100 void operator()(std::pair<info, info> const& pair) const
0101 {
0102 callback.element(tag, "", depth);
0103 boost::apply_visitor(
0104 this_type(callback, pair.first.tag, depth+1), pair.first.value);
0105 boost::apply_visitor(
0106 this_type(callback, pair.second.tag, depth+1), pair.second.value);
0107 }
0108
0109 void operator()(std::list<info> const& l) const
0110 {
0111 callback.element(tag, "", depth);
0112 for (std::list<info>::const_iterator it = l.begin(),
0113 end = l.end(); it != end; ++it)
0114 {
0115 boost::apply_visitor(
0116 this_type(callback, it->tag, depth+1), it->value);
0117 }
0118 }
0119
0120 Callback& callback;
0121 utf8_string const& tag;
0122 int depth;
0123 };
0124
0125
0126 template <typename Out>
0127 struct simple_printer
0128 {
0129 typedef utf8_string string;
0130
0131 simple_printer(Out& out_)
0132 : out(out_) {}
0133
0134 void element(string const& tag, string const& value, int ) const
0135 {
0136 if (value.empty())
0137 out << '<' << tag << '>';
0138 else
0139 out << '"' << value << '"';
0140 }
0141
0142 Out& out;
0143 };
0144 #ifdef _MSC_VER
0145 # pragma warning(pop)
0146 #endif
0147
0148 template <typename Out>
0149 Out& operator<<(Out& out, info const& what)
0150 {
0151 simple_printer<Out> pr(out);
0152 basic_info_walker<simple_printer<Out> > walker(pr, what.tag, 0);
0153 boost::apply_visitor(walker, what.value);
0154 return out;
0155 }
0156 }}
0157
0158 #endif