]>
git.proxmox.com Git - ceph.git/blob - 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/
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 =============================================================================*/
9 //[customize_karma_use_as_container_includes
10 #include <boost/spirit/include/karma.hpp>
16 ///////////////////////////////////////////////////////////////////////////////
17 //[customize_karma_use_as_container_data
20 struct use_as_container
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.
28 iterator(use_as_container
const* container
, int const* current
)
29 : container_(container
), current_(current
)
32 use_as_container
const* container_
;
36 // expose 'int' as the type of each generated element
39 use_as_container(int value1
, int value2
, int value3
)
40 : value1_(value1
), value2_(value2
), value3_(value3
)
44 std::string dummy1_
; // insert some unrelated data
46 std::string dummy2_
; // insert some more unrelated data
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.
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
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.
64 struct is_container
<client::use_as_container
const>
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>'.
73 struct container_iterator
<client::use_as_container
const>
75 typedef client::use_as_container::iterator type
;
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.
82 // The passed argument refers to the attribute instance passed to the list
85 struct begin_container
<client::use_as_container
const>
87 static client::use_as_container::iterator
88 call(client::use_as_container
const& c
)
90 return client::use_as_container::iterator(&c
, &c
.value1_
);
95 struct end_container
<client::use_as_container
const>
97 static client::use_as_container::iterator
98 call(client::use_as_container
const& c
)
100 return client::use_as_container::iterator(&c
, (int const*)0);
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
111 // The specialization of the template 'deref_iterator<>' will be used to
112 // dereference the iterator associated with our counter data structure.
114 struct deref_iterator
<client::use_as_container::iterator
>
116 typedef client::use_as_container::type type
;
118 static type
call(client::use_as_container::iterator
const& it
)
125 struct next_iterator
<client::use_as_container::iterator
>
127 static void call(client::use_as_container::iterator
& it
)
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_
;
139 struct compare_iterators
<client::use_as_container::iterator
>
141 static bool call(client::use_as_container::iterator
const& it1
142 , client::use_as_container::iterator
const& it2
)
144 return it1
.current_
== it2
.current_
&&
145 it1
.container_
== it2
.container_
;
151 ///////////////////////////////////////////////////////////////////////////////
152 namespace karma
= boost::spirit::karma
;
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'