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