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

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