• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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