matchable.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // matchable.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. 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. #ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/assert.hpp>
  14. #include <boost/mpl/assert.hpp>
  15. #include <boost/intrusive_ptr.hpp>
  16. #include <boost/throw_exception.hpp>
  17. #include <boost/type_traits/is_same.hpp>
  18. #include <boost/xpressive/detail/core/quant_style.hpp>
  19. #include <boost/xpressive/detail/utility/counted_base.hpp>
  20. #include <boost/xpressive/detail/detail_fwd.hpp>
  21. #include <boost/xpressive/detail/dynamic/sequence.hpp>
  22. #include <boost/xpressive/regex_error.hpp>
  23. namespace boost { namespace xpressive { namespace detail
  24. {
  25. //////////////////////////////////////////////////////////////////////////
  26. // quant_spec
  27. struct quant_spec
  28. {
  29. unsigned int min_;
  30. unsigned int max_;
  31. bool greedy_;
  32. std::size_t *hidden_mark_count_;
  33. };
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // matchable
  36. template<typename BidiIter>
  37. struct matchable
  38. {
  39. typedef BidiIter iterator_type;
  40. typedef typename iterator_value<iterator_type>::type char_type;
  41. virtual ~matchable() {}
  42. virtual bool match(match_state<BidiIter> &state) const = 0;
  43. };
  44. ///////////////////////////////////////////////////////////////////////////////
  45. // matchable_ex
  46. template<typename BidiIter>
  47. struct matchable_ex
  48. : matchable<BidiIter>
  49. , counted_base<matchable_ex<BidiIter> >
  50. {
  51. typedef BidiIter iterator_type;
  52. typedef typename iterator_value<iterator_type>::type char_type;
  53. virtual void link(xpression_linker<char_type> &) const
  54. {
  55. }
  56. virtual void peek(xpression_peeker<char_type> &peeker) const
  57. {
  58. peeker.fail();
  59. }
  60. virtual void repeat(quant_spec const &, sequence<BidiIter> &) const
  61. {
  62. BOOST_THROW_EXCEPTION(
  63. regex_error(regex_constants::error_badrepeat, "expression cannot be quantified")
  64. );
  65. }
  66. ///////////////////////////////////////////////////////////////////////////////////////////////
  67. // The following 4 functions (push_match, top_match, pop_match and skip_match) are
  68. // used to implement looping and branching across the matchers. Call push_match to record
  69. // a position. Then, another matcher further down the xpression chain has the
  70. // option to call either top_match, pop_match or skip_match. top_match and pop_match will
  71. // jump back to the place recorded by push_match, whereas skip_match will skip the jump and
  72. // pass execution down the xpression chain. top_match will leave the xpression on top of the
  73. // stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for
  74. // statically bound xpressions and one for dynamically bound xpressions.
  75. //
  76. template<typename Top>
  77. bool push_match(match_state<BidiIter> &state) const
  78. {
  79. BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
  80. return this->match(state);
  81. }
  82. static bool top_match(match_state<BidiIter> &state, void const *top)
  83. {
  84. return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
  85. }
  86. static bool pop_match(match_state<BidiIter> &state, void const *top)
  87. {
  88. return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
  89. }
  90. bool skip_match(match_state<BidiIter> &state) const
  91. {
  92. return this->match(state);
  93. }
  94. };
  95. ///////////////////////////////////////////////////////////////////////////////
  96. // shared_matchable
  97. template<typename BidiIter>
  98. struct shared_matchable
  99. {
  100. typedef BidiIter iterator_type;
  101. typedef typename iterator_value<BidiIter>::type char_type;
  102. typedef intrusive_ptr<matchable_ex<BidiIter> const> matchable_ptr;
  103. BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value);
  104. BOOST_STATIC_CONSTANT(bool, pure = false);
  105. shared_matchable(matchable_ptr const &xpr = matchable_ptr())
  106. : xpr_(xpr)
  107. {
  108. }
  109. bool operator !() const
  110. {
  111. return !this->xpr_;
  112. }
  113. friend bool operator ==(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
  114. {
  115. return left.xpr_ == right.xpr_;
  116. }
  117. friend bool operator !=(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
  118. {
  119. return left.xpr_ != right.xpr_;
  120. }
  121. matchable_ptr const &matchable() const
  122. {
  123. return this->xpr_;
  124. }
  125. bool match(match_state<BidiIter> &state) const
  126. {
  127. return this->xpr_->match(state);
  128. }
  129. void link(xpression_linker<char_type> &linker) const
  130. {
  131. this->xpr_->link(linker);
  132. }
  133. void peek(xpression_peeker<char_type> &peeker) const
  134. {
  135. this->xpr_->peek(peeker);
  136. }
  137. // BUGBUG yuk!
  138. template<typename Top>
  139. bool push_match(match_state<BidiIter> &state) const
  140. {
  141. BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
  142. return this->match(state);
  143. }
  144. private:
  145. matchable_ptr xpr_;
  146. };
  147. }}} // namespace boost::xpressive::detail
  148. #endif