1 // Boost string_algo library classification.hpp header file ---------------------------//
3 // Copyright Pavol Droba 2002-2003.
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)
9 // See http://www.boost.org/ for updates, documentation, and revision history.
11 #ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
12 #define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
14 #include <boost/algorithm/string/config.hpp>
19 #include <boost/range/begin.hpp>
20 #include <boost/range/end.hpp>
22 #include <boost/algorithm/string/predicate_facade.hpp>
23 #include <boost/type_traits/remove_const.hpp>
29 // classification functors -----------------------------------------------//
31 // is_classified functor
32 struct is_classifiedF :
33 public predicate_facade<is_classifiedF>
35 // Boost.ResultOf support
36 typedef bool result_type;
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) {}
42 template<typename CharT>
43 bool operator()( CharT Ch ) const
45 return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
48 #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
50 bool operator()( char const Ch ) const
52 return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
57 std::ctype_base::mask m_Type;
64 returns true if the value is from the specified set
66 template<typename CharT>
68 public predicate_facade<is_any_ofF<CharT> >
71 // set cannot operate on const value-type
72 typedef typename ::boost::remove_const<CharT>::type set_value_type;
75 // Boost.ResultOf support
76 typedef bool result_type;
79 template<typename RangeT>
80 is_any_ofF( const RangeT& Range ) : m_Size(0)
85 std::size_t Size=::boost::distance(Range);
87 set_value_type* Storage=0;
89 if(use_fixed_storage(m_Size))
92 Storage=&m_Storage.m_fixSet[0];
96 // Use dynamic storage
97 m_Storage.m_dynSet=new set_value_type[m_Size];
98 Storage=m_Storage.m_dynSet;
102 ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
103 ::std::sort(Storage, Storage+m_Size);
107 is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
110 m_Storage.m_dynSet=0;
111 const set_value_type* SrcStorage=0;
112 set_value_type* DestStorage=0;
114 if(use_fixed_storage(m_Size))
117 DestStorage=&m_Storage.m_fixSet[0];
118 SrcStorage=&Other.m_Storage.m_fixSet[0];
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;
129 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
135 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
137 delete [] m_Storage.m_dynSet;
142 is_any_ofF& operator=(const is_any_ofF& Other)
144 // Handle self assignment
145 if(this==&Other) return *this;
148 const set_value_type* SrcStorage;
149 set_value_type* DestStorage;
151 if(use_fixed_storage(Other.m_Size))
154 DestStorage=&m_Storage.m_fixSet[0];
155 SrcStorage=&Other.m_Storage.m_fixSet[0];
157 // Delete old storage if was present
158 if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
160 delete [] m_Storage.m_dynSet;
168 // Other uses dynamic storage
169 SrcStorage=Other.m_Storage.m_dynSet;
171 // Check what kind of storage are we using right now
172 if(use_fixed_storage(m_Size))
174 // Using fixed storage, allocate new
175 set_value_type* pTemp=new set_value_type[Other.m_Size];
177 m_Storage.m_dynSet=pTemp;
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)
185 // Reuse the current storage
186 DestStorage=m_Storage.m_dynSet;
191 // Allocate the new one
192 set_value_type* pTemp=new set_value_type[Other.m_Size];
195 // Delete old storage if necessary
196 if(m_Storage.m_dynSet!=0)
198 delete [] m_Storage.m_dynSet;
200 // Store the new storage
201 m_Storage.m_dynSet=pTemp;
209 ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
215 template<typename Char2T>
216 bool operator()( Char2T Ch ) const
218 const set_value_type* Storage=
219 (use_fixed_storage(m_Size))
220 ? &m_Storage.m_fixSet[0]
221 : m_Storage.m_dynSet;
223 return ::std::binary_search(Storage, Storage+m_Size, Ch);
226 // check if the size is eligible for fixed storage
227 static bool use_fixed_storage(std::size_t size)
229 return size<=sizeof(set_value_type*)*2;
235 // The actual used storage is selected on the type
238 set_value_type* m_dynSet;
239 set_value_type m_fixSet[sizeof(set_value_type*)*2];
244 ::std::size_t m_Size;
247 // is_from_range functor
249 returns true if the value is from the specified range.
250 (i.e. x>=From && x>=To)
252 template<typename CharT>
253 struct is_from_rangeF :
254 public predicate_facade< is_from_rangeF<CharT> >
256 // Boost.ResultOf support
257 typedef bool result_type;
260 is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
263 template<typename Char2T>
264 bool operator()( Char2T Ch ) const
266 return ( m_From <= Ch ) && ( Ch <= m_To );
274 // class_and composition predicate
275 template<typename Pred1T, typename Pred2T>
277 public predicate_facade< pred_andF<Pred1T,Pred2T> >
281 // Boost.ResultOf support
282 typedef bool result_type;
285 pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
286 m_Pred1(Pred1), m_Pred2(Pred2) {}
289 template<typename CharT>
290 bool operator()( CharT Ch ) const
292 return m_Pred1(Ch) && m_Pred2(Ch);
300 // class_or composition predicate
301 template<typename Pred1T, typename Pred2T>
303 public predicate_facade< pred_orF<Pred1T,Pred2T> >
306 // Boost.ResultOf support
307 typedef bool result_type;
310 pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
311 m_Pred1(Pred1), m_Pred2(Pred2) {}
314 template<typename CharT>
315 bool operator()( CharT Ch ) const
317 return m_Pred1(Ch) || m_Pred2(Ch);
325 // class_not composition predicate
326 template< typename PredT >
328 public predicate_facade< pred_notF<PredT> >
331 // Boost.ResultOf support
332 typedef bool result_type;
335 pred_notF( PredT Pred ) : m_Pred(Pred) {}
338 template<typename CharT>
339 bool operator()( CharT Ch ) const
348 } // namespace detail
349 } // namespace algorithm
353 #endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP