string_matcher.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // string_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_STRING_MATCHER_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_STRING_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 <string>
  14. #include <boost/mpl/bool.hpp>
  15. #include <boost/xpressive/detail/detail_fwd.hpp>
  16. #include <boost/xpressive/detail/core/quant_style.hpp>
  17. #include <boost/xpressive/detail/core/state.hpp>
  18. #include <boost/xpressive/detail/utility/algorithm.hpp>
  19. #include <boost/xpressive/detail/utility/traits_utils.hpp>
  20. namespace boost { namespace xpressive { namespace detail
  21. {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // string_matcher
  24. //
  25. template<typename Traits, typename ICase>
  26. struct string_matcher
  27. : quant_style_fixed_unknown_width
  28. {
  29. typedef typename Traits::char_type char_type;
  30. typedef typename Traits::string_type string_type;
  31. typedef ICase icase_type;
  32. string_type str_;
  33. char_type const *end_;
  34. string_matcher(string_type const &str, Traits const &tr)
  35. : str_(str)
  36. , end_()
  37. {
  38. typename range_iterator<string_type>::type cur = boost::begin(this->str_);
  39. typename range_iterator<string_type>::type end = boost::end(this->str_);
  40. for(; cur != end; ++cur)
  41. {
  42. *cur = detail::translate(*cur, tr, icase_type());
  43. }
  44. this->end_ = detail::data_end(str_);
  45. }
  46. string_matcher(string_matcher<Traits, ICase> const &that)
  47. : str_(that.str_)
  48. , end_(detail::data_end(str_))
  49. {
  50. }
  51. template<typename BidiIter, typename Next>
  52. bool match(match_state<BidiIter> &state, Next const &next) const
  53. {
  54. BidiIter const tmp = state.cur_;
  55. char_type const *begin = detail::data_begin(this->str_);
  56. for(; begin != this->end_; ++begin, ++state.cur_)
  57. {
  58. if(state.eos() ||
  59. (detail::translate(*state.cur_, traits_cast<Traits>(state), icase_type()) != *begin))
  60. {
  61. state.cur_ = tmp;
  62. return false;
  63. }
  64. }
  65. if(next.match(state))
  66. {
  67. return true;
  68. }
  69. state.cur_ = tmp;
  70. return false;
  71. }
  72. detail::width get_width() const
  73. {
  74. return boost::size(this->str_);
  75. }
  76. };
  77. }}}
  78. #endif