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