]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/karma/detail/alternative_function.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / spirit / home / karma / detail / alternative_function.hpp
CommitLineData
7c673cae
FG
1// Copyright (c) 2001-2011 Hartmut Kaiser
2// Copyright (c) 2001-2011 Joel de Guzman
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
f67539c2
TL
7#ifndef BOOST_SPIRIT_KARMA_DETAIL_ALTERNATIVE_FUNCTION_HPP
8#define BOOST_SPIRIT_KARMA_DETAIL_ALTERNATIVE_FUNCTION_HPP
7c673cae
FG
9
10#if defined(_MSC_VER)
11#pragma once
12#endif
13
14#include <boost/spirit/home/karma/domain.hpp>
15#include <boost/spirit/home/karma/directive/buffer.hpp>
16#include <boost/spirit/home/support/unused.hpp>
17#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
18#include <boost/spirit/home/karma/detail/attributes.hpp>
19#include <boost/spirit/home/support/detail/hold_any.hpp>
20#include <boost/spirit/home/karma/detail/output_iterator.hpp>
21#include <boost/spirit/home/support/container.hpp>
22#include <boost/utility/enable_if.hpp>
23#include <boost/variant.hpp>
24#include <boost/detail/workaround.hpp>
25
26///////////////////////////////////////////////////////////////////////////////
27namespace boost { namespace spirit { namespace karma { namespace detail
28{
29 ///////////////////////////////////////////////////////////////////////////
30 // execute a generator if the given Attribute type is compatible
31 ///////////////////////////////////////////////////////////////////////////
32
33 // this gets instantiated if the Attribute type is _not_ compatible with
34 // the generator
35 template <typename Component, typename Attribute, typename Expected
36 , typename Enable = void>
37 struct alternative_generate
38 {
39 template <typename OutputIterator, typename Context, typename Delimiter>
40 static bool
41 call(Component const&, OutputIterator&, Context&, Delimiter const&
42 , Attribute const&, bool& failed)
43 {
44 failed = true;
45 return false;
46 }
47 };
48
49 template <typename Component>
50 struct alternative_generate<Component, unused_type, unused_type>
51 {
52 template <typename OutputIterator, typename Context, typename Delimiter>
53 static bool
54 call(Component const& component, OutputIterator& sink, Context& ctx
55 , Delimiter const& d, unused_type, bool&)
56 {
57#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1e59de90 58 (void)component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
7c673cae
FG
59#endif
60 // return true if any of the generators succeed
61 return component.generate(sink, ctx, d, unused);
62 }
63 };
64
65 // this gets instantiated if there is no Attribute given for the
66 // alternative generator
67 template <typename Component, typename Expected>
68 struct alternative_generate<Component, unused_type, Expected>
69 : alternative_generate<Component, unused_type, unused_type> {};
70
71 // this gets instantiated if the generator does not expect to receive an
72 // Attribute (the generator is self contained).
73 template <typename Component, typename Attribute>
74 struct alternative_generate<Component, Attribute, unused_type>
75 : alternative_generate<Component, unused_type, unused_type> {};
76
77 // this gets instantiated if the Attribute type is compatible to the
78 // generator
79 template <typename Component, typename Attribute, typename Expected>
80 struct alternative_generate<Component, Attribute, Expected
81 , typename enable_if<
82 traits::compute_compatible_component<Expected, Attribute, karma::domain> >::type>
83 {
84 template <typename OutputIterator, typename Context, typename Delimiter>
85 static bool
86 call(Component const& component, OutputIterator& sink
87 , Context& ctx, Delimiter const& d, Attribute const& attr, bool&)
88 {
89#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1e59de90 90 (void)component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
7c673cae
FG
91#endif
92 return call(component, sink, ctx, d, attr
11fdf7f2 93 , spirit::traits::not_is_variant_or_variant_in_optional<Attribute, karma::domain>());
7c673cae
FG
94 }
95
96 template <typename OutputIterator, typename Context, typename Delimiter>
97 static bool
98 call(Component const& component, OutputIterator& sink
99 , Context& ctx, Delimiter const& d, Attribute const& attr, mpl::true_)
100 {
101#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1e59de90 102 (void)component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
7c673cae
FG
103#endif
104 return component.generate(sink, ctx, d, attr);
105 }
106
107 template <typename OutputIterator, typename Context, typename Delimiter>
108 static bool
109 call(Component const& component, OutputIterator& sink
110 , Context& ctx, Delimiter const& d, Attribute const& attr, mpl::false_)
111 {
112#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1e59de90 113 (void)component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
7c673cae
FG
114#endif
115 typedef
116 traits::compute_compatible_component<Expected, Attribute, domain>
117 component_type;
118
119 // if we got passed an empty optional, just fail generation
120 if (!traits::has_optional_value(attr))
121 return false;
122
123 // make sure, the content of the passed variant matches our
124 // expectations
125 typename traits::optional_attribute<Attribute>::type attr_ =
126 traits::optional_value(attr);
127 if (!component_type::is_compatible(spirit::traits::which(attr_)))
128 return false;
129
130 // returns true if any of the generators succeed
131 typedef typename component_type::compatible_type compatible_type;
132 return component.generate(sink, ctx, d
133 , boost::get<compatible_type>(attr_));
134 }
135 };
136
137 ///////////////////////////////////////////////////////////////////////////
138 // alternative_generate_function: a functor supplied to fusion::any which
139 // will be executed for every generator in a given alternative generator
140 // expression
141 ///////////////////////////////////////////////////////////////////////////
142 template <typename OutputIterator, typename Context, typename Delimiter,
143 typename Attribute, typename Strict>
144 struct alternative_generate_function
145 {
146 alternative_generate_function(OutputIterator& sink_, Context& ctx_
147 , Delimiter const& d, Attribute const& attr_)
148 : sink(sink_), ctx(ctx_), delim(d), attr(attr_) {}
149
150 template <typename Component>
151 bool operator()(Component const& component)
152 {
153 typedef
154 typename traits::attribute_of<Component, Context>::type
155 expected_type;
156 typedef
157 alternative_generate<Component, Attribute, expected_type>
158 generate;
159
160 // wrap the given output iterator avoid output as long as one
161 // component fails
162 detail::enable_buffering<OutputIterator> buffering(sink);
163 bool r = false;
164 bool failed = false; // will be ignored
165 {
166 detail::disable_counting<OutputIterator> nocounting(sink);
167 r = generate::call(component, sink, ctx, delim, attr, failed);
168 }
169 if (r)
170 buffering.buffer_copy();
171 return r;
172 }
173
174 // avoid double buffering
175 template <typename Component>
176 bool operator()(buffer_directive<Component> const& component)
177 {
178 typedef typename
179 traits::attribute_of<Component, Context>::type
180 expected_type;
181 typedef alternative_generate<
182 buffer_directive<Component>, Attribute, expected_type>
183 generate;
184
185 bool failed = false; // will be ignored
186 return generate::call(component, sink, ctx, delim, attr, failed);
187 }
188
189 OutputIterator& sink;
190 Context& ctx;
191 Delimiter const& delim;
192 Attribute const& attr;
193
7c673cae 194 // silence MSVC warning C4512: assignment operator could not be generated
92f5a8d4 195 BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&))
7c673cae
FG
196 };
197
198 // specialization for strict alternatives
199 template <typename OutputIterator, typename Context, typename Delimiter,
200 typename Attribute>
201 struct alternative_generate_function<
202 OutputIterator, Context, Delimiter, Attribute, mpl::true_>
203 {
204 alternative_generate_function(OutputIterator& sink_, Context& ctx_
205 , Delimiter const& d, Attribute const& attr_)
206 : sink(sink_), ctx(ctx_), delim(d), attr(attr_), failed(false) {}
207
208 template <typename Component>
209 bool operator()(Component const& component)
210 {
211 typedef
212 typename traits::attribute_of<Component, Context>::type
213 expected_type;
214 typedef
215 alternative_generate<Component, Attribute, expected_type>
216 generate;
217
218 if (failed)
219 return false; // give up when already failed
220
221 // wrap the given output iterator avoid output as long as one
222 // component fails
223 detail::enable_buffering<OutputIterator> buffering(sink);
224 bool r = false;
225 {
226 detail::disable_counting<OutputIterator> nocounting(sink);
227 r = generate::call(component, sink, ctx, delim, attr, failed);
228 }
229 if (r && !failed)
230 {
231 buffering.buffer_copy();
232 return true;
233 }
234 return false;
235 }
236
237 OutputIterator& sink;
238 Context& ctx;
239 Delimiter const& delim;
240 Attribute const& attr;
241 bool failed;
242
7c673cae 243 // silence MSVC warning C4512: assignment operator could not be generated
92f5a8d4 244 BOOST_DELETED_FUNCTION(alternative_generate_function& operator= (alternative_generate_function const&))
7c673cae
FG
245 };
246}}}}
247
248#endif