functor_input_policy.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M)
  6. #define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M
  7. #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
  8. #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
  9. #include <boost/assert.hpp>
  10. namespace boost { namespace spirit { namespace iterator_policies
  11. {
  12. namespace is_valid_test_
  13. {
  14. template <typename Token>
  15. inline bool token_is_valid(Token const&)
  16. {
  17. return true;
  18. }
  19. }
  20. ///////////////////////////////////////////////////////////////////////////
  21. // class functor_input
  22. // Implementation of the InputPolicy used by multi_pass
  23. // functor_input gets tokens from a functor
  24. //
  25. // Note: the functor must have a typedef for result_type
  26. // It also must have a static variable of type result_type defined
  27. // to represent EOF that is called eof.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////
  30. struct functor_input
  31. {
  32. ///////////////////////////////////////////////////////////////////////
  33. template <typename Functor>
  34. class unique : public detail::default_input_policy
  35. {
  36. private:
  37. typedef typename Functor::result_type result_type;
  38. protected:
  39. unique() {}
  40. explicit unique(Functor const& x) : ftor(x) {}
  41. void swap(unique& x)
  42. {
  43. boost::swap(ftor, x.ftor);
  44. }
  45. public:
  46. typedef result_type value_type;
  47. typedef std::ptrdiff_t difference_type;
  48. typedef std::ptrdiff_t distance_type;
  49. typedef result_type* pointer;
  50. typedef result_type& reference;
  51. public:
  52. // get the next token
  53. template <typename MultiPass>
  54. static typename MultiPass::reference get_input(MultiPass& mp)
  55. {
  56. value_type& curtok = mp.shared()->curtok;
  57. if (!input_is_valid(mp, curtok))
  58. curtok = mp.ftor();
  59. return curtok;
  60. }
  61. template <typename MultiPass>
  62. static void advance_input(MultiPass& mp)
  63. {
  64. // if mp.shared is NULL then this instance of the multi_pass
  65. // represents a end iterator
  66. BOOST_ASSERT(0 != mp.shared());
  67. mp.shared()->curtok = mp.ftor();
  68. }
  69. // test, whether we reached the end of the underlying stream
  70. template <typename MultiPass>
  71. static bool input_at_eof(MultiPass const& mp)
  72. {
  73. return mp.shared()->curtok == mp.ftor.eof;
  74. }
  75. template <typename MultiPass>
  76. static bool input_is_valid(MultiPass const&, value_type const& t)
  77. {
  78. using namespace is_valid_test_;
  79. return token_is_valid(t);
  80. }
  81. Functor& get_functor() const
  82. {
  83. return ftor;
  84. }
  85. protected:
  86. mutable Functor ftor;
  87. };
  88. ///////////////////////////////////////////////////////////////////////
  89. template <typename Functor>
  90. struct shared
  91. {
  92. explicit shared(Functor const&) : curtok(0) {}
  93. typename Functor::result_type curtok;
  94. };
  95. };
  96. }}}
  97. #endif