buf_id_check_policy.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. #if !defined(BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM)
  7. #define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM
  8. #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
  9. #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
  10. #include <boost/config.hpp>
  11. #include <boost/throw_exception.hpp>
  12. #include <exception> // for std::exception
  13. namespace boost { namespace spirit { namespace iterator_policies
  14. {
  15. ///////////////////////////////////////////////////////////////////////////
  16. // class illegal_backtracking
  17. // thrown by buf_id_check CheckingPolicy if an instance of an iterator is
  18. // used after another one has invalidated the queue
  19. ///////////////////////////////////////////////////////////////////////////
  20. class BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception
  21. {
  22. public:
  23. illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
  24. ~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
  25. char const* what() const BOOST_NOEXCEPT_OR_NOTHROW
  26. {
  27. return "boost::spirit::multi_pass::illegal_backtracking";
  28. }
  29. };
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // class buf_id_check
  32. // Implementation of the CheckingPolicy used by multi_pass
  33. // This policy is most effective when used together with the std_deque
  34. // StoragePolicy.
  35. //
  36. // If used with the fixed_size_queue StoragePolicy, it will not detect
  37. // iterator dereferences that are out of the range of the queue.
  38. ///////////////////////////////////////////////////////////////////////////////
  39. struct buf_id_check
  40. {
  41. ///////////////////////////////////////////////////////////////////////
  42. struct unique //: detail::default_checking_policy
  43. {
  44. unique() : buf_id(0) {}
  45. unique(unique const& x) : buf_id(x.buf_id) {}
  46. void swap(unique& x)
  47. {
  48. boost::swap(buf_id, x.buf_id);
  49. }
  50. // called to verify that everything is ok.
  51. template <typename MultiPass>
  52. static void docheck(MultiPass const& mp)
  53. {
  54. if (mp.buf_id != mp.shared()->shared_buf_id)
  55. boost::throw_exception(illegal_backtracking());
  56. }
  57. // called from multi_pass::clear_queue, so we can increment the count
  58. template <typename MultiPass>
  59. static void clear_queue(MultiPass& mp)
  60. {
  61. ++mp.shared()->shared_buf_id;
  62. ++mp.buf_id;
  63. }
  64. template <typename MultiPass>
  65. static void destroy(MultiPass&) {}
  66. protected:
  67. unsigned long buf_id;
  68. };
  69. ///////////////////////////////////////////////////////////////////////
  70. struct shared
  71. {
  72. shared() : shared_buf_id(0) {}
  73. unsigned long shared_buf_id;
  74. };
  75. };
  76. }}}
  77. #endif