]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/karma/customize_use_as_container.cpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / libs / spirit / example / karma / customize_use_as_container.cpp
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_use_as_container_includes
10 #include <boost/spirit/include/karma.hpp>
11 #include <iostream>
12 #include <string>
13 #include <vector>
14 //]
15
16 ///////////////////////////////////////////////////////////////////////////////
17 //[customize_karma_use_as_container_data
18 namespace client
19 {
20 struct use_as_container
21 {
22 // Expose a pair holding a pointer to the use_as_container and to the
23 // current element as our iterator.
24 // We intentionally leave out having it a 'operator==()' to demonstrate
25 // the use of the 'compare_iterators' customization point.
26 struct iterator
27 {
28 iterator(use_as_container const* container, int const* current)
29 : container_(container), current_(current)
30 {}
31
32 use_as_container const* container_;
33 int const* current_;
34 };
35
36 // expose 'int' as the type of each generated element
37 typedef int type;
38
39 use_as_container(int value1, int value2, int value3)
40 : value1_(value1), value2_(value2), value3_(value3)
41 {}
42
43 int value1_;
44 std::string dummy1_; // insert some unrelated data
45 int value2_;
46 std::string dummy2_; // insert some more unrelated data
47 int value3_;
48 };
49 }
50 //]
51
52 //[customize_karma_use_as_container_traits
53 // All specializations of attribute customization points have to be placed into
54 // the namespace boost::spirit::traits.
55 //
56 // Note that all templates below are specialized using the 'const' type.
57 // This is necessary as all attributes in Karma are 'const'.
58 namespace boost { namespace spirit { namespace traits
59 {
60 // The specialization of the template 'is_container<>' will tell the
61 // library to treat the type 'client::use_as_container' as a
62 // container holding the items to generate output from.
63 template <>
64 struct is_container<client::use_as_container const>
65 : mpl::true_
66 {};
67
68 // The specialization of the template 'container_iterator<>' will be
69 // invoked by the library to evaluate the iterator type to be used
70 // for iterating the data elements in the container. We simply return
71 // the type of the iterator exposed by the embedded 'std::vector<int>'.
72 template <>
73 struct container_iterator<client::use_as_container const>
74 {
75 typedef client::use_as_container::iterator type;
76 };
77
78 // The specialization of the templates 'begin_container<>' and
79 // 'end_container<>' below will be used by the library to get the iterators
80 // pointing to the begin and the end of the data to generate output from.
81 //
82 // The passed argument refers to the attribute instance passed to the list
83 // generator.
84 template <>
85 struct begin_container<client::use_as_container const>
86 {
87 static client::use_as_container::iterator
88 call(client::use_as_container const& c)
89 {
90 return client::use_as_container::iterator(&c, &c.value1_);
91 }
92 };
93
94 template <>
95 struct end_container<client::use_as_container const>
96 {
97 static client::use_as_container::iterator
98 call(client::use_as_container const& c)
99 {
100 return client::use_as_container::iterator(&c, (int const*)0);
101 }
102 };
103 }}}
104 //]
105
106 //[customize_karma_use_as_container_iterator_traits
107 // All specializations of attribute customization points have to be placed into
108 // the namespace boost::spirit::traits.
109 namespace boost { namespace spirit { namespace traits
110 {
111 // The specialization of the template 'deref_iterator<>' will be used to
112 // dereference the iterator associated with our counter data structure.
113 template <>
114 struct deref_iterator<client::use_as_container::iterator>
115 {
116 typedef client::use_as_container::type type;
117
118 static type call(client::use_as_container::iterator const& it)
119 {
120 return *it.current_;
121 }
122 };
123
124 template <>
125 struct next_iterator<client::use_as_container::iterator>
126 {
127 static void call(client::use_as_container::iterator& it)
128 {
129 if (it.current_ == &it.container_->value1_)
130 it.current_ = &it.container_->value2_;
131 else if (it.current_ == &it.container_->value2_)
132 it.current_ = &it.container_->value3_;
133 else
134 it.current_ = 0;
135 }
136 };
137
138 template <>
139 struct compare_iterators<client::use_as_container::iterator>
140 {
141 static bool call(client::use_as_container::iterator const& it1
142 , client::use_as_container::iterator const& it2)
143 {
144 return it1.current_ == it2.current_ &&
145 it1.container_ == it2.container_;
146 }
147 };
148 }}}
149 //]
150
151 ///////////////////////////////////////////////////////////////////////////////
152 namespace karma = boost::spirit::karma;
153
154 int main()
155 {
156 //[customize_karma_use_as_container
157 client::use_as_container d2 (1, 2, 3);
158 // use the instance of a 'client::use_as_container' instead of a STL vector
159 std::cout << karma::format(karma::int_ % ", ", d2) << std::endl; // prints: '1, 2, 3'
160 //]
161 return 0;
162 }
163