Line data Source code
1 : // Copyright (c) 2001-2012 Hartmut Kaiser
2 : //
3 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 :
6 : #if !defined(BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
7 : #define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
8 :
9 : #include <boost/config.hpp>
10 : #include <boost/type_traits/is_empty.hpp>
11 :
12 : namespace boost { namespace spirit { namespace iterator_policies
13 : {
14 : ///////////////////////////////////////////////////////////////////////////
15 : // The purpose of the multi_pass_unique template is to eliminate
16 : // empty policy classes (policies not containing any data items) from the
17 : // multiple inheritance chain. This is necessary since some compilers
18 : // fail to apply the empty base optimization if multiple inheritance is
19 : // involved.
20 : // Additionally this can be used to combine separate policies into one
21 : // single multi_pass_policy as required by the multi_pass template
22 : ///////////////////////////////////////////////////////////////////////////
23 :
24 : ///////////////////////////////////////////////////////////////////////////
25 : // select the correct derived classes based on if a policy is empty
26 : template <typename T
27 : , typename Ownership, typename Checking, typename Input, typename Storage
28 : , bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
29 : , bool CheckingIsEmpty = boost::is_empty<Checking>::value
30 : , bool InputIsEmpty = boost::is_empty<Input>::value>
31 : struct multi_pass_unique;
32 :
33 : ///////////////////////////////////////////////////////////////////////////
34 : template <typename T, typename Ownership, typename Checking
35 : , typename Input, typename Storage>
36 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
37 : , false, false, false>
38 : : Ownership, Checking, Input, Storage
39 : {
40 : multi_pass_unique() {}
41 : multi_pass_unique(T& x) : Input(x) {}
42 : multi_pass_unique(T const& x) : Input(x) {}
43 :
44 : template <typename MultiPass>
45 : static void destroy(MultiPass& mp)
46 : {
47 : Ownership::destroy(mp);
48 : Checking::destroy(mp);
49 : Input::destroy(mp);
50 : Storage::destroy(mp);
51 : }
52 :
53 : void swap(multi_pass_unique& x)
54 : {
55 : this->Ownership::swap(x);
56 : this->Checking::swap(x);
57 : this->Input::swap(x);
58 : this->Storage::swap(x);
59 : }
60 :
61 : template <typename MultiPass>
62 : inline static void clear_queue(MultiPass& mp)
63 : {
64 : Checking::clear_queue(mp);
65 : Storage::clear_queue(mp);
66 : }
67 : };
68 :
69 : ///////////////////////////////////////////////////////////////////////////
70 : template <typename T, typename Ownership, typename Checking
71 : , typename Input, typename Storage>
72 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
73 : , false, false, true>
74 : : Ownership, Checking, Storage
75 : {
76 : multi_pass_unique() {}
77 : multi_pass_unique(T const&) {}
78 :
79 : template <typename MultiPass>
80 : static void destroy(MultiPass& mp)
81 : {
82 : Ownership::destroy(mp);
83 : Checking::destroy(mp);
84 : Input::destroy(mp);
85 : Storage::destroy(mp);
86 : }
87 :
88 : void swap(multi_pass_unique& x)
89 : {
90 : this->Ownership::swap(x);
91 : this->Checking::swap(x);
92 : this->Storage::swap(x);
93 : }
94 :
95 : template <typename MultiPass>
96 : inline static void clear_queue(MultiPass& mp)
97 : {
98 : Checking::clear_queue(mp);
99 : Storage::clear_queue(mp);
100 : }
101 :
102 : // implement input policy functions by forwarding to the Input type
103 : template <typename MultiPass>
104 : inline static void advance_input(MultiPass& mp)
105 : { Input::advance_input(mp); }
106 :
107 : template <typename MultiPass>
108 : inline static typename MultiPass::reference get_input(MultiPass& mp)
109 : { return Input::get_input(mp); }
110 :
111 : template <typename MultiPass>
112 : inline static bool input_at_eof(MultiPass const& mp)
113 : { return Input::input_at_eof(mp); }
114 :
115 : template <typename MultiPass, typename TokenType>
116 : inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
117 : { return Input::input_is_valid(mp, curtok); }
118 : };
119 :
120 : ///////////////////////////////////////////////////////////////////////////
121 : template <typename T, typename Ownership, typename Checking
122 : , typename Input, typename Storage>
123 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
124 : , false, true, false>
125 : : Ownership, Input, Storage
126 : {
127 : multi_pass_unique() {}
128 : multi_pass_unique(T& x) : Input(x) {}
129 : multi_pass_unique(T const& x) : Input(x) {}
130 :
131 : template <typename MultiPass>
132 : static void destroy(MultiPass& mp)
133 : {
134 : Ownership::destroy(mp);
135 : Input::destroy(mp);
136 : Storage::destroy(mp);
137 : }
138 :
139 : void swap(multi_pass_unique& x)
140 : {
141 : this->Ownership::swap(x);
142 : this->Input::swap(x);
143 : this->Storage::swap(x);
144 : }
145 :
146 : template <typename MultiPass>
147 : inline static void clear_queue(MultiPass& mp)
148 : {
149 : Checking::clear_queue(mp);
150 : Storage::clear_queue(mp);
151 : }
152 :
153 : // checking policy functions are forwarded to the Checking type
154 : template <typename MultiPass>
155 : inline static void docheck(MultiPass const& mp)
156 : { Checking::docheck(mp); }
157 : };
158 :
159 : ///////////////////////////////////////////////////////////////////////////
160 : template <typename T, typename Ownership, typename Checking
161 : , typename Input, typename Storage>
162 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
163 : , false, true, true>
164 : : Ownership, Storage
165 : {
166 : multi_pass_unique() {}
167 : multi_pass_unique(T const&) {}
168 :
169 : template <typename MultiPass>
170 : static void destroy(MultiPass& mp)
171 : {
172 : Ownership::destroy(mp);
173 : Input::destroy(mp);
174 : Storage::destroy(mp);
175 : }
176 :
177 : void swap(multi_pass_unique& x)
178 : {
179 : this->Ownership::swap(x);
180 : this->Storage::swap(x);
181 : }
182 :
183 : template <typename MultiPass>
184 : inline static void clear_queue(MultiPass& mp)
185 : {
186 : Checking::clear_queue(mp);
187 : Storage::clear_queue(mp);
188 : }
189 :
190 : // implement input policy functions by forwarding to the Input type
191 : template <typename MultiPass>
192 : inline static void advance_input(MultiPass& mp)
193 : { Input::advance_input(mp); }
194 :
195 : template <typename MultiPass>
196 : inline static typename MultiPass::reference get_input(MultiPass& mp)
197 : { return Input::get_input(mp); }
198 :
199 : template <typename MultiPass>
200 : inline static bool input_at_eof(MultiPass const& mp)
201 : { return Input::input_at_eof(mp); }
202 :
203 : template <typename MultiPass, typename TokenType>
204 : inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
205 : { return Input::input_is_valid(mp, curtok); }
206 :
207 : // checking policy functions are forwarded to the Checking type
208 : template <typename MultiPass>
209 : inline static void docheck(MultiPass const& mp)
210 : { Checking::docheck(mp); }
211 : };
212 :
213 : ///////////////////////////////////////////////////////////////////////////
214 : template <typename T, typename Ownership, typename Checking
215 : , typename Input, typename Storage>
216 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
217 : , true, false, false>
218 : : Checking, Input, Storage
219 : {
220 : multi_pass_unique() {}
221 : multi_pass_unique(T& x) : Input(x) {}
222 : multi_pass_unique(T const& x) : Input(x) {}
223 :
224 : template <typename MultiPass>
225 : static void destroy(MultiPass& mp)
226 : {
227 : Checking::destroy(mp);
228 : Input::destroy(mp);
229 : Storage::destroy(mp);
230 : }
231 :
232 : void swap(multi_pass_unique& x)
233 : {
234 : this->Checking::swap(x);
235 : this->Input::swap(x);
236 : this->Storage::swap(x);
237 : }
238 :
239 : template <typename MultiPass>
240 : inline static void clear_queue(MultiPass& mp)
241 : {
242 : Checking::clear_queue(mp);
243 : Storage::clear_queue(mp);
244 : }
245 :
246 : // ownership policy functions are forwarded to the Ownership type
247 : template <typename MultiPass>
248 : inline static void clone(MultiPass& mp)
249 : { Ownership::clone(mp); }
250 :
251 : template <typename MultiPass>
252 : inline static bool release(MultiPass& mp)
253 : { return Ownership::release(mp); }
254 :
255 : template <typename MultiPass>
256 : inline static bool is_unique(MultiPass const& mp)
257 : { return Ownership::is_unique(mp); }
258 : };
259 :
260 : ///////////////////////////////////////////////////////////////////////////
261 : template <typename T, typename Ownership, typename Checking
262 : , typename Input, typename Storage>
263 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
264 : , true, false, true>
265 : : Checking, Storage
266 : {
267 : multi_pass_unique() {}
268 : multi_pass_unique(T const&) {}
269 :
270 : template <typename MultiPass>
271 : static void destroy(MultiPass& mp)
272 : {
273 : Checking::destroy(mp);
274 : Input::destroy(mp);
275 : Storage::destroy(mp);
276 : }
277 :
278 : void swap(multi_pass_unique& x)
279 : {
280 : this->Checking::swap(x);
281 : this->Storage::swap(x);
282 : }
283 :
284 : template <typename MultiPass>
285 : inline static void clear_queue(MultiPass& mp)
286 : {
287 : Checking::clear_queue(mp);
288 : Storage::clear_queue(mp);
289 : }
290 :
291 : // implement input policy functions by forwarding to the Input type
292 : template <typename MultiPass>
293 : inline static void advance_input(MultiPass& mp)
294 : { Input::advance_input(mp); }
295 :
296 : template <typename MultiPass>
297 : inline static typename MultiPass::reference get_input(MultiPass& mp)
298 : { return Input::get_input(mp); }
299 :
300 : template <typename MultiPass>
301 : inline static bool input_at_eof(MultiPass const& mp)
302 : { return Input::input_at_eof(mp); }
303 :
304 : template <typename MultiPass, typename TokenType>
305 : inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
306 : { return Input::input_is_valid(mp, curtok); }
307 :
308 : // ownership policy functions are forwarded to the Ownership type
309 : template <typename MultiPass>
310 : inline static void clone(MultiPass& mp)
311 : { Ownership::clone(mp); }
312 :
313 : template <typename MultiPass>
314 : inline static bool release(MultiPass& mp)
315 : { return Ownership::release(mp); }
316 :
317 : template <typename MultiPass>
318 : inline static bool is_unique(MultiPass const& mp)
319 : { return Ownership::is_unique(mp); }
320 : };
321 :
322 : ///////////////////////////////////////////////////////////////////////////
323 : template <typename T, typename Ownership, typename Checking
324 : , typename Input, typename Storage>
325 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
326 : , true, true, false>
327 : : Input, Storage
328 : {
329 : multi_pass_unique() {}
330 : multi_pass_unique(T& x) : Input(x) {}
331 : multi_pass_unique(T const& x) : Input(x) {}
332 :
333 : template <typename MultiPass>
334 : static void destroy(MultiPass& mp)
335 : {
336 : Input::destroy(mp);
337 : Storage::destroy(mp);
338 : }
339 :
340 : void swap(multi_pass_unique& x)
341 : {
342 : this->Input::swap(x);
343 : this->Storage::swap(x);
344 : }
345 :
346 : template <typename MultiPass>
347 : inline static void clear_queue(MultiPass& mp)
348 : {
349 : Checking::clear_queue(mp);
350 : Storage::clear_queue(mp);
351 : }
352 :
353 : // checking policy functions are forwarded to the Checking type
354 : template <typename MultiPass>
355 : inline static void docheck(MultiPass const& mp)
356 : { Checking::docheck(mp); }
357 :
358 : // ownership policy functions are forwarded to the Ownership type
359 : template <typename MultiPass>
360 : inline static void clone(MultiPass& mp)
361 : { Ownership::clone(mp); }
362 :
363 : template <typename MultiPass>
364 : inline static bool release(MultiPass& mp)
365 : { return Ownership::release(mp); }
366 :
367 : template <typename MultiPass>
368 : inline static bool is_unique(MultiPass const& mp)
369 : { return Ownership::is_unique(mp); }
370 : };
371 :
372 : ///////////////////////////////////////////////////////////////////////////
373 : template <typename T, typename Ownership, typename Checking
374 : , typename Input, typename Storage>
375 0 : struct multi_pass_unique<T, Ownership, Checking, Input, Storage
376 : , true, true, true>
377 : : Storage
378 : {
379 0 : multi_pass_unique() {}
380 0 : multi_pass_unique(T const&) {}
381 :
382 : template <typename MultiPass>
383 0 : static void destroy(MultiPass& mp)
384 : {
385 0 : Input::destroy(mp);
386 0 : Storage::destroy(mp);
387 : }
388 :
389 0 : void swap(multi_pass_unique& x)
390 : {
391 0 : this->Storage::swap(x);
392 : }
393 :
394 : template <typename MultiPass>
395 : inline static void clear_queue(MultiPass& mp)
396 : {
397 : Checking::clear_queue(mp);
398 : Storage::clear_queue(mp);
399 : }
400 :
401 : // implement input policy functions by forwarding to the Input type
402 : template <typename MultiPass>
403 0 : inline static void advance_input(MultiPass& mp)
404 0 : { Input::advance_input(mp); }
405 :
406 : template <typename MultiPass>
407 0 : inline static typename MultiPass::reference get_input(MultiPass& mp)
408 0 : { return Input::get_input(mp); }
409 :
410 : template <typename MultiPass>
411 0 : inline static bool input_at_eof(MultiPass const& mp)
412 0 : { return Input::input_at_eof(mp); }
413 :
414 : template <typename MultiPass, typename TokenType>
415 : inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
416 : { return Input::input_is_valid(mp, curtok); }
417 :
418 : // checking policy functions are forwarded to the Checking type
419 : template <typename MultiPass>
420 0 : inline static void docheck(MultiPass const& mp)
421 0 : { Checking::docheck(mp); }
422 :
423 : // ownership policy functions are forwarded to the Ownership type
424 : template <typename MultiPass>
425 0 : inline static void clone(MultiPass& mp)
426 0 : { Ownership::clone(mp); }
427 :
428 : template <typename MultiPass>
429 0 : inline static bool release(MultiPass& mp)
430 0 : { return Ownership::release(mp); }
431 :
432 : template <typename MultiPass>
433 0 : inline static bool is_unique(MultiPass const& mp)
434 0 : { return Ownership::is_unique(mp); }
435 : };
436 :
437 : ///////////////////////////////////////////////////////////////////////////
438 : // the multi_pass_shared structure is used to combine the shared data items
439 : // of all policies into one single structure
440 : ///////////////////////////////////////////////////////////////////////////
441 : template<typename T, typename Ownership, typename Checking, typename Input
442 : , typename Storage>
443 0 : struct multi_pass_shared : Ownership, Checking, Input, Storage
444 : {
445 : explicit multi_pass_shared(T& input) : Input(input) {}
446 0 : explicit multi_pass_shared(T const& input) : Input(input) {}
447 : };
448 :
449 : ///////////////////////////////////////////////////////////////////////////
450 : // This is a default implementation of a policy class as required by the
451 : // multi_pass template, combining 4 separate policies into one. Any other
452 : // multi_pass policy class needs to follow the scheme as shown below.
453 : template<typename Ownership, typename Checking, typename Input
454 : , typename Storage>
455 : struct default_policy
456 : {
457 : typedef Ownership ownership_policy;
458 : typedef Checking checking_policy;
459 : typedef Input input_policy;
460 : typedef Storage storage_policy;
461 :
462 : ///////////////////////////////////////////////////////////////////////
463 : template <typename T>
464 0 : struct unique : multi_pass_unique<T
465 : , typename Ownership::unique, typename Checking::unique
466 : , typename Input::BOOST_NESTED_TEMPLATE unique<T>
467 : , typename Storage::BOOST_NESTED_TEMPLATE unique<
468 : typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
469 : {
470 : typedef typename Ownership::unique ownership_policy;
471 : typedef typename Checking::unique checking_policy;
472 : typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
473 : input_policy;
474 : typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
475 : typename input_policy::value_type> storage_policy;
476 :
477 : typedef multi_pass_unique<T, ownership_policy, checking_policy
478 : , input_policy, storage_policy> unique_base_type;
479 :
480 0 : unique() {}
481 : explicit unique(T& input) : unique_base_type(input) {}
482 0 : explicit unique(T const& input) : unique_base_type(input) {}
483 : };
484 :
485 : ///////////////////////////////////////////////////////////////////////
486 : template <typename T>
487 0 : struct shared : multi_pass_shared<T
488 : , typename Ownership::shared, typename Checking::shared
489 : , typename Input::BOOST_NESTED_TEMPLATE shared<T>
490 : , typename Storage::BOOST_NESTED_TEMPLATE shared<
491 : typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
492 : {
493 : typedef typename Ownership::shared ownership_policy;
494 : typedef typename Checking::shared checking_policy;
495 : typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
496 : input_policy;
497 : typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
498 : typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
499 : storage_policy;
500 :
501 : typedef multi_pass_shared<T, ownership_policy, checking_policy
502 : , input_policy, storage_policy> shared_base_type;
503 :
504 : explicit shared(T& input)
505 : : shared_base_type(input), inhibit_clear_queue_(false) {}
506 0 : explicit shared(T const& input)
507 0 : : shared_base_type(input), inhibit_clear_queue_(false) {}
508 :
509 : // This is needed for the correct implementation of expectation
510 : // points. Normally expectation points flush any multi_pass
511 : // iterator they may act on, but if the corresponding error handler
512 : // is of type 'retry' no flushing of the internal buffers should be
513 : // executed (even if explicitly requested).
514 : bool inhibit_clear_queue_;
515 : };
516 : };
517 :
518 : }}}
519 :
520 : #endif
|