set_matcher.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // set.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_SET_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_SET_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. # pragma warning(push)
  13. # pragma warning(disable : 4127) // conditional expression constant
  14. # pragma warning(disable : 4100) // unreferenced formal parameter
  15. # pragma warning(disable : 4351) // vc8 new behavior: elements of array 'foo' will be default initialized
  16. #endif
  17. #include <algorithm>
  18. #include <boost/mpl/assert.hpp>
  19. #include <boost/type_traits/same_traits.hpp>
  20. #include <boost/xpressive/detail/detail_fwd.hpp>
  21. #include <boost/xpressive/detail/core/quant_style.hpp>
  22. #include <boost/xpressive/detail/core/state.hpp>
  23. namespace boost { namespace xpressive { namespace detail
  24. {
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // set_matcher
  27. //
  28. template<typename Traits, typename Size>
  29. struct set_matcher
  30. : quant_style_fixed_width<1>
  31. {
  32. typedef typename Traits::char_type char_type;
  33. char_type set_[ Size::value ];
  34. bool not_;
  35. bool icase_;
  36. set_matcher()
  37. : set_()
  38. , not_(false)
  39. , icase_(false)
  40. {
  41. }
  42. void inverse()
  43. {
  44. this->not_ = !this->not_;
  45. }
  46. void nocase(Traits const &tr)
  47. {
  48. this->icase_ = true;
  49. for(int i = 0; i < Size::value; ++i)
  50. {
  51. this->set_[i] = tr.translate_nocase(this->set_[i]);
  52. }
  53. }
  54. bool in_set(Traits const &tr, char_type ch) const
  55. {
  56. char_type const *begin = &this->set_[0], *end = begin + Size::value;
  57. ch = this->icase_ ? tr.translate_nocase(ch) : tr.translate(ch);
  58. return end != std::find(begin, end, ch);
  59. }
  60. template<typename BidiIter, typename Next>
  61. bool match(match_state<BidiIter> &state, Next const &next) const
  62. {
  63. if(state.eos() || this->not_ == this->in_set(traits_cast<Traits>(state), *state.cur_))
  64. {
  65. return false;
  66. }
  67. if(++state.cur_, next.match(state))
  68. {
  69. return true;
  70. }
  71. return --state.cur_, false;
  72. }
  73. };
  74. ///////////////////////////////////////////////////////////////////////////////
  75. // set_initializer
  76. struct set_initializer
  77. {
  78. };
  79. #if defined(_MSC_VER)
  80. # pragma warning(pop)
  81. #endif
  82. }}} // namespace boost::xpressive::detail
  83. #endif