Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:51

0001 //  Copyright (c) 2001-2012 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
0007 #define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
0008 
0009 #include <boost/config.hpp>
0010 #include <boost/type_traits/is_empty.hpp>
0011 
0012 namespace boost { namespace spirit { namespace iterator_policies
0013 {
0014     ///////////////////////////////////////////////////////////////////////////
0015     //  The purpose of the multi_pass_unique template is to eliminate
0016     //  empty policy classes (policies not containing any data items) from the
0017     //  multiple inheritance chain. This is necessary since some compilers
0018     //  fail to apply the empty base optimization if multiple inheritance is
0019     //  involved.
0020     //  Additionally this can be used to combine separate policies into one
0021     //  single multi_pass_policy as required by the multi_pass template
0022     ///////////////////////////////////////////////////////////////////////////
0023 
0024     ///////////////////////////////////////////////////////////////////////////
0025     // select the correct derived classes based on if a policy is empty
0026     template <typename T
0027       , typename Ownership, typename Checking, typename Input, typename Storage
0028       , bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
0029       , bool CheckingIsEmpty = boost::is_empty<Checking>::value
0030       , bool InputIsEmpty = boost::is_empty<Input>::value>
0031     struct multi_pass_unique;
0032 
0033     ///////////////////////////////////////////////////////////////////////////
0034     template <typename T, typename Ownership, typename Checking
0035       , typename Input, typename Storage>
0036     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0037           , false, false, false>
0038       : Ownership, Checking, Input, Storage
0039     {
0040         multi_pass_unique() {}
0041         multi_pass_unique(T& x) : Input(x) {}
0042         multi_pass_unique(T const& x) : Input(x) {}
0043 
0044         template <typename MultiPass>
0045         static void destroy(MultiPass& mp)
0046         {
0047             Ownership::destroy(mp);
0048             Checking::destroy(mp);
0049             Input::destroy(mp);
0050             Storage::destroy(mp);
0051         }
0052 
0053         void swap(multi_pass_unique& x)
0054         {
0055             this->Ownership::swap(x);
0056             this->Checking::swap(x);
0057             this->Input::swap(x);
0058             this->Storage::swap(x);
0059         }
0060 
0061         template <typename MultiPass>
0062         inline static void clear_queue(MultiPass& mp)
0063         {
0064             Checking::clear_queue(mp);
0065             Storage::clear_queue(mp);
0066         }
0067     };
0068 
0069     ///////////////////////////////////////////////////////////////////////////
0070     template <typename T, typename Ownership, typename Checking
0071       , typename Input, typename Storage>
0072     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0073           , false, false, true>
0074       : Ownership, Checking, Storage
0075     {
0076         multi_pass_unique() {}
0077         multi_pass_unique(T const&) {}
0078 
0079         template <typename MultiPass>
0080         static void destroy(MultiPass& mp)
0081         {
0082             Ownership::destroy(mp);
0083             Checking::destroy(mp);
0084             Input::destroy(mp);
0085             Storage::destroy(mp);
0086         }
0087 
0088         void swap(multi_pass_unique& x)
0089         {
0090             this->Ownership::swap(x);
0091             this->Checking::swap(x);
0092             this->Storage::swap(x);
0093         }
0094 
0095         template <typename MultiPass>
0096         inline static void clear_queue(MultiPass& mp)
0097         {
0098             Checking::clear_queue(mp);
0099             Storage::clear_queue(mp);
0100         }
0101 
0102         // implement input policy functions by forwarding to the Input type
0103         template <typename MultiPass>
0104         inline static void advance_input(MultiPass& mp)
0105             { Input::advance_input(mp); }
0106 
0107         template <typename MultiPass>
0108         inline static typename MultiPass::reference get_input(MultiPass& mp)
0109             { return Input::get_input(mp); }
0110 
0111         template <typename MultiPass>
0112         inline static bool input_at_eof(MultiPass const& mp)
0113             { return Input::input_at_eof(mp); }
0114 
0115         template <typename MultiPass, typename TokenType>
0116         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
0117             { return Input::input_is_valid(mp, curtok); }
0118     };
0119 
0120     ///////////////////////////////////////////////////////////////////////////
0121     template <typename T, typename Ownership, typename Checking
0122       , typename Input, typename Storage>
0123     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0124           , false, true, false>
0125       : Ownership, Input, Storage
0126     {
0127         multi_pass_unique() {}
0128         multi_pass_unique(T& x) : Input(x) {}
0129         multi_pass_unique(T const& x) : Input(x) {}
0130 
0131         template <typename MultiPass>
0132         static void destroy(MultiPass& mp)
0133         {
0134             Ownership::destroy(mp);
0135             Input::destroy(mp);
0136             Storage::destroy(mp);
0137         }
0138 
0139         void swap(multi_pass_unique& x)
0140         {
0141             this->Ownership::swap(x);
0142             this->Input::swap(x);
0143             this->Storage::swap(x);
0144         }
0145 
0146         template <typename MultiPass>
0147         inline static void clear_queue(MultiPass& mp)
0148         {
0149             Checking::clear_queue(mp);
0150             Storage::clear_queue(mp);
0151         }
0152 
0153         // checking policy functions are forwarded to the Checking type
0154         template <typename MultiPass>
0155         inline static void docheck(MultiPass const& mp)
0156             { Checking::docheck(mp); }
0157     };
0158 
0159     ///////////////////////////////////////////////////////////////////////////
0160     template <typename T, typename Ownership, typename Checking
0161       , typename Input, typename Storage>
0162     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0163           , false, true, true>
0164       : Ownership, Storage
0165     {
0166         multi_pass_unique() {}
0167         multi_pass_unique(T const&) {}
0168 
0169         template <typename MultiPass>
0170         static void destroy(MultiPass& mp)
0171         {
0172             Ownership::destroy(mp);
0173             Input::destroy(mp);
0174             Storage::destroy(mp);
0175         }
0176 
0177         void swap(multi_pass_unique& x)
0178         {
0179             this->Ownership::swap(x);
0180             this->Storage::swap(x);
0181         }
0182 
0183         template <typename MultiPass>
0184         inline static void clear_queue(MultiPass& mp)
0185         {
0186             Checking::clear_queue(mp);
0187             Storage::clear_queue(mp);
0188         }
0189 
0190         // implement input policy functions by forwarding to the Input type
0191         template <typename MultiPass>
0192         inline static void advance_input(MultiPass& mp)
0193             { Input::advance_input(mp); }
0194 
0195         template <typename MultiPass>
0196         inline static typename MultiPass::reference get_input(MultiPass& mp)
0197             { return Input::get_input(mp); }
0198 
0199         template <typename MultiPass>
0200         inline static bool input_at_eof(MultiPass const& mp)
0201             { return Input::input_at_eof(mp); }
0202 
0203         template <typename MultiPass, typename TokenType>
0204         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
0205             { return Input::input_is_valid(mp, curtok); }
0206 
0207         // checking policy functions are forwarded to the Checking type
0208         template <typename MultiPass>
0209         inline static void docheck(MultiPass const& mp)
0210             { Checking::docheck(mp); }
0211     };
0212 
0213     ///////////////////////////////////////////////////////////////////////////
0214     template <typename T, typename Ownership, typename Checking
0215       , typename Input, typename Storage>
0216     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0217           , true, false, false>
0218       : Checking, Input, Storage
0219     {
0220         multi_pass_unique() {}
0221         multi_pass_unique(T& x) : Input(x) {}
0222         multi_pass_unique(T const& x) : Input(x) {}
0223 
0224         template <typename MultiPass>
0225         static void destroy(MultiPass& mp)
0226         {
0227             Checking::destroy(mp);
0228             Input::destroy(mp);
0229             Storage::destroy(mp);
0230         }
0231 
0232         void swap(multi_pass_unique& x)
0233         {
0234             this->Checking::swap(x);
0235             this->Input::swap(x);
0236             this->Storage::swap(x);
0237         }
0238 
0239         template <typename MultiPass>
0240         inline static void clear_queue(MultiPass& mp)
0241         {
0242             Checking::clear_queue(mp);
0243             Storage::clear_queue(mp);
0244         }
0245 
0246         // ownership policy functions are forwarded to the Ownership type
0247         template <typename MultiPass>
0248         inline static void clone(MultiPass& mp)
0249             { Ownership::clone(mp); }
0250 
0251         template <typename MultiPass>
0252         inline static bool release(MultiPass& mp)
0253             { return Ownership::release(mp); }
0254 
0255         template <typename MultiPass>
0256         inline static bool is_unique(MultiPass const& mp)
0257             { return Ownership::is_unique(mp); }
0258     };
0259 
0260     ///////////////////////////////////////////////////////////////////////////
0261     template <typename T, typename Ownership, typename Checking
0262       , typename Input, typename Storage>
0263     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0264           , true, false, true>
0265       : Checking, Storage
0266     {
0267         multi_pass_unique() {}
0268         multi_pass_unique(T const&) {}
0269 
0270         template <typename MultiPass>
0271         static void destroy(MultiPass& mp)
0272         {
0273             Checking::destroy(mp);
0274             Input::destroy(mp);
0275             Storage::destroy(mp);
0276         }
0277 
0278         void swap(multi_pass_unique& x)
0279         {
0280             this->Checking::swap(x);
0281             this->Storage::swap(x);
0282         }
0283 
0284         template <typename MultiPass>
0285         inline static void clear_queue(MultiPass& mp)
0286         {
0287             Checking::clear_queue(mp);
0288             Storage::clear_queue(mp);
0289         }
0290 
0291         // implement input policy functions by forwarding to the Input type
0292         template <typename MultiPass>
0293         inline static void advance_input(MultiPass& mp)
0294             { Input::advance_input(mp); }
0295 
0296         template <typename MultiPass>
0297         inline static typename MultiPass::reference get_input(MultiPass& mp)
0298             { return Input::get_input(mp); }
0299 
0300         template <typename MultiPass>
0301         inline static bool input_at_eof(MultiPass const& mp)
0302             { return Input::input_at_eof(mp); }
0303 
0304         template <typename MultiPass, typename TokenType>
0305         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
0306             { return Input::input_is_valid(mp, curtok); }
0307 
0308         // ownership policy functions are forwarded to the Ownership type
0309         template <typename MultiPass>
0310         inline static void clone(MultiPass& mp)
0311             { Ownership::clone(mp); }
0312 
0313         template <typename MultiPass>
0314         inline static bool release(MultiPass& mp)
0315             { return Ownership::release(mp); }
0316 
0317         template <typename MultiPass>
0318         inline static bool is_unique(MultiPass const& mp)
0319             { return Ownership::is_unique(mp); }
0320     };
0321 
0322     ///////////////////////////////////////////////////////////////////////////
0323     template <typename T, typename Ownership, typename Checking
0324       , typename Input, typename Storage>
0325     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0326           , true, true, false>
0327       : Input, Storage
0328     {
0329         multi_pass_unique() {}
0330         multi_pass_unique(T& x) : Input(x) {}
0331         multi_pass_unique(T const& x) : Input(x) {}
0332 
0333         template <typename MultiPass>
0334         static void destroy(MultiPass& mp)
0335         {
0336             Input::destroy(mp);
0337             Storage::destroy(mp);
0338         }
0339 
0340         void swap(multi_pass_unique& x)
0341         {
0342             this->Input::swap(x);
0343             this->Storage::swap(x);
0344         }
0345 
0346         template <typename MultiPass>
0347         inline static void clear_queue(MultiPass& mp)
0348         {
0349             Checking::clear_queue(mp);
0350             Storage::clear_queue(mp);
0351         }
0352 
0353         // checking policy functions are forwarded to the Checking type
0354         template <typename MultiPass>
0355         inline static void docheck(MultiPass const& mp)
0356             { Checking::docheck(mp); }
0357 
0358         // ownership policy functions are forwarded to the Ownership type
0359         template <typename MultiPass>
0360         inline static void clone(MultiPass& mp)
0361             { Ownership::clone(mp); }
0362 
0363         template <typename MultiPass>
0364         inline static bool release(MultiPass& mp)
0365             { return Ownership::release(mp); }
0366 
0367         template <typename MultiPass>
0368         inline static bool is_unique(MultiPass const& mp)
0369             { return Ownership::is_unique(mp); }
0370     };
0371 
0372     ///////////////////////////////////////////////////////////////////////////
0373     template <typename T, typename Ownership, typename Checking
0374       , typename Input, typename Storage>
0375     struct multi_pass_unique<T, Ownership, Checking, Input, Storage
0376           , true, true, true>
0377       : Storage
0378     {
0379         multi_pass_unique() {}
0380         multi_pass_unique(T const&) {}
0381 
0382         template <typename MultiPass>
0383         static void destroy(MultiPass& mp)
0384         {
0385             Input::destroy(mp);
0386             Storage::destroy(mp);
0387         }
0388 
0389         void swap(multi_pass_unique& x)
0390         {
0391             this->Storage::swap(x);
0392         }
0393 
0394         template <typename MultiPass>
0395         inline static void clear_queue(MultiPass& mp)
0396         {
0397             Checking::clear_queue(mp);
0398             Storage::clear_queue(mp);
0399         }
0400 
0401         // implement input policy functions by forwarding to the Input type
0402         template <typename MultiPass>
0403         inline static void advance_input(MultiPass& mp)
0404             { Input::advance_input(mp); }
0405 
0406         template <typename MultiPass>
0407         inline static typename MultiPass::reference get_input(MultiPass& mp)
0408             { return Input::get_input(mp); }
0409 
0410         template <typename MultiPass>
0411         inline static bool input_at_eof(MultiPass const& mp)
0412             { return Input::input_at_eof(mp); }
0413 
0414         template <typename MultiPass, typename TokenType>
0415         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
0416             { return Input::input_is_valid(mp, curtok); }
0417 
0418         // checking policy functions are forwarded to the Checking type
0419         template <typename MultiPass>
0420         inline static void docheck(MultiPass const& mp)
0421             { Checking::docheck(mp); }
0422 
0423         // ownership policy functions are forwarded to the Ownership type
0424         template <typename MultiPass>
0425         inline static void clone(MultiPass& mp)
0426             { Ownership::clone(mp); }
0427 
0428         template <typename MultiPass>
0429         inline static bool release(MultiPass& mp)
0430             { return Ownership::release(mp); }
0431 
0432         template <typename MultiPass>
0433         inline static bool is_unique(MultiPass const& mp)
0434             { return Ownership::is_unique(mp); }
0435     };
0436 
0437     ///////////////////////////////////////////////////////////////////////////
0438     // the multi_pass_shared structure is used to combine the shared data items
0439     // of all policies into one single structure
0440     ///////////////////////////////////////////////////////////////////////////
0441     template<typename T, typename Ownership, typename Checking, typename Input
0442       , typename Storage>
0443     struct multi_pass_shared : Ownership, Checking, Input, Storage
0444     {
0445         explicit multi_pass_shared(T& input) : Input(input) {}
0446         explicit multi_pass_shared(T const& input) : Input(input) {}
0447     };
0448 
0449     ///////////////////////////////////////////////////////////////////////////
0450     //  This is a default implementation of a policy class as required by the
0451     //  multi_pass template, combining 4 separate policies into one. Any other
0452     //  multi_pass policy class needs to follow the scheme as shown below.
0453     template<typename Ownership, typename Checking, typename Input
0454       , typename Storage>
0455     struct default_policy
0456     {
0457         typedef Ownership ownership_policy;
0458         typedef Checking checking_policy;
0459         typedef Input input_policy;
0460         typedef Storage storage_policy;
0461 
0462         ///////////////////////////////////////////////////////////////////////
0463         template <typename T>
0464         struct unique : multi_pass_unique<T
0465           , typename Ownership::unique, typename Checking::unique
0466           , typename Input::BOOST_NESTED_TEMPLATE unique<T>
0467           , typename Storage::BOOST_NESTED_TEMPLATE unique<
0468                 typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
0469         {
0470             typedef typename Ownership::unique ownership_policy;
0471             typedef typename Checking::unique checking_policy;
0472             typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
0473                 input_policy;
0474             typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
0475                 typename input_policy::value_type> storage_policy;
0476 
0477             typedef multi_pass_unique<T, ownership_policy, checking_policy
0478               , input_policy, storage_policy> unique_base_type;
0479 
0480             unique() {}
0481             explicit unique(T& input) : unique_base_type(input) {}
0482             explicit unique(T const& input) : unique_base_type(input) {}
0483         };
0484 
0485         ///////////////////////////////////////////////////////////////////////
0486         template <typename T>
0487         struct shared : multi_pass_shared<T
0488           , typename Ownership::shared, typename Checking::shared
0489           , typename Input::BOOST_NESTED_TEMPLATE shared<T>
0490           , typename Storage::BOOST_NESTED_TEMPLATE shared<
0491                 typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
0492         {
0493             typedef typename Ownership::shared ownership_policy;
0494             typedef typename Checking::shared checking_policy;
0495             typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
0496                 input_policy;
0497             typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
0498                 typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
0499             storage_policy;
0500 
0501             typedef multi_pass_shared<T, ownership_policy, checking_policy
0502               , input_policy, storage_policy> shared_base_type;
0503 
0504             explicit shared(T& input)
0505               : shared_base_type(input), inhibit_clear_queue_(false) {}
0506             explicit shared(T const& input)
0507               : shared_base_type(input), inhibit_clear_queue_(false) {}
0508 
0509             // This is needed for the correct implementation of expectation
0510             // points. Normally expectation points flush any multi_pass
0511             // iterator they may act on, but if the corresponding error handler
0512             // is of type 'retry' no flushing of the internal buffers should be
0513             // executed (even if explicitly requested).
0514             bool inhibit_clear_queue_;
0515         };
0516     };
0517 
0518 }}}
0519 
0520 #endif