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 <cstring> 17 #include <functional> 18 #include <locale> 19 20 #include <boost/range/begin.hpp> 21 #include <boost/range/distance.hpp> 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 is_classifiedFboost::algorithm::detail::is_classifiedF41 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> operator ()boost::algorithm::detail::is_classifiedF45 bool operator()( CharT Ch ) const 46 { 47 return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); 48 } 49 50 #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL) 51 template<> operator ()boost::algorithm::detail::is_classifiedF52 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> is_any_ofFboost::algorithm::detail::is_any_ofF82 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 is_any_ofFboost::algorithm::detail::is_any_ofF109 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 ~is_any_ofFboost::algorithm::detail::is_any_ofF135 ~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 operator =boost::algorithm::detail::is_any_ofF144 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> operator ()boost::algorithm::detail::is_any_ofF218 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 use_fixed_storageboost::algorithm::detail::is_any_ofF229 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 is_from_rangeFboost::algorithm::detail::is_from_rangeF262 is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} 263 264 // Operation 265 template<typename Char2T> operator ()boost::algorithm::detail::is_from_rangeF266 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 pred_andFboost::algorithm::detail::pred_andF287 pred_andF( Pred1T Pred1, Pred2T Pred2 ) : 288 m_Pred1(Pred1), m_Pred2(Pred2) {} 289 290 // Operation 291 template<typename CharT> operator ()boost::algorithm::detail::pred_andF292 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 pred_orFboost::algorithm::detail::pred_orF312 pred_orF( Pred1T Pred1, Pred2T Pred2 ) : 313 m_Pred1(Pred1), m_Pred2(Pred2) {} 314 315 // Operation 316 template<typename CharT> operator ()boost::algorithm::detail::pred_orF317 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 pred_notFboost::algorithm::detail::pred_notF337 pred_notF( PredT Pred ) : m_Pred(Pred) {} 338 339 // Operation 340 template<typename CharT> operator ()boost::algorithm::detail::pred_notF341 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 356