customize_embedded_container.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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_embedded_container_includes
  9. #include <boost/spirit/include/karma.hpp>
  10. #include <iostream>
  11. #include <vector>
  12. //]
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //[customize_karma_embedded_container_data
  15. namespace client
  16. {
  17. struct embedded_container
  18. {
  19. // expose the iterator of the embedded vector as our iterator
  20. typedef std::vector<int>::const_iterator iterator;
  21. // expose the type of the held data elements as our type
  22. typedef std::vector<int>::value_type type;
  23. // this is the vector holding the actual elements we need to generate
  24. // output from
  25. std::vector<int> data;
  26. };
  27. }
  28. //]
  29. //[customize_karma_embedded_container_traits
  30. // All specializations of attribute customization points have to be placed into
  31. // the namespace boost::spirit::traits.
  32. //
  33. // Note that all templates below are specialized using the 'const' type.
  34. // This is necessary as all attributes in Karma are 'const'.
  35. namespace boost { namespace spirit { namespace traits
  36. {
  37. // The specialization of the template 'is_container<>' will tell the
  38. // library to treat the type 'client::embedded_container' as a
  39. // container holding the items to generate output from.
  40. template <>
  41. struct is_container<client::embedded_container const>
  42. : mpl::true_
  43. {};
  44. // The specialization of the template 'container_iterator<>' will be
  45. // invoked by the library to evaluate the iterator type to be used
  46. // for iterating the data elements in the container. We simply return
  47. // the type of the iterator exposed by the embedded 'std::vector<int>'.
  48. template <>
  49. struct container_iterator<client::embedded_container const>
  50. {
  51. typedef client::embedded_container::iterator type;
  52. };
  53. // The specialization of the templates 'begin_container<>' and
  54. // 'end_container<>' below will be used by the library to get the iterators
  55. // pointing to the begin and the end of the data to generate output from.
  56. // These specializations simply return the 'begin' and 'end' iterators as
  57. // exposed by the embedded 'std::vector<int>'.
  58. //
  59. // The passed argument refers to the attribute instance passed to the list
  60. // generator.
  61. template <>
  62. struct begin_container<client::embedded_container const>
  63. {
  64. static client::embedded_container::iterator
  65. call(client::embedded_container const& d)
  66. {
  67. return d.data.begin();
  68. }
  69. };
  70. template <>
  71. struct end_container<client::embedded_container const>
  72. {
  73. static client::embedded_container::iterator
  74. call(client::embedded_container const& d)
  75. {
  76. return d.data.end();
  77. }
  78. };
  79. }}}
  80. //]
  81. ///////////////////////////////////////////////////////////////////////////////
  82. namespace karma = boost::spirit::karma;
  83. int main()
  84. {
  85. //[customize_karma_embedded_container
  86. client::embedded_container d1; // create some test data
  87. d1.data.push_back(1);
  88. d1.data.push_back(2);
  89. d1.data.push_back(3);
  90. // use the instance of an 'client::embedded_container' instead of a
  91. // STL vector
  92. std::cout << karma::format(karma::int_ % ", ", d1) << std::endl; // prints: '1, 2, 3'
  93. //]
  94. return 0;
  95. }