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

source code of boost/libs/spirit/example/karma/basic_facilities.cpp