123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- // Copyright (c) 2001-2012 Hartmut Kaiser
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #if !defined(BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
- #define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
- #include <boost/config.hpp>
- #include <boost/type_traits/is_empty.hpp>
- namespace boost { namespace spirit { namespace iterator_policies
- {
- ///////////////////////////////////////////////////////////////////////////
- // The purpose of the multi_pass_unique template is to eliminate
- // empty policy classes (policies not containing any data items) from the
- // multiple inheritance chain. This is necessary since some compilers
- // fail to apply the empty base optimization if multiple inheritance is
- // involved.
- // Additionally this can be used to combine separate policies into one
- // single multi_pass_policy as required by the multi_pass template
- ///////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
- // select the correct derived classes based on if a policy is empty
- template <typename T
- , typename Ownership, typename Checking, typename Input, typename Storage
- , bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
- , bool CheckingIsEmpty = boost::is_empty<Checking>::value
- , bool InputIsEmpty = boost::is_empty<Input>::value>
- struct multi_pass_unique;
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , false, false, false>
- : Ownership, Checking, Input, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T& x) : Input(x) {}
- multi_pass_unique(T const& x) : Input(x) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Ownership::destroy(mp);
- Checking::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Ownership::swap(x);
- this->Checking::swap(x);
- this->Input::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , false, false, true>
- : Ownership, Checking, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T const&) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Ownership::destroy(mp);
- Checking::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Ownership::swap(x);
- this->Checking::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // implement input policy functions by forwarding to the Input type
- template <typename MultiPass>
- inline static void advance_input(MultiPass& mp)
- { Input::advance_input(mp); }
- template <typename MultiPass>
- inline static typename MultiPass::reference get_input(MultiPass& mp)
- { return Input::get_input(mp); }
- template <typename MultiPass>
- inline static bool input_at_eof(MultiPass const& mp)
- { return Input::input_at_eof(mp); }
- template <typename MultiPass, typename TokenType>
- inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
- { return Input::input_is_valid(mp, curtok); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , false, true, false>
- : Ownership, Input, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T& x) : Input(x) {}
- multi_pass_unique(T const& x) : Input(x) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Ownership::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Ownership::swap(x);
- this->Input::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // checking policy functions are forwarded to the Checking type
- template <typename MultiPass>
- inline static void docheck(MultiPass const& mp)
- { Checking::docheck(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , false, true, true>
- : Ownership, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T const&) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Ownership::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Ownership::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // implement input policy functions by forwarding to the Input type
- template <typename MultiPass>
- inline static void advance_input(MultiPass& mp)
- { Input::advance_input(mp); }
- template <typename MultiPass>
- inline static typename MultiPass::reference get_input(MultiPass& mp)
- { return Input::get_input(mp); }
- template <typename MultiPass>
- inline static bool input_at_eof(MultiPass const& mp)
- { return Input::input_at_eof(mp); }
- template <typename MultiPass, typename TokenType>
- inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
- { return Input::input_is_valid(mp, curtok); }
- // checking policy functions are forwarded to the Checking type
- template <typename MultiPass>
- inline static void docheck(MultiPass const& mp)
- { Checking::docheck(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , true, false, false>
- : Checking, Input, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T& x) : Input(x) {}
- multi_pass_unique(T const& x) : Input(x) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Checking::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Checking::swap(x);
- this->Input::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // ownership policy functions are forwarded to the Ownership type
- template <typename MultiPass>
- inline static void clone(MultiPass& mp)
- { Ownership::clone(mp); }
- template <typename MultiPass>
- inline static bool release(MultiPass& mp)
- { return Ownership::release(mp); }
- template <typename MultiPass>
- inline static bool is_unique(MultiPass const& mp)
- { return Ownership::is_unique(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , true, false, true>
- : Checking, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T const&) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Checking::destroy(mp);
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Checking::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // implement input policy functions by forwarding to the Input type
- template <typename MultiPass>
- inline static void advance_input(MultiPass& mp)
- { Input::advance_input(mp); }
- template <typename MultiPass>
- inline static typename MultiPass::reference get_input(MultiPass& mp)
- { return Input::get_input(mp); }
- template <typename MultiPass>
- inline static bool input_at_eof(MultiPass const& mp)
- { return Input::input_at_eof(mp); }
- template <typename MultiPass, typename TokenType>
- inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
- { return Input::input_is_valid(mp, curtok); }
- // ownership policy functions are forwarded to the Ownership type
- template <typename MultiPass>
- inline static void clone(MultiPass& mp)
- { Ownership::clone(mp); }
- template <typename MultiPass>
- inline static bool release(MultiPass& mp)
- { return Ownership::release(mp); }
- template <typename MultiPass>
- inline static bool is_unique(MultiPass const& mp)
- { return Ownership::is_unique(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , true, true, false>
- : Input, Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T& x) : Input(x) {}
- multi_pass_unique(T const& x) : Input(x) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Input::swap(x);
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // checking policy functions are forwarded to the Checking type
- template <typename MultiPass>
- inline static void docheck(MultiPass const& mp)
- { Checking::docheck(mp); }
- // ownership policy functions are forwarded to the Ownership type
- template <typename MultiPass>
- inline static void clone(MultiPass& mp)
- { Ownership::clone(mp); }
- template <typename MultiPass>
- inline static bool release(MultiPass& mp)
- { return Ownership::release(mp); }
- template <typename MultiPass>
- inline static bool is_unique(MultiPass const& mp)
- { return Ownership::is_unique(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Ownership, typename Checking
- , typename Input, typename Storage>
- struct multi_pass_unique<T, Ownership, Checking, Input, Storage
- , true, true, true>
- : Storage
- {
- multi_pass_unique() {}
- multi_pass_unique(T const&) {}
- template <typename MultiPass>
- static void destroy(MultiPass& mp)
- {
- Input::destroy(mp);
- Storage::destroy(mp);
- }
- void swap(multi_pass_unique& x)
- {
- this->Storage::swap(x);
- }
- template <typename MultiPass>
- inline static void clear_queue(MultiPass& mp)
- {
- Checking::clear_queue(mp);
- Storage::clear_queue(mp);
- }
- // implement input policy functions by forwarding to the Input type
- template <typename MultiPass>
- inline static void advance_input(MultiPass& mp)
- { Input::advance_input(mp); }
- template <typename MultiPass>
- inline static typename MultiPass::reference get_input(MultiPass& mp)
- { return Input::get_input(mp); }
- template <typename MultiPass>
- inline static bool input_at_eof(MultiPass const& mp)
- { return Input::input_at_eof(mp); }
- template <typename MultiPass, typename TokenType>
- inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
- { return Input::input_is_valid(mp, curtok); }
- // checking policy functions are forwarded to the Checking type
- template <typename MultiPass>
- inline static void docheck(MultiPass const& mp)
- { Checking::docheck(mp); }
- // ownership policy functions are forwarded to the Ownership type
- template <typename MultiPass>
- inline static void clone(MultiPass& mp)
- { Ownership::clone(mp); }
- template <typename MultiPass>
- inline static bool release(MultiPass& mp)
- { return Ownership::release(mp); }
- template <typename MultiPass>
- inline static bool is_unique(MultiPass const& mp)
- { return Ownership::is_unique(mp); }
- };
- ///////////////////////////////////////////////////////////////////////////
- // the multi_pass_shared structure is used to combine the shared data items
- // of all policies into one single structure
- ///////////////////////////////////////////////////////////////////////////
- template<typename T, typename Ownership, typename Checking, typename Input
- , typename Storage>
- struct multi_pass_shared : Ownership, Checking, Input, Storage
- {
- explicit multi_pass_shared(T& input) : Input(input) {}
- explicit multi_pass_shared(T const& input) : Input(input) {}
- };
- ///////////////////////////////////////////////////////////////////////////
- // This is a default implementation of a policy class as required by the
- // multi_pass template, combining 4 separate policies into one. Any other
- // multi_pass policy class needs to follow the scheme as shown below.
- template<typename Ownership, typename Checking, typename Input
- , typename Storage>
- struct default_policy
- {
- typedef Ownership ownership_policy;
- typedef Checking checking_policy;
- typedef Input input_policy;
- typedef Storage storage_policy;
- ///////////////////////////////////////////////////////////////////////
- template <typename T>
- struct unique : multi_pass_unique<T
- , typename Ownership::unique, typename Checking::unique
- , typename Input::BOOST_NESTED_TEMPLATE unique<T>
- , typename Storage::BOOST_NESTED_TEMPLATE unique<
- typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
- {
- typedef typename Ownership::unique ownership_policy;
- typedef typename Checking::unique checking_policy;
- typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
- input_policy;
- typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
- typename input_policy::value_type> storage_policy;
- typedef multi_pass_unique<T, ownership_policy, checking_policy
- , input_policy, storage_policy> unique_base_type;
- unique() {}
- explicit unique(T& input) : unique_base_type(input) {}
- explicit unique(T const& input) : unique_base_type(input) {}
- };
- ///////////////////////////////////////////////////////////////////////
- template <typename T>
- struct shared : multi_pass_shared<T
- , typename Ownership::shared, typename Checking::shared
- , typename Input::BOOST_NESTED_TEMPLATE shared<T>
- , typename Storage::BOOST_NESTED_TEMPLATE shared<
- typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
- {
- typedef typename Ownership::shared ownership_policy;
- typedef typename Checking::shared checking_policy;
- typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
- input_policy;
- typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
- typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
- storage_policy;
- typedef multi_pass_shared<T, ownership_policy, checking_policy
- , input_policy, storage_policy> shared_base_type;
- explicit shared(T& input)
- : shared_base_type(input), inhibit_clear_queue_(false) {}
- explicit shared(T const& input)
- : shared_base_type(input), inhibit_clear_queue_(false) {}
- // This is needed for the correct implementation of expectation
- // points. Normally expectation points flush any multi_pass
- // iterator they may act on, but if the corresponding error handler
- // is of type 'retry' no flushing of the internal buffers should be
- // executed (even if explicitly requested).
- bool inhibit_clear_queue_;
- };
- };
- }}}
- #endif
|