| // Copyright (c) 2001, Daniel C. Nuffer |
| // Copyright (c) 2001-2010 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_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM) |
| #define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM |
| |
| #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp> |
| #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp> |
| #include <boost/config.hpp> |
| #include <boost/throw_exception.hpp> |
| #include <exception> // for std::exception |
| |
| namespace boost { namespace spirit { namespace iterator_policies |
| { |
| /////////////////////////////////////////////////////////////////////////// |
| // class illegal_backtracking |
| // thrown by buf_id_check CheckingPolicy if an instance of an iterator is |
| // used after another one has invalidated the queue |
| /////////////////////////////////////////////////////////////////////////// |
| class illegal_backtracking : public std::exception |
| { |
| public: |
| illegal_backtracking() throw() {} |
| ~illegal_backtracking() throw() {} |
| |
| char const* what() const throw() |
| { |
| return "boost::spirit::multi_pass::illegal_backtracking"; |
| } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // class buf_id_check |
| // Implementation of the CheckingPolicy used by multi_pass |
| // This policy is most effective when used together with the std_deque |
| // StoragePolicy. |
| // |
| // If used with the fixed_size_queue StoragePolicy, it will not detect |
| // iterator dereferences that are out of the range of the queue. |
| /////////////////////////////////////////////////////////////////////////////// |
| struct buf_id_check |
| { |
| /////////////////////////////////////////////////////////////////////// |
| struct unique //: detail::default_checking_policy |
| { |
| unique() : buf_id(0) {} |
| unique(unique const& x) : buf_id(x.buf_id) {} |
| |
| void swap(unique& x) |
| { |
| boost::swap(buf_id, x.buf_id); |
| } |
| |
| // called to verify that everything is ok. |
| template <typename MultiPass> |
| static void docheck(MultiPass const& mp) |
| { |
| if (mp.buf_id != mp.shared()->shared_buf_id) |
| boost::throw_exception(illegal_backtracking()); |
| } |
| |
| // called from multi_pass::clear_queue, so we can increment the count |
| template <typename MultiPass> |
| static void clear_queue(MultiPass& mp) |
| { |
| ++mp.shared()->shared_buf_id; |
| ++mp.buf_id; |
| } |
| |
| template <typename MultiPass> |
| static void destroy(MultiPass&) {} |
| |
| protected: |
| unsigned long buf_id; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////// |
| struct shared |
| { |
| shared() : shared_buf_id(0) {} |
| unsigned long shared_buf_id; |
| }; |
| }; |
| |
| }}} |
| |
| #endif |