1 // Copyright (c) 2001-2010 Hartmut Kaiser
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 // The main purpose of this example is to show the uniform and easy way of
7 // output formatting for different container types.
8 //
9 // Since the 'stream' primitive used below uses the streaming operator defined
10 // for the container value_type, you must make sure to have a corresponding
11 // operator<<() available for this contained data type. OTOH this means, that
12 // the format descriptions used below will be usable for any contained type as
13 // long as this type has an associated streaming operator defined.
14
15 // use a larger value for the alignment field width (default is 10)
16 #define BOOST_KARMA_DEFAULT_FIELD_LENGTH 25
17
18 #include <boost/config/warning_disable.hpp>
19
20 #include <iostream>
21 #include <string>
22 #include <vector>
23 #include <list>
24 #include <map>
25 #include <algorithm>
26 #include <cstdlib>
27
28 #include <boost/array.hpp>
29 #include <boost/date_time/gregorian/gregorian.hpp>
30 #include <boost/fusion/include/std_pair.hpp>
31 #include <boost/range/iterator_range.hpp>
32
33 ///////////////////////////////////////////////////////////////////////////////
34 // This streaming operator is needed to generate the output from the map below
35 // Yes, it's heresy, but this operator has to live in namespace std to be
36 // picked up by the compiler.
37 namespace std {
38 inline std::ostream&
operator <<(std::ostream & os,std::pair<int const,std::string> v)39 operator<<(std::ostream& os, std::pair<int const, std::string> v)
40 {
41 os << v.first << ": " << v.second;
42 return os;
43 }
44 }
45
46 #include <boost/spirit/include/karma.hpp>
47 #include <boost/spirit/include/karma_format.hpp>
48
49 using namespace boost::spirit;
50 using namespace boost::spirit::ascii;
51
52 ///////////////////////////////////////////////////////////////////////////////
53 // Output the given containers in list format
54 // Note: the format description does not depend on the type of the sequence
55 // nor does it depend on the type of the elements contained in the
56 // sequence
57 ///////////////////////////////////////////////////////////////////////////////
58 template <typename Container>
output_container(std::ostream & os,Container const & c)59 void output_container(std::ostream& os, Container const& c)
60 {
61 // output the container as a space separated sequence
62 os <<
63 karma::format(
64 *stream, // format description
65 c // data
66 ) << std::endl << std::endl;
67
68 // output the container as a space separated sequence
69 os <<
70 karma::format_delimited(
71 *stream, // format description
72 space, // delimiter
73 c // data
74 ) << std::endl << std::endl;
75
76 os <<
77 karma::format_delimited(
78 '[' << *stream << ']', // format description
79 space, // delimiter
80 c // data
81 ) << std::endl << std::endl;
82
83 // output the container as a comma separated list
84 os <<
85 karma::format(
86 stream % ", ", // format description
87 c // data
88 ) << std::endl << std::endl;
89
90 os <<
91 karma::format(
92 '[' << (stream % ", ") << ']', // format description
93 c // data
94 ) << std::endl << std::endl;
95
96 os <<
97 karma::format(
98 '[' << -(stream % ", ") << ']', // format description
99 c // data
100 ) << std::endl << std::endl;
101
102 os <<
103 karma::format(
104 '[' << (+stream | "empty") << ']', // format description
105 c // data
106 ) << std::endl << std::endl;
107
108 // output the container as a comma separated list of items enclosed in '()'
109 os <<
110 karma::format(
111 ('(' << stream << ')') % ", ", // format description
112 c // data
113 ) << std::endl << std::endl;
114
115 os <<
116 karma::format(
117 '[' << (
118 ('(' << stream << ')') % ", "
119 ) << ']', // format description
120 c // data
121 ) << std::endl << std::endl;
122
123 // output the container as a HTML list
124 os <<
125 karma::format_delimited(
126 "<ol>" <<
127 *verbatim["<li>" << stream << "</li>"]
128 << "</ol>", // format description
129 '\n', // delimiter
130 c // data
131 ) << std::endl;
132
133 // output the container as right aligned column
134 os <<
135 karma::format_delimited(
136 *verbatim[
137 "|" << right_align[stream] << "|"
138 ], // format description
139 '\n', // delimiter
140 c // data
141 ) << std::endl;
142
143 os << std::endl;
144 }
145
main()146 int main()
147 {
148 ///////////////////////////////////////////////////////////////////////////
149 // C-style array
150 int i[4] = { 3, 6, 9, 12 };
151
152 std::cout << "-------------------------------------------------------------"
153 << std::endl;
154 std::cout << "int i[]" << std::endl;
155 output_container(std::cout, boost::make_iterator_range(i, i+4));
156
157 ///////////////////////////////////////////////////////////////////////////
158 // vector
159 std::vector<int> v (5);
160 std::generate(v.begin(), v.end(), std::rand); // randomly fill the vector
161
162 std::cout << "-------------------------------------------------------------"
163 << std::endl;
164 std::cout << "std::vector<int>" << std::endl;
165 output_container(std::cout, v);
166
167 ///////////////////////////////////////////////////////////////////////////
168 // list
169 std::list<char> l;
170 l.push_back('A');
171 l.push_back('B');
172 l.push_back('C');
173
174 std::cout << "-------------------------------------------------------------"
175 << std::endl;
176 std::cout << "std::list<char>" << std::endl;
177 output_container(std::cout, l);
178
179 ///////////////////////////////////////////////////////////////////////////
180 // strings
181 std::string str("Hello world!");
182
183 std::cout << "-------------------------------------------------------------"
184 << std::endl;
185 std::cout << "std::string" << std::endl;
186 output_container(std::cout, str);
187
188 ///////////////////////////////////////////////////////////////////////////
189 // boost::array
190 boost::array<long, 5> arr;
191 std::generate(arr.begin(), arr.end(), std::rand); // randomly fill the array
192
193 std::cout << "-------------------------------------------------------------"
194 << std::endl;
195 std::cout << "boost::array<long, 5>" << std::endl;
196 output_container(std::cout, arr);
197
198 ///////////////////////////////////////////////////////////////////////////
199 // vector of boost::date objects
200 // Note: any registered facets get used!
201 using namespace boost::gregorian;
202 std::vector<date> dates;
203 dates.push_back(date(2005, Jun, 25));
204 dates.push_back(date(2006, Jan, 13));
205 dates.push_back(date(2007, May, 03));
206
207 date_facet* facet(new date_facet("%A %B %d, %Y"));
208 std::cout.imbue(std::locale(std::cout.getloc(), facet));
209
210 std::cout << "-------------------------------------------------------------"
211 << std::endl;
212 std::cout << "std::vector<boost::date>" << std::endl;
213 output_container(std::cout, dates);
214
215 ///////////////////////////////////////////////////////////////////////////
216 // map of int --> string mappings
217 std::map<int, std::string> mappings;
218 mappings.insert(std::make_pair(0, "zero"));
219 mappings.insert(std::make_pair(1, "one"));
220 mappings.insert(std::make_pair(2, "two"));
221
222 std::cout << "-------------------------------------------------------------"
223 << std::endl;
224 std::cout << "std::map<int, std::string>" << std::endl;
225 output_container(std::cout, mappings);
226
227 return 0;
228 }
229
230