Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //  Copyright (c) 2001, Daniel C. Nuffer
0002 //  Copyright (c) 2001-2011 Hartmut Kaiser
0003 //  http://spirit.sourceforge.net/
0004 //
0005 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
0009 #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
0010 
0011 #include <boost/config.hpp>
0012 #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
0013 #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
0014 #include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
0015 #include <boost/limits.hpp>
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/core/invoke_swap.hpp>
0018 #include <boost/utility/base_from_member.hpp>
0019 
0020 namespace boost { namespace spirit
0021 {
0022     ///////////////////////////////////////////////////////////////////////////
0023     // The default multi_pass instantiation uses a ref-counted std_deque scheme.
0024     ///////////////////////////////////////////////////////////////////////////
0025     template<typename T, typename Policies>
0026     class multi_pass
0027       : private boost::base_from_member<
0028             typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
0029       , public Policies::BOOST_NESTED_TEMPLATE unique<T>
0030     {
0031     private:
0032         // unique and shared data types
0033         typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T>
0034             policies_base_type;
0035         typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T>
0036             shared_data_type;
0037 
0038         typedef boost::base_from_member<shared_data_type*> member_base;
0039 
0040         // define the types the standard embedded iterator typedefs are taken
0041         // from
0042         typedef typename policies_base_type::input_policy iterator_type;
0043 
0044     public:
0045         // standard iterator typedefs
0046         typedef std::forward_iterator_tag iterator_category;
0047         typedef typename iterator_type::value_type value_type;
0048         typedef typename iterator_type::difference_type difference_type;
0049         typedef typename iterator_type::distance_type distance_type;
0050         typedef typename iterator_type::reference reference;
0051         typedef typename iterator_type::pointer pointer;
0052 
0053         multi_pass() : member_base(static_cast<shared_data_type*>(0)) {}
0054 
0055         explicit multi_pass(T& input)
0056           : member_base(new shared_data_type(input)), policies_base_type(input) {}
0057 
0058         explicit multi_pass(T const& input)
0059           : member_base(new shared_data_type(input)), policies_base_type(input) {}
0060 
0061         multi_pass(multi_pass const& x)
0062           : member_base(x.member), policies_base_type(x)
0063         {
0064             policies_base_type::clone(*this);
0065         }
0066 
0067 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
0068         // The standard library shipped with gcc-3.1 has a bug in
0069         // bits/basic_string.tcc. It tries to use iter::iter(0) to
0070         // construct an iterator. Ironically, this  happens in sanity
0071         // checking code that isn't required by the standard.
0072         // The workaround is to provide an additional constructor that
0073         // ignores its int argument and behaves like the default constructor.
0074         multi_pass(int) : member_base(static_cast<shared_data_type*>(0)) {}
0075 #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
0076 
0077         ~multi_pass()
0078         {
0079             if (policies_base_type::release(*this)) {
0080                 policies_base_type::destroy(*this);
0081                 delete this->member;
0082             }
0083         }
0084 
0085         multi_pass& operator=(multi_pass const& x)
0086         {
0087             if (this != &x) {
0088                 multi_pass temp(x);
0089                 temp.swap(*this);
0090             }
0091             return *this;
0092         }
0093 
0094         void swap(multi_pass& x)
0095         {
0096             boost::core::invoke_swap(this->member, x.member);
0097             this->policies_base_type::swap(x);
0098         }
0099 
0100         reference operator*() const
0101         {
0102             policies_base_type::docheck(*this);
0103             return policies_base_type::dereference(*this);
0104         }
0105         pointer operator->() const
0106         {
0107             return &(operator*());
0108         }
0109 
0110         multi_pass& operator++()
0111         {
0112             policies_base_type::docheck(*this);
0113             policies_base_type::increment(*this);
0114             return *this;
0115         }
0116         multi_pass operator++(int)
0117         {
0118             multi_pass tmp(*this);
0119             ++*this;
0120             return tmp;
0121         }
0122 
0123         void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode =
0124             traits::clear_mode::clear_if_enabled)
0125         {
0126             if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
0127                 policies_base_type::clear_queue(*this);
0128         }
0129         bool inhibit_clear_queue() const
0130         {
0131             return this->member->inhibit_clear_queue_;
0132         }
0133         void inhibit_clear_queue(bool flag)
0134         {
0135             this->member->inhibit_clear_queue_ = flag;
0136         }
0137 
0138         bool operator==(multi_pass const& y) const
0139         {
0140             if (is_eof())
0141                 return y.is_eof();
0142             if (y.is_eof())
0143                 return false;
0144 
0145             return policies_base_type::equal_to(*this, y);
0146         }
0147         bool operator<(multi_pass const& y) const
0148         {
0149             return policies_base_type::less_than(*this, y);
0150         }
0151 
0152         bool operator!=(multi_pass const& y) const
0153         {
0154             return !(*this == y);
0155         }
0156         bool operator>(multi_pass const& y) const
0157         {
0158             return y < *this;
0159         }
0160         bool operator>=(multi_pass const& y) const
0161         {
0162             return !(*this < y);
0163         }
0164         bool operator<=(multi_pass const& y) const
0165         {
0166             return !(y < *this);
0167         }
0168 
0169         // allow access to base member
0170         shared_data_type* shared() const { return this->member; }
0171 
0172     private: // helper functions
0173         bool is_eof() const
0174         {
0175             return (0 == this->member) || policies_base_type::is_eof(*this);
0176         }
0177     };
0178 
0179     ///////////////////////////////////////////////////////////////////////////
0180     //  Generator function
0181     ///////////////////////////////////////////////////////////////////////////
0182     template <typename Policies, typename T>
0183     inline multi_pass<T, Policies>
0184     make_multi_pass(T& i)
0185     {
0186         return multi_pass<T, Policies>(i);
0187     }
0188     template <typename Policies, typename T>
0189     inline multi_pass<T, Policies>
0190     make_multi_pass(T const& i)
0191     {
0192         return multi_pass<T, Policies>(i);
0193     }
0194 
0195     ///////////////////////////////////////////////////////////////////////////
0196     template <typename T>
0197     inline multi_pass<T>
0198     make_default_multi_pass(T& i)
0199     {
0200         return multi_pass<T>(i);
0201     }
0202     template <typename T>
0203     inline multi_pass<T>
0204     make_default_multi_pass(T const& i)
0205     {
0206         return multi_pass<T>(i);
0207     }
0208 
0209     ///////////////////////////////////////////////////////////////////////////
0210     template <typename T, typename Policies>
0211     inline void
0212     swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
0213     {
0214         x.swap(y);
0215     }
0216 
0217     ///////////////////////////////////////////////////////////////////////////
0218     // define special functions allowing to integrate any multi_pass iterator
0219     // with expectation points
0220     namespace traits
0221     {
0222         template <typename T, typename Policies>
0223         void clear_queue(multi_pass<T, Policies>& mp
0224           , BOOST_SCOPED_ENUM(traits::clear_mode) mode)
0225         {
0226             mp.clear_queue(mode);
0227         }
0228 
0229         template <typename T, typename Policies>
0230         void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
0231         {
0232             mp.inhibit_clear_queue(flag);
0233         }
0234 
0235         template <typename T, typename Policies>
0236         bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
0237         {
0238             return mp.inhibit_clear_queue();
0239         }
0240     }
0241 
0242 }} // namespace boost::spirit
0243 
0244 #endif
0245 
0246