File indexing completed on 2025-01-18 09:53:52
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_HASH_PEEK_BITSET_HPP_EAN_10_04_2005
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 # pragma warning(push)
0015 # pragma warning(disable : 4100)
0016 # pragma warning(disable : 4127)
0017 #endif
0018
0019 #include <bitset>
0020 #include <string> // for std::char_traits
0021 #include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
0022
0023 namespace boost { namespace xpressive { namespace detail
0024 {
0025
0026
0027
0028
0029 template<typename Char>
0030 struct hash_peek_bitset
0031 {
0032 typedef Char char_type;
0033 typedef typename std::char_traits<char_type>::int_type int_type;
0034
0035 hash_peek_bitset()
0036 : icase_(false)
0037 , bset_()
0038 {
0039 }
0040
0041 std::size_t count() const
0042 {
0043 return this->bset_.count();
0044 }
0045
0046 void set_all()
0047 {
0048 this->icase_ = false;
0049 this->bset_.set();
0050 }
0051
0052 template<typename Traits>
0053 void set_char(char_type ch, bool icase, Traits const &tr)
0054 {
0055 if(this->test_icase_(icase))
0056 {
0057 ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
0058 this->bset_.set(tr.hash(ch));
0059 }
0060 }
0061
0062 template<typename Traits>
0063 void set_range(char_type from, char_type to, bool no, bool icase, Traits const &tr)
0064 {
0065 int_type ifrom = std::char_traits<char_type>::to_int_type(from);
0066 int_type ito = std::char_traits<char_type>::to_int_type(to);
0067 BOOST_ASSERT(ifrom <= ito);
0068
0069 if(no || 256 < (ito - ifrom))
0070 {
0071 this->set_all();
0072 }
0073 else if(this->test_icase_(icase))
0074 {
0075 for(int_type i = ifrom; i <= ito; ++i)
0076 {
0077 char_type ch = std::char_traits<char_type>::to_char_type(i);
0078 ch = icase ? tr.translate_nocase(ch) : tr.translate(ch);
0079 this->bset_.set(tr.hash(ch));
0080 }
0081 }
0082 }
0083
0084 template<typename Traits>
0085 void set_class(typename Traits::char_class_type char_class, bool no, Traits const &tr)
0086 {
0087 if(1 != sizeof(char_type))
0088 {
0089
0090 this->set_all();
0091 }
0092 else
0093 {
0094 for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
0095 {
0096 char_type ch = std::char_traits<char_type>::to_char_type(static_cast<int_type>(i));
0097 if(no != tr.isctype(ch, char_class))
0098 {
0099 this->bset_.set(i);
0100 }
0101 }
0102 }
0103 }
0104
0105 void set_bitset(hash_peek_bitset<Char> const &that)
0106 {
0107 if(this->test_icase_(that.icase()))
0108 {
0109 this->bset_ |= that.bset_;
0110 }
0111 }
0112
0113 void set_charset(basic_chset_8bit<Char> const &that, bool icase)
0114 {
0115 if(this->test_icase_(icase))
0116 {
0117 this->bset_ |= that.base();
0118 }
0119 }
0120
0121 bool icase() const
0122 {
0123 return this->icase_;
0124 }
0125
0126 template<typename Traits>
0127 bool test(char_type ch, Traits const &tr) const
0128 {
0129 ch = this->icase_ ? tr.translate_nocase(ch) : tr.translate(ch);
0130 return this->bset_.test(tr.hash(ch));
0131 }
0132
0133 template<typename Traits>
0134 bool test(char_type ch, Traits const &tr, mpl::false_) const
0135 {
0136 BOOST_ASSERT(!this->icase_);
0137 return this->bset_.test(tr.hash(tr.translate(ch)));
0138 }
0139
0140 template<typename Traits>
0141 bool test(char_type ch, Traits const &tr, mpl::true_) const
0142 {
0143 BOOST_ASSERT(this->icase_);
0144 return this->bset_.test(tr.hash(tr.translate_nocase(ch)));
0145 }
0146
0147 private:
0148
0149
0150 bool test_icase_(bool icase)
0151 {
0152 std::size_t count = this->bset_.count();
0153
0154 if(256 == count)
0155 {
0156 return false;
0157 }
0158 else if(0 != count && this->icase_ != icase)
0159 {
0160 this->set_all();
0161 return false;
0162 }
0163
0164 this->icase_ = icase;
0165 return true;
0166 }
0167
0168 bool icase_;
0169 std::bitset<256> bset_;
0170 };
0171
0172 }}}
0173
0174 #if defined(_MSC_VER)
0175 # pragma warning(pop)
0176 #endif
0177
0178 #endif