chset.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // chset.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_CHSET_CHSET_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <vector>
  14. #include <boost/call_traits.hpp>
  15. #include <boost/xpressive/detail/detail_fwd.hpp>
  16. #include <boost/xpressive/detail/utility/algorithm.hpp>
  17. #include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
  18. namespace boost { namespace xpressive { namespace detail
  19. {
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // compound_charset
  22. //
  23. template<typename Traits>
  24. struct compound_charset
  25. : private basic_chset<typename Traits::char_type>
  26. {
  27. typedef typename Traits::char_type char_type;
  28. typedef basic_chset<char_type> base_type;
  29. typedef Traits traits_type;
  30. typedef typename Traits::char_class_type char_class_type;
  31. compound_charset()
  32. : base_type()
  33. , complement_(false)
  34. , has_posix_(false)
  35. , posix_yes_()
  36. , posix_no_()
  37. {
  38. }
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // accessors
  41. basic_chset<char_type> const &base() const
  42. {
  43. return *this;
  44. }
  45. bool is_inverted() const
  46. {
  47. return this->complement_;
  48. }
  49. char_class_type posix_yes() const
  50. {
  51. return this->posix_yes_;
  52. }
  53. std::vector<char_class_type> const &posix_no() const
  54. {
  55. return this->posix_no_;
  56. }
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // complement
  59. void inverse()
  60. {
  61. this->complement_ = !this->complement_;
  62. }
  63. ///////////////////////////////////////////////////////////////////////////////
  64. // set
  65. void set_char(char_type ch, Traits const &tr, bool icase)
  66. {
  67. icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
  68. }
  69. void set_range(char_type from, char_type to, Traits const &tr, bool icase)
  70. {
  71. icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to);
  72. }
  73. void set_class(char_class_type const &m, bool no)
  74. {
  75. this->has_posix_ = true;
  76. if(no)
  77. {
  78. this->posix_no_.push_back(m);
  79. }
  80. else
  81. {
  82. this->posix_yes_ |= m;
  83. }
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////
  86. // test
  87. template<typename ICase>
  88. bool test(char_type ch, Traits const &tr, ICase) const
  89. {
  90. return this->complement_ !=
  91. (this->base_type::test(ch, tr, ICase()) ||
  92. (this->has_posix_ && this->test_posix(ch, tr)));
  93. }
  94. private:
  95. ///////////////////////////////////////////////////////////////////////////////
  96. // not_posix_pred
  97. struct not_posix_pred
  98. {
  99. char_type ch_;
  100. Traits const *traits_ptr_;
  101. bool operator ()(typename call_traits<char_class_type>::param_type m) const
  102. {
  103. return !this->traits_ptr_->isctype(this->ch_, m);
  104. }
  105. };
  106. ///////////////////////////////////////////////////////////////////////////////
  107. // test_posix
  108. bool test_posix(char_type ch, Traits const &tr) const
  109. {
  110. not_posix_pred const pred = {ch, &tr};
  111. return tr.isctype(ch, this->posix_yes_)
  112. || any(this->posix_no_.begin(), this->posix_no_.end(), pred);
  113. }
  114. bool complement_;
  115. bool has_posix_;
  116. char_class_type posix_yes_;
  117. std::vector<char_class_type> posix_no_;
  118. };
  119. ///////////////////////////////////////////////////////////////////////////////
  120. // helpers
  121. template<typename Char, typename Traits>
  122. inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
  123. {
  124. chset.set_char(ch, tr, icase);
  125. }
  126. template<typename Char, typename Traits>
  127. inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
  128. {
  129. chset.set_range(from, to, tr, icase);
  130. }
  131. template<typename Traits>
  132. inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
  133. {
  134. chset.set_class(char_class, no);
  135. }
  136. }}} // namespace boost::xpressive::detail
  137. #endif