]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost string_algo library classification.hpp header file ---------------------------// |
2 | ||
3 | // Copyright Pavol Droba 2002-2003. | |
4 | // | |
5 | // Distributed under the Boost Software License, Version 1.0. | |
6 | // (See accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | // See http://www.boost.org/ for updates, documentation, and revision history. | |
10 | ||
11 | #ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP | |
12 | #define BOOST_STRING_CLASSIFICATION_DETAIL_HPP | |
13 | ||
14 | #include <boost/algorithm/string/config.hpp> | |
15 | #include <algorithm> | |
20effc67 | 16 | #include <cstring> |
7c673cae FG |
17 | #include <functional> |
18 | #include <locale> | |
19 | ||
20 | #include <boost/range/begin.hpp> | |
20effc67 | 21 | #include <boost/range/distance.hpp> |
7c673cae FG |
22 | #include <boost/range/end.hpp> |
23 | ||
24 | #include <boost/algorithm/string/predicate_facade.hpp> | |
25 | #include <boost/type_traits/remove_const.hpp> | |
26 | ||
27 | namespace boost { | |
28 | namespace algorithm { | |
29 | namespace detail { | |
30 | ||
31 | // classification functors -----------------------------------------------// | |
32 | ||
33 | // is_classified functor | |
34 | struct is_classifiedF : | |
35 | public predicate_facade<is_classifiedF> | |
36 | { | |
37 | // Boost.ResultOf support | |
38 | typedef bool result_type; | |
39 | ||
40 | // Constructor from a locale | |
41 | is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : | |
42 | m_Type(Type), m_Locale(Loc) {} | |
43 | // Operation | |
44 | template<typename CharT> | |
45 | bool operator()( CharT Ch ) const | |
46 | { | |
47 | return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); | |
48 | } | |
49 | ||
20effc67 | 50 | #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL) |
7c673cae FG |
51 | template<> |
52 | bool operator()( char const Ch ) const | |
53 | { | |
54 | return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch ); | |
55 | } | |
56 | #endif | |
57 | ||
58 | private: | |
59 | std::ctype_base::mask m_Type; | |
60 | std::locale m_Locale; | |
61 | }; | |
62 | ||
63 | ||
64 | // is_any_of functor | |
65 | /* | |
66 | returns true if the value is from the specified set | |
67 | */ | |
68 | template<typename CharT> | |
69 | struct is_any_ofF : | |
70 | public predicate_facade<is_any_ofF<CharT> > | |
71 | { | |
72 | private: | |
73 | // set cannot operate on const value-type | |
74 | typedef typename ::boost::remove_const<CharT>::type set_value_type; | |
75 | ||
76 | public: | |
77 | // Boost.ResultOf support | |
78 | typedef bool result_type; | |
79 | ||
80 | // Constructor | |
81 | template<typename RangeT> | |
82 | is_any_ofF( const RangeT& Range ) : m_Size(0) | |
83 | { | |
84 | // Prepare storage | |
85 | m_Storage.m_dynSet=0; | |
86 | ||
87 | std::size_t Size=::boost::distance(Range); | |
88 | m_Size=Size; | |
89 | set_value_type* Storage=0; | |
90 | ||
91 | if(use_fixed_storage(m_Size)) | |
92 | { | |
93 | // Use fixed storage | |
94 | Storage=&m_Storage.m_fixSet[0]; | |
95 | } | |
96 | else | |
97 | { | |
98 | // Use dynamic storage | |
99 | m_Storage.m_dynSet=new set_value_type[m_Size]; | |
100 | Storage=m_Storage.m_dynSet; | |
101 | } | |
102 | ||
103 | // Use fixed storage | |
104 | ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); | |
105 | ::std::sort(Storage, Storage+m_Size); | |
106 | } | |
107 | ||
108 | // Copy constructor | |
109 | is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size) | |
110 | { | |
111 | // Prepare storage | |
112 | m_Storage.m_dynSet=0; | |
113 | const set_value_type* SrcStorage=0; | |
114 | set_value_type* DestStorage=0; | |
115 | ||
116 | if(use_fixed_storage(m_Size)) | |
117 | { | |
118 | // Use fixed storage | |
119 | DestStorage=&m_Storage.m_fixSet[0]; | |
120 | SrcStorage=&Other.m_Storage.m_fixSet[0]; | |
121 | } | |
122 | else | |
123 | { | |
124 | // Use dynamic storage | |
125 | m_Storage.m_dynSet=new set_value_type[m_Size]; | |
126 | DestStorage=m_Storage.m_dynSet; | |
127 | SrcStorage=Other.m_Storage.m_dynSet; | |
128 | } | |
129 | ||
130 | // Use fixed storage | |
131 | ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); | |
132 | } | |
133 | ||
134 | // Destructor | |
135 | ~is_any_ofF() | |
136 | { | |
137 | if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) | |
138 | { | |
139 | delete [] m_Storage.m_dynSet; | |
140 | } | |
141 | } | |
142 | ||
143 | // Assignment | |
144 | is_any_ofF& operator=(const is_any_ofF& Other) | |
145 | { | |
146 | // Handle self assignment | |
147 | if(this==&Other) return *this; | |
148 | ||
149 | // Prepare storage | |
150 | const set_value_type* SrcStorage; | |
151 | set_value_type* DestStorage; | |
152 | ||
153 | if(use_fixed_storage(Other.m_Size)) | |
154 | { | |
155 | // Use fixed storage | |
156 | DestStorage=&m_Storage.m_fixSet[0]; | |
157 | SrcStorage=&Other.m_Storage.m_fixSet[0]; | |
158 | ||
159 | // Delete old storage if was present | |
160 | if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) | |
161 | { | |
162 | delete [] m_Storage.m_dynSet; | |
163 | } | |
164 | ||
165 | // Set new size | |
166 | m_Size=Other.m_Size; | |
167 | } | |
168 | else | |
169 | { | |
170 | // Other uses dynamic storage | |
171 | SrcStorage=Other.m_Storage.m_dynSet; | |
172 | ||
173 | // Check what kind of storage are we using right now | |
174 | if(use_fixed_storage(m_Size)) | |
175 | { | |
176 | // Using fixed storage, allocate new | |
177 | set_value_type* pTemp=new set_value_type[Other.m_Size]; | |
178 | DestStorage=pTemp; | |
179 | m_Storage.m_dynSet=pTemp; | |
180 | m_Size=Other.m_Size; | |
181 | } | |
182 | else | |
183 | { | |
184 | // Using dynamic storage, check if can reuse | |
185 | if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2) | |
186 | { | |
187 | // Reuse the current storage | |
188 | DestStorage=m_Storage.m_dynSet; | |
189 | m_Size=Other.m_Size; | |
190 | } | |
191 | else | |
192 | { | |
193 | // Allocate the new one | |
194 | set_value_type* pTemp=new set_value_type[Other.m_Size]; | |
195 | DestStorage=pTemp; | |
196 | ||
197 | // Delete old storage if necessary | |
198 | if(m_Storage.m_dynSet!=0) | |
199 | { | |
200 | delete [] m_Storage.m_dynSet; | |
201 | } | |
202 | // Store the new storage | |
203 | m_Storage.m_dynSet=pTemp; | |
204 | // Set new size | |
205 | m_Size=Other.m_Size; | |
206 | } | |
207 | } | |
208 | } | |
209 | ||
210 | // Copy the data | |
211 | ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); | |
212 | ||
213 | return *this; | |
214 | } | |
215 | ||
216 | // Operation | |
217 | template<typename Char2T> | |
218 | bool operator()( Char2T Ch ) const | |
219 | { | |
220 | const set_value_type* Storage= | |
221 | (use_fixed_storage(m_Size)) | |
222 | ? &m_Storage.m_fixSet[0] | |
223 | : m_Storage.m_dynSet; | |
224 | ||
225 | return ::std::binary_search(Storage, Storage+m_Size, Ch); | |
226 | } | |
227 | private: | |
228 | // check if the size is eligible for fixed storage | |
229 | static bool use_fixed_storage(std::size_t size) | |
230 | { | |
231 | return size<=sizeof(set_value_type*)*2; | |
232 | } | |
233 | ||
234 | ||
235 | private: | |
236 | // storage | |
237 | // The actual used storage is selected on the type | |
238 | union | |
239 | { | |
240 | set_value_type* m_dynSet; | |
241 | set_value_type m_fixSet[sizeof(set_value_type*)*2]; | |
242 | } | |
243 | m_Storage; | |
244 | ||
245 | // storage size | |
246 | ::std::size_t m_Size; | |
247 | }; | |
248 | ||
249 | // is_from_range functor | |
250 | /* | |
251 | returns true if the value is from the specified range. | |
252 | (i.e. x>=From && x>=To) | |
253 | */ | |
254 | template<typename CharT> | |
255 | struct is_from_rangeF : | |
256 | public predicate_facade< is_from_rangeF<CharT> > | |
257 | { | |
258 | // Boost.ResultOf support | |
259 | typedef bool result_type; | |
260 | ||
261 | // Constructor | |
262 | is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} | |
263 | ||
264 | // Operation | |
265 | template<typename Char2T> | |
266 | bool operator()( Char2T Ch ) const | |
267 | { | |
268 | return ( m_From <= Ch ) && ( Ch <= m_To ); | |
269 | } | |
270 | ||
271 | private: | |
272 | CharT m_From; | |
273 | CharT m_To; | |
274 | }; | |
275 | ||
276 | // class_and composition predicate | |
277 | template<typename Pred1T, typename Pred2T> | |
278 | struct pred_andF : | |
279 | public predicate_facade< pred_andF<Pred1T,Pred2T> > | |
280 | { | |
281 | public: | |
282 | ||
283 | // Boost.ResultOf support | |
284 | typedef bool result_type; | |
285 | ||
286 | // Constructor | |
287 | pred_andF( Pred1T Pred1, Pred2T Pred2 ) : | |
288 | m_Pred1(Pred1), m_Pred2(Pred2) {} | |
289 | ||
290 | // Operation | |
291 | template<typename CharT> | |
292 | bool operator()( CharT Ch ) const | |
293 | { | |
294 | return m_Pred1(Ch) && m_Pred2(Ch); | |
295 | } | |
296 | ||
297 | private: | |
298 | Pred1T m_Pred1; | |
299 | Pred2T m_Pred2; | |
300 | }; | |
301 | ||
302 | // class_or composition predicate | |
303 | template<typename Pred1T, typename Pred2T> | |
304 | struct pred_orF : | |
305 | public predicate_facade< pred_orF<Pred1T,Pred2T> > | |
306 | { | |
307 | public: | |
308 | // Boost.ResultOf support | |
309 | typedef bool result_type; | |
310 | ||
311 | // Constructor | |
312 | pred_orF( Pred1T Pred1, Pred2T Pred2 ) : | |
313 | m_Pred1(Pred1), m_Pred2(Pred2) {} | |
314 | ||
315 | // Operation | |
316 | template<typename CharT> | |
317 | bool operator()( CharT Ch ) const | |
318 | { | |
319 | return m_Pred1(Ch) || m_Pred2(Ch); | |
320 | } | |
321 | ||
322 | private: | |
323 | Pred1T m_Pred1; | |
324 | Pred2T m_Pred2; | |
325 | }; | |
326 | ||
327 | // class_not composition predicate | |
328 | template< typename PredT > | |
329 | struct pred_notF : | |
330 | public predicate_facade< pred_notF<PredT> > | |
331 | { | |
332 | public: | |
333 | // Boost.ResultOf support | |
334 | typedef bool result_type; | |
335 | ||
336 | // Constructor | |
337 | pred_notF( PredT Pred ) : m_Pred(Pred) {} | |
338 | ||
339 | // Operation | |
340 | template<typename CharT> | |
341 | bool operator()( CharT Ch ) const | |
342 | { | |
343 | return !m_Pred(Ch); | |
344 | } | |
345 | ||
346 | private: | |
347 | PredT m_Pred; | |
348 | }; | |
349 | ||
350 | } // namespace detail | |
351 | } // namespace algorithm | |
352 | } // namespace boost | |
353 | ||
354 | ||
355 | #endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP |