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

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.