]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/spirit/home/support/info.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / spirit / home / support / info.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3
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)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM)
8 #define BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM
9
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13
14 #include <boost/variant/variant.hpp>
15 #include <boost/variant/recursive_variant.hpp>
16 #include <boost/variant/apply_visitor.hpp>
17 #include <boost/foreach.hpp>
18 #include <boost/spirit/home/support/utf8.hpp>
19 #include <list>
20 #include <iterator>
21 #include <utility>
22
23 namespace boost { namespace spirit
24 {
25     // info provides information about a component. Each component
26     // has a what member function that returns an info object.
27     // strings in the info object are assumed to be encoded as UTF8
28     // for uniformity.
29     struct info
30     {
31         struct nil {};
32
33         typedef
34             boost::variant<
35                 nil
36               , utf8_string
37               , recursive_wrapper<info>
38               , recursive_wrapper<std::pair<info, info> >
39               , std::list<info>
40             >
41         value_type;
42
43         explicit info(utf8_string const& tag)
44           : tag(tag), value(nil()) {}
45
46         template <typename T>
47         info(utf8_string const& tag, T const& value)
48           : tag(tag), value(value) {}
49
50         info(utf8_string const& tag, char value)
51           : tag(tag), value(utf8_string(1, value)) {}
52
53         info(utf8_string const& tag, wchar_t value)
54           : tag(tag), value(to_utf8(value)) {}
55
56         info(utf8_string const& tag, ucs4_char value)
57           : tag(tag), value(to_utf8(value)) {}
58
59         template <typename Char>
60         info(utf8_string const& tag, Char const* str)
61           : tag(tag), value(to_utf8(str)) {}
62
63         template <typename Char, typename Traits, typename Allocator>
64         info(utf8_string const& tag
65               , std::basic_string<Char, Traits, Allocator> const& str)
66           : tag(tag), value(to_utf8(str)) {}
67
68         utf8_string tag;
69         value_type value;
70     };
71
72     template <typename Callback>
73     struct basic_info_walker
74     {
75         typedef void result_type;
76         typedef basic_info_walker<Callback> this_type;
77
78         basic_info_walker(Callback& callback, utf8_string const& tag, int depth)
79           : callback(callback), tag(tag), depth(depth) {}
80
81         void operator()(info::nil) const
82         {
83             callback.element(tag, "", depth);
84         }
85
86         void operator()(utf8_string const& str) const
87         {
88             callback.element(tag, str, depth);
89         }
90
91         void operator()(info const& what) const
92         {
93             boost::apply_visitor(
94                 this_type(callback, what.tag, depth+1), what.value);
95         }
96
97         void operator()(std::pair<info, info> const& pair) const
98         {
99             callback.element(tag, "", depth);
100             boost::apply_visitor(
101                 this_type(callback, pair.first.tag, depth+1), pair.first.value);
102             boost::apply_visitor(
103                 this_type(callback, pair.second.tag, depth+1), pair.second.value);
104         }
105
106         void operator()(std::list<info> const& l) const
107         {
108             callback.element(tag, "", depth);
109             BOOST_FOREACH(info const& what, l)
110             {
111                 boost::apply_visitor(
112                     this_type(callback, what.tag, depth+1), what.value);
113             }
114         }
115
116         Callback& callback;
117         utf8_string const& tag;
118         int depth;
119
120     private:
121         // silence MSVC warning C4512: assignment operator could not be generated
122         basic_info_walker& operator= (basic_info_walker const&);
123     };
124
125     // bare-bones print support
126     template <typename Out>
127     struct simple_printer
128     {
129         typedef utf8_string string;
130
131         simple_printer(Out& out)
132           : out(out) {}
133
134         void element(string const& tag, string const& value, int /*depth*/) const
135         {
136             if (value == "")
137                 out << '<' << tag << '>';
138             else
139                 out << '"' << value << '"';
140         }
141
142         Out& out;
143
144     private:
145         // silence MSVC warning C4512: assignment operator could not be generated
146         simple_printer& operator= (simple_printer const&);
147     };
148
149     template <typename Out>
150     Out& operator<<(Out& out, info const& what)
151     {
152         simple_printer<Out> pr(out);
153         basic_info_walker<simple_printer<Out> > walker(pr, what.tag, 0);
154         boost::apply_visitor(walker, what.value);
155         return out;
156     }
157 }}
158
159 #endif