functor_input.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
  9. #define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED
  10. #include <boost/assert.hpp>
  11. #include <boost/spirit/include/classic_multi_pass.hpp>
  12. #include <boost/wave/wave_config.hpp>
  13. // this must occur after all of the includes and before any code appears
  14. #ifdef BOOST_HAS_ABI_HEADERS
  15. #include BOOST_ABI_PREFIX
  16. #endif
  17. ///////////////////////////////////////////////////////////////////////////////
  18. namespace boost {
  19. namespace wave {
  20. namespace util {
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. // class functor_input
  24. //
  25. // Implementation of the InputPolicy used by multi_pass
  26. // functor_input gets tokens from a functor
  27. // Note: the functor must have a typedef for result_type
  28. // It also must have a static variable of type result_type defined
  29. // to represent eof that is called eof.
  30. //
  31. // This functor input policy template is essentially the same as the
  32. // predefined multi_pass functor_input policy. The difference is,
  33. // that the first token is not read at initialization time, but only
  34. // just before returning the first token. Additionally it does not
  35. // call operator new() twice but only once.
  36. //
  37. ///////////////////////////////////////////////////////////////////////////////
  38. struct functor_input {
  39. template <typename FunctorT>
  40. class inner {
  41. private:
  42. typedef typename FunctorT::result_type result_type;
  43. public:
  44. typedef result_type value_type;
  45. private:
  46. struct Data {
  47. Data(FunctorT const &ftor_)
  48. : ftor(ftor_), was_initialized(false)
  49. {}
  50. FunctorT ftor;
  51. value_type curtok;
  52. bool was_initialized;
  53. };
  54. // Needed by compilers not implementing the resolution to DR45. For
  55. // reference, see
  56. // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
  57. friend struct Data;
  58. public:
  59. typedef std::ptrdiff_t difference_type;
  60. typedef result_type *pointer;
  61. typedef result_type &reference;
  62. protected:
  63. inner()
  64. : data(0)
  65. {}
  66. inner(FunctorT const &x)
  67. : data(new Data(x))
  68. {}
  69. inner(inner const &x)
  70. : data(x.data)
  71. {}
  72. void destroy()
  73. {
  74. delete data;
  75. data = 0;
  76. }
  77. bool same_input(inner const &x) const
  78. {
  79. return data == x.data;
  80. }
  81. void swap(inner &x)
  82. {
  83. boost::spirit::classic::impl::mp_swap(data, x.data);
  84. }
  85. void ensure_initialized() const
  86. {
  87. if (data && !data->was_initialized) {
  88. data->curtok = (data->ftor)(); // get the first token
  89. data->was_initialized = true;
  90. }
  91. }
  92. public:
  93. reference get_input() const
  94. {
  95. ensure_initialized();
  96. return data->curtok;
  97. }
  98. void advance_input()
  99. {
  100. BOOST_ASSERT(0 != data);
  101. data->curtok = (data->ftor)();
  102. data->was_initialized = true;
  103. }
  104. bool input_at_eof() const
  105. {
  106. ensure_initialized();
  107. return !data || data->curtok == data->ftor.eof;
  108. }
  109. FunctorT& get_functor() const
  110. {
  111. BOOST_ASSERT(0 != data);
  112. return data->ftor;
  113. }
  114. private:
  115. mutable Data *data;
  116. };
  117. };
  118. ///////////////////////////////////////////////////////////////////////////////
  119. } // namespace util
  120. } // namespace wave
  121. } // namespace boost
  122. // the suffix header occurs after all of the code
  123. #ifdef BOOST_HAS_ABI_HEADERS
  124. #include BOOST_ABI_SUFFIX
  125. #endif
  126. #endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)