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

source code of include/boost/algorithm/string/detail/classification.hpp