Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM) Chris@16: #define BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: // info provides information about a component. Each component Chris@16: // has a what member function that returns an info object. Chris@16: // strings in the info object are assumed to be encoded as UTF8 Chris@16: // for uniformity. Chris@16: struct info Chris@16: { Chris@101: struct nil_ {}; Chris@16: Chris@16: typedef Chris@16: boost::variant< Chris@101: nil_ Chris@16: , utf8_string Chris@16: , recursive_wrapper Chris@16: , recursive_wrapper > Chris@16: , recursive_wrapper > Chris@16: > Chris@16: value_type; Chris@16: Chris@16: explicit info(utf8_string const& tag_) Chris@101: : tag(tag_), value(nil_()) {} Chris@16: Chris@16: template Chris@16: info(utf8_string const& tag_, T const& value_) Chris@16: : tag(tag_), value(value_) {} Chris@16: Chris@16: info(utf8_string const& tag_, char value_) Chris@16: : tag(tag_), value(utf8_string(1, value_)) {} Chris@16: Chris@16: info(utf8_string const& tag_, wchar_t value_) Chris@16: : tag(tag_), value(to_utf8(value_)) {} Chris@16: Chris@16: info(utf8_string const& tag_, ucs4_char value_) Chris@16: : tag(tag_), value(to_utf8(value_)) {} Chris@16: Chris@16: template Chris@16: info(utf8_string const& tag_, Char const* str) Chris@16: : tag(tag_), value(to_utf8(str)) {} Chris@16: Chris@16: template Chris@16: info(utf8_string const& tag_ Chris@16: , std::basic_string const& str) Chris@16: : tag(tag_), value(to_utf8(str)) {} Chris@16: Chris@16: utf8_string tag; Chris@16: value_type value; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct basic_info_walker Chris@16: { Chris@16: typedef void result_type; Chris@16: typedef basic_info_walker this_type; Chris@16: Chris@16: basic_info_walker(Callback& callback_, utf8_string const& tag_, int depth_) Chris@16: : callback(callback_), tag(tag_), depth(depth_) {} Chris@16: Chris@101: void operator()(info::nil_) const Chris@16: { Chris@16: callback.element(tag, "", depth); Chris@16: } Chris@16: Chris@16: void operator()(utf8_string const& str) const Chris@16: { Chris@16: callback.element(tag, str, depth); Chris@16: } Chris@16: Chris@16: void operator()(info const& what) const Chris@16: { Chris@16: boost::apply_visitor( Chris@16: this_type(callback, what.tag, depth+1), what.value); Chris@16: } Chris@16: Chris@16: void operator()(std::pair const& pair) const Chris@16: { Chris@16: callback.element(tag, "", depth); Chris@16: boost::apply_visitor( Chris@16: this_type(callback, pair.first.tag, depth+1), pair.first.value); Chris@16: boost::apply_visitor( Chris@16: this_type(callback, pair.second.tag, depth+1), pair.second.value); Chris@16: } Chris@16: Chris@16: void operator()(std::list const& l) const Chris@16: { Chris@16: callback.element(tag, "", depth); Chris@16: BOOST_FOREACH(info const& what, l) Chris@16: { Chris@16: boost::apply_visitor( Chris@16: this_type(callback, what.tag, depth+1), what.value); Chris@16: } Chris@16: } Chris@16: Chris@16: Callback& callback; Chris@16: utf8_string const& tag; Chris@16: int depth; Chris@16: Chris@16: private: Chris@16: // silence MSVC warning C4512: assignment operator could not be generated Chris@16: basic_info_walker& operator= (basic_info_walker const&); Chris@16: }; Chris@16: Chris@16: // bare-bones print support Chris@16: template Chris@16: struct simple_printer Chris@16: { Chris@16: typedef utf8_string string; Chris@16: Chris@16: simple_printer(Out& out_) Chris@16: : out(out_) {} Chris@16: Chris@16: void element(string const& tag, string const& value, int /*depth*/) const Chris@16: { Chris@16: if (value == "") Chris@16: out << '<' << tag << '>'; Chris@16: else Chris@16: out << '"' << value << '"'; Chris@16: } Chris@16: Chris@16: Out& out; Chris@16: Chris@16: private: Chris@16: // silence MSVC warning C4512: assignment operator could not be generated Chris@16: simple_printer& operator= (simple_printer const&); Chris@16: }; Chris@16: Chris@16: template Chris@16: Out& operator<<(Out& out, info const& what) Chris@16: { Chris@16: simple_printer pr(out); Chris@16: basic_info_walker > walker(pr, what.tag, 0); Chris@16: boost::apply_visitor(walker, what.value); Chris@16: return out; Chris@16: } Chris@16: }} Chris@16: Chris@16: #endif