customize_counter.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Hartmut Kaiser
  3. http://spirit.sourceforge.net/
  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. #include <boost/config/warning_disable.hpp>
  8. //[customize_karma_counter_includes
  9. #include <boost/spirit/include/karma.hpp>
  10. #include <iostream>
  11. #include <vector>
  12. //]
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //[customize_karma_counter_data
  15. namespace client
  16. {
  17. struct counter
  18. {
  19. // expose the current value of the counter as our iterator
  20. typedef int iterator;
  21. // expose 'int' as the type of each generated element
  22. typedef int type;
  23. counter(int max_count)
  24. : counter_(0), max_count_(max_count)
  25. {}
  26. int counter_;
  27. int max_count_;
  28. };
  29. }
  30. //]
  31. //[customize_karma_counter_traits
  32. // All specializations of attribute customization points have to be placed into
  33. // the namespace boost::spirit::traits.
  34. //
  35. // Note that all templates below are specialized using the 'const' type.
  36. // This is necessary as all attributes in Karma are 'const'.
  37. namespace boost { namespace spirit { namespace traits
  38. {
  39. // The specialization of the template 'is_container<>' will tell the
  40. // library to treat the type 'client::counter' as a container providing
  41. // the items to generate output from.
  42. template <>
  43. struct is_container<client::counter const>
  44. : mpl::true_
  45. {};
  46. // The specialization of the template 'container_iterator<>' will be
  47. // invoked by the library to evaluate the iterator type to be used
  48. // for iterating the data elements in the container.
  49. template <>
  50. struct container_iterator<client::counter const>
  51. {
  52. typedef client::counter::iterator type;
  53. };
  54. // The specialization of the templates 'begin_container<>' and
  55. // 'end_container<>' below will be used by the library to get the iterators
  56. // pointing to the begin and the end of the data to generate output from.
  57. // These specializations respectively return the initial and maximum
  58. // counter values.
  59. //
  60. // The passed argument refers to the attribute instance passed to the list
  61. // generator.
  62. template <>
  63. struct begin_container<client::counter const>
  64. {
  65. static client::counter::iterator
  66. call(client::counter const& c)
  67. {
  68. return c.counter_;
  69. }
  70. };
  71. template <>
  72. struct end_container<client::counter const>
  73. {
  74. static client::counter::iterator
  75. call(client::counter const& c)
  76. {
  77. return c.max_count_;
  78. }
  79. };
  80. }}}
  81. //]
  82. //[customize_karma_counter_iterator_traits
  83. // All specializations of attribute customization points have to be placed into
  84. // the namespace boost::spirit::traits.
  85. namespace boost { namespace spirit { namespace traits
  86. {
  87. // The specialization of the template 'deref_iterator<>' will be used to
  88. // dereference the iterator associated with our counter data structure.
  89. // Since we expose the current value as the iterator we just return the
  90. // current iterator as the return value.
  91. template <>
  92. struct deref_iterator<client::counter::iterator>
  93. {
  94. typedef client::counter::type type;
  95. static type call(client::counter::iterator const& it)
  96. {
  97. return it;
  98. }
  99. };
  100. }}}
  101. //]
  102. ///////////////////////////////////////////////////////////////////////////////
  103. namespace karma = boost::spirit::karma;
  104. int main()
  105. {
  106. //[customize_karma_counter
  107. // use the instance of a 'client::counter' instead of a STL vector
  108. client::counter count(4);
  109. std::cout << karma::format(karma::int_ % ", ", count) << std::endl; // prints: '0, 1, 2, 3'
  110. //]
  111. return 0;
  112. }