istream_policy.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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_ISTREAM_POLICY_JAN_04_2010_0130PM)
  7. #define BOOST_SPIRIT_ISTREAM_POLICY_JAN_04_2010_0130PM
  8. #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
  9. #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
  10. namespace boost { namespace spirit { namespace iterator_policies
  11. {
  12. ///////////////////////////////////////////////////////////////////////////
  13. // class istream
  14. // Implementation of the InputPolicy used by multi_pass
  15. //
  16. // The istream encapsulates an std::basic_istream
  17. ///////////////////////////////////////////////////////////////////////////
  18. struct istream
  19. {
  20. ///////////////////////////////////////////////////////////////////////
  21. template <typename T>
  22. class unique // : public detail::default_input_policy
  23. {
  24. private:
  25. typedef typename T::char_type result_type;
  26. public:
  27. typedef typename T::off_type difference_type;
  28. typedef typename T::off_type distance_type;
  29. typedef result_type const* pointer;
  30. typedef result_type const& reference;
  31. typedef result_type value_type;
  32. protected:
  33. unique() {}
  34. explicit unique(T&) {}
  35. void swap(unique&) {}
  36. public:
  37. template <typename MultiPass>
  38. static void destroy(MultiPass&) {}
  39. template <typename MultiPass>
  40. static typename MultiPass::reference get_input(MultiPass& mp)
  41. {
  42. if (!mp.shared()->initialized_)
  43. mp.shared()->read_one();
  44. return mp.shared()->curtok_;
  45. }
  46. template <typename MultiPass>
  47. static void advance_input(MultiPass& mp)
  48. {
  49. // We invalidate the currently cached input character to avoid
  50. // reading more input from the underlying iterator than
  51. // required. Without this we would always read ahead one
  52. // character, even if this character never gets consumed by the
  53. // client.
  54. mp.shared()->peek_one();
  55. }
  56. // test, whether we reached the end of the underlying stream
  57. template <typename MultiPass>
  58. static bool input_at_eof(MultiPass const& mp)
  59. {
  60. return mp.shared()->eof_reached_;
  61. }
  62. template <typename MultiPass>
  63. static bool input_is_valid(MultiPass const& mp, value_type const&)
  64. {
  65. return mp.shared()->initialized_;
  66. }
  67. // no unique data elements
  68. };
  69. ///////////////////////////////////////////////////////////////////////
  70. template <typename T>
  71. struct shared
  72. {
  73. private:
  74. typedef typename T::char_type result_type;
  75. public:
  76. explicit shared(T& input)
  77. : input_(input), curtok_(-1)
  78. , initialized_(false), eof_reached_(false)
  79. {
  80. peek_one(); // istreams may be at eof right in the beginning
  81. }
  82. void read_one()
  83. {
  84. if (!(input_ >> curtok_)) {
  85. initialized_ = false;
  86. eof_reached_ = true;
  87. }
  88. else {
  89. initialized_ = true;
  90. }
  91. }
  92. void peek_one()
  93. {
  94. input_.peek(); // try for eof
  95. initialized_ = false;
  96. eof_reached_ = input_.eof();
  97. }
  98. T& input_;
  99. result_type curtok_;
  100. bool initialized_;
  101. bool eof_reached_;
  102. };
  103. };
  104. }}}
  105. #endif