Line data Source code
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 6418 : 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 1069 : is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : 40 1069 : m_Type(Type), m_Locale(Loc) {} 41 : // Operation 42 : template<typename CharT> 43 2138 : bool operator()( CharT Ch ) const 44 : { 45 2138 : return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch ); 46 : } 47 : 48 : #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__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 0 : is_any_ofF( const RangeT& Range ) : m_Size(0) 81 : { 82 : // Prepare storage 83 0 : m_Storage.m_dynSet=0; 84 : 85 0 : std::size_t Size=::boost::distance(Range); 86 0 : m_Size=Size; 87 0 : set_value_type* Storage=0; 88 : 89 0 : if(use_fixed_storage(m_Size)) 90 : { 91 : // Use fixed storage 92 0 : Storage=&m_Storage.m_fixSet[0]; 93 : } 94 : else 95 : { 96 : // Use dynamic storage 97 0 : m_Storage.m_dynSet=new set_value_type[m_Size]; 98 0 : Storage=m_Storage.m_dynSet; 99 : } 100 : 101 : // Use fixed storage 102 0 : ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); 103 0 : ::std::sort(Storage, Storage+m_Size); 104 0 : } 105 : 106 : // Copy constructor 107 0 : is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size) 108 : { 109 : // Prepare storage 110 0 : m_Storage.m_dynSet=0; 111 0 : const set_value_type* SrcStorage=0; 112 0 : set_value_type* DestStorage=0; 113 : 114 0 : if(use_fixed_storage(m_Size)) 115 : { 116 : // Use fixed storage 117 0 : DestStorage=&m_Storage.m_fixSet[0]; 118 0 : SrcStorage=&Other.m_Storage.m_fixSet[0]; 119 : } 120 : else 121 : { 122 : // Use dynamic storage 123 0 : m_Storage.m_dynSet=new set_value_type[m_Size]; 124 0 : DestStorage=m_Storage.m_dynSet; 125 0 : SrcStorage=Other.m_Storage.m_dynSet; 126 : } 127 : 128 : // Use fixed storage 129 0 : ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); 130 0 : } 131 : 132 : // Destructor 133 0 : ~is_any_ofF() 134 : { 135 0 : if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) 136 : { 137 0 : 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(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> 216 0 : bool operator()( Char2T Ch ) const 217 : { 218 0 : const set_value_type* Storage= 219 0 : (use_fixed_storage(m_Size)) 220 0 : ? &m_Storage.m_fixSet[0] 221 : : m_Storage.m_dynSet; 222 : 223 0 : return ::std::binary_search(Storage, Storage+m_Size, Ch); 224 : } 225 : private: 226 : // check if the size is eligible for fixed storage 227 0 : 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