Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // chset.hpp
|
Chris@16
|
3 //
|
Chris@16
|
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
5 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
|
Chris@16
|
9 #define BOOST_XPRESSIVE_DETAIL_CHSET_CHSET_HPP_EAN_10_04_2005
|
Chris@16
|
10
|
Chris@16
|
11 // MS compatible compilers support #pragma once
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 # pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <vector>
|
Chris@16
|
17 #include <boost/call_traits.hpp>
|
Chris@16
|
18 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
19 #include <boost/xpressive/detail/utility/algorithm.hpp>
|
Chris@16
|
20 #include <boost/xpressive/detail/utility/chset/basic_chset.ipp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
23 {
|
Chris@16
|
24
|
Chris@16
|
25 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
26 // compound_charset
|
Chris@16
|
27 //
|
Chris@16
|
28 template<typename Traits>
|
Chris@16
|
29 struct compound_charset
|
Chris@16
|
30 : private basic_chset<typename Traits::char_type>
|
Chris@16
|
31 {
|
Chris@16
|
32 typedef typename Traits::char_type char_type;
|
Chris@16
|
33 typedef basic_chset<char_type> base_type;
|
Chris@16
|
34 typedef Traits traits_type;
|
Chris@16
|
35 typedef typename Traits::char_class_type char_class_type;
|
Chris@16
|
36
|
Chris@16
|
37 compound_charset()
|
Chris@16
|
38 : base_type()
|
Chris@16
|
39 , complement_(false)
|
Chris@16
|
40 , has_posix_(false)
|
Chris@16
|
41 , posix_yes_()
|
Chris@16
|
42 , posix_no_()
|
Chris@16
|
43 {
|
Chris@16
|
44 }
|
Chris@16
|
45
|
Chris@16
|
46 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
47 // accessors
|
Chris@16
|
48 basic_chset<char_type> const &base() const
|
Chris@16
|
49 {
|
Chris@16
|
50 return *this;
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 bool is_inverted() const
|
Chris@16
|
54 {
|
Chris@16
|
55 return this->complement_;
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 char_class_type posix_yes() const
|
Chris@16
|
59 {
|
Chris@16
|
60 return this->posix_yes_;
|
Chris@16
|
61 }
|
Chris@16
|
62
|
Chris@16
|
63 std::vector<char_class_type> const &posix_no() const
|
Chris@16
|
64 {
|
Chris@16
|
65 return this->posix_no_;
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
69 // complement
|
Chris@16
|
70 void inverse()
|
Chris@16
|
71 {
|
Chris@16
|
72 this->complement_ = !this->complement_;
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
76 // set
|
Chris@16
|
77 void set_char(char_type ch, Traits const &tr, bool icase)
|
Chris@16
|
78 {
|
Chris@16
|
79 icase ? this->base_type::set(ch, tr) : this->base_type::set(ch);
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 void set_range(char_type from, char_type to, Traits const &tr, bool icase)
|
Chris@16
|
83 {
|
Chris@16
|
84 icase ? this->base_type::set(from, to, tr) : this->base_type::set(from, to);
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 void set_class(char_class_type const &m, bool no)
|
Chris@16
|
88 {
|
Chris@16
|
89 this->has_posix_ = true;
|
Chris@16
|
90
|
Chris@16
|
91 if(no)
|
Chris@16
|
92 {
|
Chris@16
|
93 this->posix_no_.push_back(m);
|
Chris@16
|
94 }
|
Chris@16
|
95 else
|
Chris@16
|
96 {
|
Chris@16
|
97 this->posix_yes_ |= m;
|
Chris@16
|
98 }
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
102 // test
|
Chris@16
|
103 template<typename ICase>
|
Chris@16
|
104 bool test(char_type ch, Traits const &tr, ICase) const
|
Chris@16
|
105 {
|
Chris@16
|
106 return this->complement_ !=
|
Chris@16
|
107 (this->base_type::test(ch, tr, ICase()) ||
|
Chris@16
|
108 (this->has_posix_ && this->test_posix(ch, tr)));
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 private:
|
Chris@16
|
112
|
Chris@16
|
113 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
114 // not_posix_pred
|
Chris@16
|
115 struct not_posix_pred
|
Chris@16
|
116 {
|
Chris@16
|
117 char_type ch_;
|
Chris@16
|
118 Traits const *traits_ptr_;
|
Chris@16
|
119
|
Chris@16
|
120 bool operator ()(typename call_traits<char_class_type>::param_type m) const
|
Chris@16
|
121 {
|
Chris@16
|
122 return !this->traits_ptr_->isctype(this->ch_, m);
|
Chris@16
|
123 }
|
Chris@16
|
124 };
|
Chris@16
|
125
|
Chris@16
|
126 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
127 // test_posix
|
Chris@16
|
128 bool test_posix(char_type ch, Traits const &tr) const
|
Chris@16
|
129 {
|
Chris@16
|
130 not_posix_pred const pred = {ch, &tr};
|
Chris@16
|
131 return tr.isctype(ch, this->posix_yes_)
|
Chris@16
|
132 || any(this->posix_no_.begin(), this->posix_no_.end(), pred);
|
Chris@16
|
133 }
|
Chris@16
|
134
|
Chris@16
|
135 bool complement_;
|
Chris@16
|
136 bool has_posix_;
|
Chris@16
|
137 char_class_type posix_yes_;
|
Chris@16
|
138 std::vector<char_class_type> posix_no_;
|
Chris@16
|
139 };
|
Chris@16
|
140
|
Chris@16
|
141
|
Chris@16
|
142 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
143 // helpers
|
Chris@16
|
144 template<typename Char, typename Traits>
|
Chris@16
|
145 inline void set_char(compound_charset<Traits> &chset, Char ch, Traits const &tr, bool icase)
|
Chris@16
|
146 {
|
Chris@16
|
147 chset.set_char(ch, tr, icase);
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 template<typename Char, typename Traits>
|
Chris@16
|
151 inline void set_range(compound_charset<Traits> &chset, Char from, Char to, Traits const &tr, bool icase)
|
Chris@16
|
152 {
|
Chris@16
|
153 chset.set_range(from, to, tr, icase);
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 template<typename Traits>
|
Chris@16
|
157 inline void set_class(compound_charset<Traits> &chset, typename Traits::char_class_type char_class, bool no, Traits const &)
|
Chris@16
|
158 {
|
Chris@16
|
159 chset.set_class(char_class, no);
|
Chris@16
|
160 }
|
Chris@16
|
161
|
Chris@16
|
162 }}} // namespace boost::xpressive::detail
|
Chris@16
|
163
|
Chris@16
|
164 #endif
|
Chris@16
|
165
|