• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace 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
is_classifiedFboost::algorithm::detail::is_classifiedF39                 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>
operator ()boost::algorithm::detail::is_classifiedF43                 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<>
operator ()boost::algorithm::detail::is_classifiedF50                     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>
is_any_ofFboost::algorithm::detail::is_any_ofF80                 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(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
is_any_ofFboost::algorithm::detail::is_any_ofF107                 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(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(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
130                 }
131 
132                 // Destructor
~is_any_ofFboost::algorithm::detail::is_any_ofF133                 ~is_any_ofF()
134                 {
135                     if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
136                     {
137                         delete [] m_Storage.m_dynSet;
138                     }
139                 }
140 
141                 // Assignment
operator =boost::algorithm::detail::is_any_ofF142                 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(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(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(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(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
210 
211                     return *this;
212                 }
213 
214                 // Operation
215                 template<typename Char2T>
operator ()boost::algorithm::detail::is_any_ofF216                 bool operator()( Char2T Ch ) const
217                 {
218                     const set_value_type* Storage=
219                         (use_fixed_storage(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
use_fixed_storageboost::algorithm::detail::is_any_ofF227                 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
is_from_rangeFboost::algorithm::detail::is_from_rangeF260                 is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
261 
262                 // Operation
263                 template<typename Char2T>
operator ()boost::algorithm::detail::is_from_rangeF264                 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
pred_andFboost::algorithm::detail::pred_andF285                 pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
286                     m_Pred1(Pred1), m_Pred2(Pred2) {}
287 
288                 // Operation
289                 template<typename CharT>
operator ()boost::algorithm::detail::pred_andF290                 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
pred_orFboost::algorithm::detail::pred_orF310                 pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
311                     m_Pred1(Pred1), m_Pred2(Pred2) {}
312 
313                 // Operation
314                 template<typename CharT>
operator ()boost::algorithm::detail::pred_orF315                 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
pred_notFboost::algorithm::detail::pred_notF335                 pred_notF( PredT Pred ) : m_Pred(Pred) {}
336 
337                 // Operation
338                 template<typename CharT>
operator ()boost::algorithm::detail::pred_notF339                 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