]>
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 =============================================================================*/
8 #include <boost/config/warning_disable.hpp>
10 //[customize_karma_use_as_container_includes
11 #include <boost/spirit/include/karma.hpp>
17 ///////////////////////////////////////////////////////////////////////////////
18 //[customize_karma_use_as_container_data
21 struct use_as_container
23 // Expose a pair holding a pointer to the use_as_container and to the
24 // current element as our iterator.
25 // We intentionally leave out having it a 'operator==()' to demonstrate
26 // the use of the 'compare_iterators' customization point.
29 iterator(use_as_container
const* container
, int const* current
)
30 : container_(container
), current_(current
)
33 use_as_container
const* container_
;
37 // expose 'int' as the type of each generated element
40 use_as_container(int value1
, int value2
, int value3
)
41 : value1_(value1
), value2_(value2
), value3_(value3
)
45 std::string dummy1_
; // insert some unrelated data
47 std::string dummy2_
; // insert some more unrelated data
53 //[customize_karma_use_as_container_traits
54 // All specializations of attribute customization points have to be placed into
55 // the namespace boost::spirit::traits.
57 // Note that all templates below are specialized using the 'const' type.
58 // This is necessary as all attributes in Karma are 'const'.
59 namespace boost
{ namespace spirit
{ namespace traits
61 // The specialization of the template 'is_container<>' will tell the
62 // library to treat the type 'client::use_as_container' as a
63 // container holding the items to generate output from.
65 struct is_container
<client::use_as_container
const>
69 // The specialization of the template 'container_iterator<>' will be
70 // invoked by the library to evaluate the iterator type to be used
71 // for iterating the data elements in the container. We simply return
72 // the type of the iterator exposed by the embedded 'std::vector<int>'.
74 struct container_iterator
<client::use_as_container
const>
76 typedef client::use_as_container::iterator type
;
79 // The specialization of the templates 'begin_container<>' and
80 // 'end_container<>' below will be used by the library to get the iterators
81 // pointing to the begin and the end of the data to generate output from.
83 // The passed argument refers to the attribute instance passed to the list
86 struct begin_container
<client::use_as_container
const>
88 static client::use_as_container::iterator
89 call(client::use_as_container
const& c
)
91 return client::use_as_container::iterator(&c
, &c
.value1_
);
96 struct end_container
<client::use_as_container
const>
98 static client::use_as_container::iterator
99 call(client::use_as_container
const& c
)
101 return client::use_as_container::iterator(&c
, (int const*)0);
107 //[customize_karma_use_as_container_iterator_traits
108 // All specializations of attribute customization points have to be placed into
109 // the namespace boost::spirit::traits.
110 namespace boost
{ namespace spirit
{ namespace traits
112 // The specialization of the template 'deref_iterator<>' will be used to
113 // dereference the iterator associated with our counter data structure.
115 struct deref_iterator
<client::use_as_container::iterator
>
117 typedef client::use_as_container::type type
;
119 static type
call(client::use_as_container::iterator
const& it
)
126 struct next_iterator
<client::use_as_container::iterator
>
128 static void call(client::use_as_container::iterator
& it
)
130 if (it
.current_
== &it
.container_
->value1_
)
131 it
.current_
= &it
.container_
->value2_
;
132 else if (it
.current_
== &it
.container_
->value2_
)
133 it
.current_
= &it
.container_
->value3_
;
140 struct compare_iterators
<client::use_as_container::iterator
>
142 static bool call(client::use_as_container::iterator
const& it1
143 , client::use_as_container::iterator
const& it2
)
145 return it1
.current_
== it2
.current_
&&
146 it1
.container_
== it2
.container_
;
152 ///////////////////////////////////////////////////////////////////////////////
153 namespace karma
= boost::spirit::karma
;
157 //[customize_karma_use_as_container
158 client::use_as_container
d2 (1, 2, 3);
159 // use the instance of a 'client::use_as_container' instead of a STL vector
160 std::cout
<< karma::format(karma::int_
% ", ", d2
) << std::endl
; // prints: '1, 2, 3'