alternate_matcher.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // alternate_matcher.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_CORE_MATCHER_ALTERNATE_MATCHER_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ALTERNATE_MATCHER_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/version.hpp>
  14. #if BOOST_VERSION <= 103200
  15. // WORKAROUND for Fusion bug in Boost 1.32
  16. namespace boost { namespace fusion
  17. {
  18. namespace detail { struct iterator_root; }
  19. using detail::iterator_root;
  20. }}
  21. #endif
  22. #include <boost/xpressive/detail/detail_fwd.hpp>
  23. #include <boost/xpressive/detail/core/quant_style.hpp>
  24. #include <boost/xpressive/detail/core/state.hpp>
  25. #include <boost/xpressive/detail/dynamic/matchable.hpp>
  26. #include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
  27. #include <boost/xpressive/detail/utility/algorithm.hpp>
  28. #include <boost/xpressive/detail/utility/any.hpp>
  29. namespace boost { namespace xpressive { namespace detail
  30. {
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // alt_match_pred
  33. //
  34. template<typename BidiIter, typename Next>
  35. struct alt_match_pred
  36. {
  37. alt_match_pred(match_state<BidiIter> &state)
  38. : state_(&state)
  39. {
  40. }
  41. template<typename Xpr>
  42. bool operator ()(Xpr const &xpr) const
  43. {
  44. return xpr.BOOST_NESTED_TEMPLATE push_match<Next>(*this->state_);
  45. }
  46. private:
  47. match_state<BidiIter> *state_;
  48. };
  49. ///////////////////////////////////////////////////////////////////////////////
  50. // alt_match
  51. //
  52. template<typename BidiIter, typename Next>
  53. inline bool alt_match
  54. (
  55. alternates_vector<BidiIter> const &alts, match_state<BidiIter> &state, Next const &
  56. )
  57. {
  58. return detail::any(alts.begin(), alts.end(), alt_match_pred<BidiIter, Next>(state));
  59. }
  60. template<typename Head, typename Tail, typename BidiIter, typename Next>
  61. inline bool alt_match
  62. (
  63. alternates_list<Head, Tail> const &alts, match_state<BidiIter> &state, Next const &
  64. )
  65. {
  66. return fusion::any(alts, alt_match_pred<BidiIter, Next>(state));
  67. }
  68. ///////////////////////////////////////////////////////////////////////////////
  69. // alternate_matcher
  70. template<typename Alternates, typename Traits>
  71. struct alternate_matcher
  72. : quant_style<
  73. Alternates::width != unknown_width::value && Alternates::pure ? quant_fixed_width : quant_variable_width
  74. , Alternates::width
  75. , Alternates::pure
  76. >
  77. {
  78. typedef Alternates alternates_type;
  79. typedef typename Traits::char_type char_type;
  80. Alternates alternates_;
  81. mutable hash_peek_bitset<char_type> bset_;
  82. explicit alternate_matcher(Alternates const &alternates = Alternates())
  83. : alternates_(alternates)
  84. , bset_()
  85. {
  86. }
  87. template<typename BidiIter, typename Next>
  88. bool match(match_state<BidiIter> &state, Next const &next) const
  89. {
  90. if(!state.eos() && !this->can_match_(*state.cur_, traits_cast<Traits>(state)))
  91. {
  92. return false;
  93. }
  94. return detail::alt_match(this->alternates_, state, next);
  95. }
  96. detail::width get_width() const
  97. {
  98. // Only called when constructing static regexes, and this is a
  99. // set of same-width alternates where the widths are known at compile
  100. // time, as in: sregex rx = +(_ | 'a' | _n);
  101. BOOST_MPL_ASSERT_RELATION(unknown_width::value, !=, Alternates::width);
  102. return Alternates::width;
  103. }
  104. private:
  105. alternate_matcher &operator =(alternate_matcher const &);
  106. bool can_match_(char_type ch, Traits const &tr) const
  107. {
  108. return this->bset_.test(ch, tr);
  109. }
  110. };
  111. }}}
  112. #endif