File indexing completed on 2025-01-18 09:53:51
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <vector>
0017 #include <boost/call_traits.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/utility/algorithm.hpp>
0020 #include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
0021
0022 namespace boost { namespace xpressive { namespace detail
0023 {
0024
0025
0026
0027
0028 template<typename Traits>
0029 struct compound_charset
0030 : private basic_chset<typename Traits::char_type>
0031 {
0032 typedef typename Traits::char_type char_type;
0033 typedef basic_chset<char_type> base_type;
0034 typedef Traits traits_type;
0035 typedef typename Traits::char_class_type char_class_type;
0036
0037 compound_charset()
0038 : base_type()
0039 , complement_(false)
0040 , has_posix_(false)
0041 , posix_yes_()
0042 , posix_no_()
0043 {
0044 }
0045
0046
0047
0048 basic_chset<char_type> const &base() const
0049 {
0050 return *this;
0051 }
0052
0053 bool is_inverted() const
0054 {
0055 return this->complement_;
0056 }
0057
0058 char_class_type posix_yes() const
0059 {
0060 return this->posix_yes_;
0061 }
0062
0063 std::vector<char_class_type> const &posix_no() const
0064 {
0065 return this->posix_no_;
0066 }
0067
0068
0069
0070 void inverse()
0071 {
0072 this->complement_ = !this->complement_;
0073 }
0074
0075
0076
0077 void set_char(char_type ch, Traits const &tr, bool icase)
0078 {
0079 icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
0080 }
0081
0082 void set_range(char_type from, char_type to, Traits const &tr, bool icase)
0083 {
0084 icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to);
0085 }
0086
0087 void set_class(char_class_type const &m, bool no)
0088 {
0089 this->has_posix_ = true;
0090
0091 if(no)
0092 {
0093 this->posix_no_.push_back(m);
0094 }
0095 else
0096 {
0097 this->posix_yes_ |= m;
0098 }
0099 }
0100
0101
0102
0103 template<typename ICase>
0104 bool test(char_type ch, Traits const &tr, ICase) const
0105 {
0106 return this->complement_ !=
0107 (this->base_type::test(ch, tr, ICase()) ||
0108 (this->has_posix_ && this->test_posix(ch, tr)));
0109 }
0110
0111 private:
0112
0113
0114
0115 struct not_posix_pred
0116 {
0117 char_type ch_;
0118 Traits const *traits_ptr_;
0119
0120 bool operator ()(typename call_traits<char_class_type>::param_type m) const
0121 {
0122 return !this->traits_ptr_->isctype(this->ch_, m);
0123 }
0124 };
0125
0126
0127
0128 bool test_posix(char_type ch, Traits const &tr) const
0129 {
0130 not_posix_pred const pred = {ch, &tr};
0131 return tr.isctype(ch, this->posix_yes_)
0132 || any(this->posix_no_.begin(), this->posix_no_.end(), pred);
0133 }
0134
0135 bool complement_;
0136 bool has_posix_;
0137 char_class_type posix_yes_;
0138 std::vector<char_class_type> posix_no_;
0139 };
0140
0141
0142
0143
0144 template<typename Char, typename Traits>
0145 inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
0146 {
0147 chset.set_char(ch, tr, icase);
0148 }
0149
0150 template<typename Char, typename Traits>
0151 inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
0152 {
0153 chset.set_range(from, to, tr, icase);
0154 }
0155
0156 template<typename Traits>
0157 inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
0158 {
0159 chset.set_class(char_class, no);
0160 }
0161
0162 }}}
0163
0164 #endif
0165