auto_facilities.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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. // The main purpose of this example is to show the uniform and easy way of
  6. // output formatting for different container types.
  7. //
  8. // The 'auto_' primitive used below is very similar to the 'stream' primitive
  9. // demonstrated in the example 'basic_facilities.cpp' as it allows to generate
  10. // output from a multitude of data types. The main difference is that it is
  11. // mapped to the correct Karma generator instead of using any available
  12. // operator<<() for the contained data type. Additionally this means, that
  13. // the format descriptions used below will be usable for any contained type as
  14. // long as this type has a defined mapping to a Karma generator.
  15. // use a larger value for the alignment field width (default is 10)
  16. #define BOOST_KARMA_DEFAULT_FIELD_LENGTH 25
  17. #include <boost/config/warning_disable.hpp>
  18. #include <iostream>
  19. #include <string>
  20. #include <vector>
  21. #include <list>
  22. #include <map>
  23. #include <algorithm>
  24. #include <cstdlib>
  25. #include <boost/range.hpp>
  26. #include <boost/array.hpp>
  27. #include <boost/fusion/include/std_pair.hpp>
  28. #include <boost/fusion/include/array.hpp>
  29. #include <boost/spirit/include/karma.hpp>
  30. using namespace boost::spirit;
  31. using namespace boost::spirit::ascii;
  32. ///////////////////////////////////////////////////////////////////////////////
  33. namespace boost { namespace spirit { namespace traits
  34. {
  35. // We add a specialization for the create_generator customization point
  36. // defining a custom output format for the value type of the std::map used
  37. // below (std::pair<int const, std::string>). Generally, any specialization
  38. // for create_generator is expected to return the proto expression to be
  39. // used to generate output for the type the customization point has been
  40. // specialized for.
  41. //
  42. // We need to utilize proto::deep_copy as the expression contains a literal
  43. // (the ':') which normally gets embedded in the proto expression by
  44. // reference only. The deep copy converts the proto tree to hold this by
  45. // value. The deep copy operation can be left out for simpler proto
  46. // expressions (not containing references to temporaries). Alternatively
  47. // you could use the proto::make_expr() facility to build the required
  48. // proto expression.
  49. template <>
  50. struct create_generator<std::pair<int const, std::string> >
  51. {
  52. typedef proto::result_of::deep_copy<
  53. BOOST_TYPEOF(int_ << ':' << string)
  54. >::type type;
  55. static type call()
  56. {
  57. return proto::deep_copy(int_ << ':' << string);
  58. }
  59. };
  60. }}}
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // Output the given containers in list format
  63. // Note: the format description does not depend on the type of the sequence
  64. // nor does it depend on the type of the elements contained in the
  65. // sequence
  66. ///////////////////////////////////////////////////////////////////////////////
  67. template <typename Container>
  68. void output_container(std::ostream& os, Container const& c)
  69. {
  70. // output the container as a sequence without separators
  71. os <<
  72. karma::format(
  73. auto_, // format description
  74. c // data
  75. ) << std::endl << std::endl;
  76. os <<
  77. karma::format(
  78. *auto_, // format description
  79. c // data
  80. ) << std::endl << std::endl;
  81. // output the container as a space separated sequence
  82. os <<
  83. karma::format_delimited(
  84. auto_, // format description
  85. space, // delimiter
  86. c // data
  87. ) << std::endl << std::endl;
  88. os <<
  89. karma::format_delimited(
  90. *auto_, // format description
  91. space, // delimiter
  92. c // data
  93. ) << std::endl << std::endl;
  94. os <<
  95. karma::format_delimited(
  96. '[' << *auto_ << ']', // format description
  97. space, // delimiter
  98. c // data
  99. ) << std::endl << std::endl;
  100. // output the container as a comma separated list
  101. os <<
  102. karma::format(
  103. auto_ % ", ", // format description
  104. c // data
  105. ) << std::endl << std::endl;
  106. os <<
  107. karma::format(
  108. '[' << (auto_ % ", ") << ']', // format description
  109. c // data
  110. ) << std::endl << std::endl;
  111. os <<
  112. karma::format(
  113. '[' << -(auto_ % ", ") << ']', // format description
  114. c // data
  115. ) << std::endl << std::endl;
  116. os <<
  117. karma::format(
  118. '[' << (+auto_ | "empty") << ']', // format description
  119. c // data
  120. ) << std::endl << std::endl;
  121. // output the container as a comma separated list of items enclosed in '()'
  122. os <<
  123. karma::format(
  124. ('(' << auto_ << ')') % ", ", // format description
  125. c // data
  126. ) << std::endl << std::endl;
  127. os <<
  128. karma::format(
  129. '[' << (
  130. ('(' << auto_ << ')') % ", "
  131. ) << ']', // format description
  132. c // data
  133. ) << std::endl << std::endl;
  134. // output the container as a HTML list
  135. os <<
  136. karma::format_delimited(
  137. "<ol>" <<
  138. *verbatim["<li>" << auto_ << "</li>"]
  139. << "</ol>", // format description
  140. '\n', // delimiter
  141. c // data
  142. ) << std::endl;
  143. // output the container as right aligned column
  144. os <<
  145. karma::format_delimited(
  146. *verbatim[
  147. "|" << right_align[auto_] << "|"
  148. ], // format description
  149. '\n', // delimiter
  150. c // data
  151. ) << std::endl;
  152. os << std::endl;
  153. }
  154. int main()
  155. {
  156. ///////////////////////////////////////////////////////////////////////////
  157. // C-style array
  158. int i[4] = { 3, 6, 9, 12 };
  159. std::cout << "-------------------------------------------------------------"
  160. << std::endl;
  161. std::cout << "int i[]" << std::endl;
  162. output_container(std::cout, boost::make_iterator_range(i, i+4));
  163. ///////////////////////////////////////////////////////////////////////////
  164. // vector
  165. std::vector<int> v (5);
  166. std::generate(v.begin(), v.end(), std::rand); // randomly fill the vector
  167. std::cout << "-------------------------------------------------------------"
  168. << std::endl;
  169. std::cout << "std::vector<int>" << std::endl;
  170. output_container(std::cout, v);
  171. ///////////////////////////////////////////////////////////////////////////
  172. // list
  173. std::list<char> l;
  174. l.push_back('A');
  175. l.push_back('B');
  176. l.push_back('C');
  177. std::cout << "-------------------------------------------------------------"
  178. << std::endl;
  179. std::cout << "std::list<char>" << std::endl;
  180. output_container(std::cout, l);
  181. ///////////////////////////////////////////////////////////////////////////
  182. // strings
  183. std::string str("Hello world!");
  184. std::cout << "-------------------------------------------------------------"
  185. << std::endl;
  186. std::cout << "std::string" << std::endl;
  187. output_container(std::cout, str);
  188. ///////////////////////////////////////////////////////////////////////////
  189. // boost::array
  190. boost::array<long, 5> arr;
  191. std::generate(arr.begin(), arr.end(), std::rand); // randomly fill the array
  192. std::cout << "-------------------------------------------------------------"
  193. << std::endl;
  194. std::cout << "boost::array<long, 5>" << std::endl;
  195. output_container(std::cout, arr);
  196. ///////////////////////////////////////////////////////////////////////////
  197. // map of int --> string mappings
  198. std::map<int, std::string> mappings;
  199. mappings.insert(std::make_pair(0, "zero"));
  200. mappings.insert(std::make_pair(1, "one"));
  201. mappings.insert(std::make_pair(2, "two"));
  202. std::cout << "-------------------------------------------------------------"
  203. << std::endl;
  204. std::cout << "std::map<int, std::string>" << std::endl;
  205. output_container(std::cout, mappings);
  206. return 0;
  207. }