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