Line data Source code
1 : // Copyright (c) 2001, Daniel C. Nuffer 2 : // Copyright (c) 2001-2011 Hartmut Kaiser 3 : // 4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 : 7 : #if !defined(BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM) 8 : #define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM 9 : 10 : #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp> 11 : #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp> 12 : #include <boost/config.hpp> 13 : #include <boost/throw_exception.hpp> 14 : #include <exception> // for std::exception 15 : 16 : namespace boost { namespace spirit { namespace iterator_policies 17 : { 18 : /////////////////////////////////////////////////////////////////////////// 19 : // class illegal_backtracking 20 : // thrown by buf_id_check CheckingPolicy if an instance of an iterator is 21 : // used after another one has invalidated the queue 22 : /////////////////////////////////////////////////////////////////////////// 23 : class BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception 24 : { 25 : public: 26 : illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {} 27 : ~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {} 28 : 29 0 : char const* what() const BOOST_NOEXCEPT_OR_NOTHROW 30 : { 31 0 : return "boost::spirit::multi_pass::illegal_backtracking"; 32 : } 33 : }; 34 : 35 : /////////////////////////////////////////////////////////////////////////////// 36 : // class buf_id_check 37 : // Implementation of the CheckingPolicy used by multi_pass 38 : // This policy is most effective when used together with the std_deque 39 : // StoragePolicy. 40 : // 41 : // If used with the fixed_size_queue StoragePolicy, it will not detect 42 : // iterator dereferences that are out of the range of the queue. 43 : /////////////////////////////////////////////////////////////////////////////// 44 : struct buf_id_check 45 : { 46 : /////////////////////////////////////////////////////////////////////// 47 : struct unique //: detail::default_checking_policy 48 : { 49 : unique() : buf_id(0) {} 50 : unique(unique const& x) : buf_id(x.buf_id) {} 51 : 52 : void swap(unique& x) 53 : { 54 : boost::swap(buf_id, x.buf_id); 55 : } 56 : 57 : // called to verify that everything is ok. 58 : template <typename MultiPass> 59 : static void docheck(MultiPass const& mp) 60 : { 61 : if (mp.buf_id != mp.shared()->shared_buf_id) 62 : boost::throw_exception(illegal_backtracking()); 63 : } 64 : 65 : // called from multi_pass::clear_queue, so we can increment the count 66 : template <typename MultiPass> 67 : static void clear_queue(MultiPass& mp) 68 : { 69 : ++mp.shared()->shared_buf_id; 70 : ++mp.buf_id; 71 : } 72 : 73 : template <typename MultiPass> 74 : static void destroy(MultiPass&) {} 75 : 76 : protected: 77 : unsigned long buf_id; 78 : }; 79 : 80 : /////////////////////////////////////////////////////////////////////// 81 : struct shared 82 : { 83 : shared() : shared_buf_id(0) {} 84 : unsigned long shared_buf_id; 85 : }; 86 : }; 87 : 88 : }}} 89 : 90 : #endif