00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef NET_HALFDANS_HSTRING_HPP
00037 #define NET_HALFDANS_HSTRING_HPP
00038
00039 #include <string>
00040 #include <sstream>
00041 #include <vector>
00042 #include <iostream>
00043
00044 namespace net
00045 {
00046 namespace halfdans
00047 {
00048 class String;
00049
00054 class StringList : public std::vector<String>
00055 {
00056 public:
00063 String & operator[] ( int _index )
00064 {
00065 if ( _index < 0 )
00066 {
00067 _index = size() + _index;
00068 }
00069 return std::vector<String>::operator[] ( _index );
00070 }
00071
00077 const String & operator[] ( int _index ) const
00078 {
00079 if ( _index < 0 )
00080 {
00081 _index = size() + _index;
00082 }
00083 return std::vector<String>::operator[] ( _index );
00084 }
00085
00090 void purgeEmpty ();
00102 void stripAndPurgeEmpty ( const std::string & _letters = " \t\r\n" );
00103 };
00104
00109 class String : public std::string
00110 {
00111 public:
00112
00113
00118 template<typename T>
00119 String ( T _value )
00120 {
00121 std::stringstream ss;
00122 ss << _value;
00123 *this = ss.str();
00124 }
00125
00129 explicit String ( size_type _size, value_type _character )
00130 : std::string ( _size, _character )
00131 {
00132 }
00133
00137 explicit String ( const std::string & _value = "" ) : std::string(_value) {}
00138
00146 template<typename T1>
00147 explicit String ( const String & format, T1 arg1 )
00148 {
00149 *this = format.replace("%1", String(arg1));
00150 }
00151
00155 template<typename T1, typename T2>
00156 explicit String ( const String & format, T1 arg1, T2 arg2 )
00157 {
00158 *this = format.replace("%1", String(arg1)).replace("%2", String(arg2));
00159 }
00160
00164 template<typename T1, typename T2, typename T3>
00165 explicit String ( const String & format, T1 arg1, T2 arg2, T3 arg3 )
00166 {
00167 *this = format.replace("%1", String(arg1)).replace("%2", String(arg2))
00168 .replace("%3", String(arg3));
00169 }
00170
00174 template<typename T1, typename T2, typename T3, typename T4>
00175 explicit String ( const String & format, T1 arg1, T2 arg2, T3 arg3, T4 arg4 )
00176 {
00177 *this = format.replace("%1", String(arg1)).replace("%2", String(arg2))
00178 .replace("%3", String(arg3)).replace("%4", String(arg4));
00179 }
00180
00184 template<typename T1, typename T2, typename T3, typename T4, typename T5>
00185 explicit String ( const String & format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5 )
00186 {
00187 *this = format.replace("%1", String(arg1)).replace("%2", String(arg2))
00188 .replace("%3", String(arg3)).replace("%4", String(arg4)).replace("%5", String(arg5));
00189 }
00190
00194 template<typename T>
00195 void operator= ( T _value )
00196 {
00197 *this = String(_value);
00198 }
00199
00204 String replace ( const std::string &a, const std::string &b ) const
00205 {
00206 String ret;
00207 std::string::size_type i = 0;
00208 std::string::size_type j = this->find(a);
00209 while ( j != std::string::npos )
00210 {
00211 ret += this->substr(i, j - i);
00212 ret += b;
00213 i = j + a.size();
00214 j = find(a, i);
00215 }
00216 if ( i != this->size() ) {
00217 ret += this->substr(i, this->size() - i);
00218 }
00219 return ret;
00220 }
00221
00225 String rstrip ( const std::string & _letters = " \t\n\r" ) const
00226 {
00227 std::string::size_type end = this->find_last_not_of(_letters);
00228 return String( this->substr(0, end + 1) );
00229 }
00230
00234 String lstrip ( const std::string & _letters = " \t\n\r" ) const
00235 {
00236 std::string::size_type start = this->find_first_not_of(_letters);
00237 return String( this->substr(start, this->size() - start) );
00238 }
00239
00248 String strip ( const std::string & _letters = " \t\n\r" ) const
00249 {
00250 std::string::size_type start = this->find_first_not_of(_letters);
00251 std::string::size_type end = this->find_last_not_of(_letters);
00252 if ( start == end )
00253 {
00254 if ( start == std::string::npos )
00255 {
00256 return String();
00257 }
00258 else
00259 {
00260 return *this;
00261 }
00262 }
00263 else
00264 {
00265 return String( this->substr(start, end - start + 1) );
00266 }
00267 }
00268
00288 template<typename TInsertIterator>
00289 void split ( TInsertIterator & _ii, const std::string & _delimiters ) const
00290 {
00291 if ( this->empty() )
00292 return;
00293
00294 std::string::size_type i = 0;
00295 std::string::size_type j = this->find_first_of(_delimiters);
00296 while ( j != std::string::npos )
00297 {
00298 *_ii++ = this->substr(i, j - i);
00299 i = j + 1;
00300 j = find_first_of(_delimiters, i);
00301 }
00302
00303
00304 *_ii++ = this->substr(i, this->size() - i);
00305 }
00306
00314 StringList split ( const std::string & _delimiters = " \t\n\r" ) const
00315 {
00316 StringList ret;
00317 std::insert_iterator<StringList> ii (ret, ret.begin());
00318 split ( ii, _delimiters);
00319 return ret;
00320 }
00321
00326 bool isAlpha () const
00327 {
00328 for ( size_type i = 0; i < size(); ++i )
00329 {
00330 if ( !std::isalpha((*this)[i]) )
00331 {
00332 return false;
00333 }
00334 }
00335 return true;
00336 }
00337
00342 bool isAlphaNumeric () const
00343 {
00344 for ( size_type i = 0; i < size(); ++i )
00345 {
00346 if ( !std::isalnum((*this)[i]) )
00347 {
00348 return false;
00349 }
00350 }
00351 return true;
00352 }
00353
00358 bool isUpper() const
00359 {
00360 for ( size_type i = 0; i < size(); ++i )
00361 {
00362 if ( !std::isupper((*this)[i]) )
00363 {
00364 return false;
00365 }
00366 }
00367 return true;
00368 }
00369
00374 bool isLower() const
00375 {
00376 for ( size_type i = 0; i < size(); ++i )
00377 {
00378 if ( !std::islower((*this)[i]) )
00379 {
00380 return false;
00381 }
00382 }
00383 return true;
00384 }
00385
00390 bool isDigits() const
00391 {
00392 for ( size_type i = 0; i < size(); ++i )
00393 {
00394 if ( !std::isdigit((*this)[i]) )
00395 {
00396 return false;
00397 }
00398 }
00399 return true;
00400 }
00401
00406 bool isWhitespace() const
00407 {
00408 for ( size_type i = 0; i < size(); ++i )
00409 {
00410 if ( !std::isspace((*this)[i]) )
00411 {
00412 return false;
00413 }
00414 }
00415 return true;
00416 }
00417
00422 bool isHexadecimal() const
00423 {
00424 for ( size_type i = 0; i < size(); ++i )
00425 {
00426 if ( !std::isxdigit((*this)[i]) )
00427 {
00428 return false;
00429 }
00430 }
00431 return true;
00432 }
00433
00434
00440 String capitalize () const
00441 {
00442 String ret ( this->size(), ' ' );
00443 ret[0] = toupper((*this)[0]);
00444 for ( size_type i = 1; i < size(); ++i )
00445 {
00446 ret[i] = tolower((*this)[i]);
00447 }
00448 return ret;
00449 }
00450
00454 String upper () const
00455 {
00456 String ret ( this->size(), ' ' );
00457 for ( size_type i = 0; i < size(); ++i )
00458 {
00459 ret[i] = std::toupper((*this)[i]);
00460 }
00461 return ret;
00462 }
00463
00467 String lower () const
00468 {
00469 String ret ( this->size(), ' ' );
00470 for ( size_type i = 0; i < size(); ++i )
00471 {
00472 ret[i] = std::tolower((*this)[i]);
00473 }
00474 return ret;
00475 }
00476
00495 std::string::value_type & operator[] ( int _index )
00496 {
00497 if ( _index < 0 )
00498 {
00499 _index = size() + _index;
00500 }
00501 return std::string::operator[] ( _index );
00502 }
00503
00509 std::string::value_type operator[] ( int _index ) const
00510 {
00511 if ( _index < 0 )
00512 {
00513 _index = size() + _index;
00514 }
00515 return std::string::operator[] ( _index );
00516 }
00517
00525 template <typename ListType>
00526 static String join ( const ListType & _list, const String & _seperator )
00527 {
00528 return join(_list.begin(), _list.end(), _seperator);
00529 }
00530
00542 template <typename IteratorType>
00543 static String join ( const IteratorType & _begin, const IteratorType & _end, const String & _seperator )
00544 {
00545 String ret;
00546 for ( IteratorType it = _begin; it != _end; ++it )
00547 {
00548 if ( it != _begin )
00549 {
00550 ret += _seperator;
00551 }
00552 ret += String(*it);
00553 }
00554 return ret;
00555 }
00556 };
00557
00558 inline void StringList::purgeEmpty ()
00559 {
00560 for ( iterator it = begin(); it != end(); )
00561 {
00562 if ( it->empty() )
00563 {
00564 it = erase(it);
00565 }
00566 else
00567 {
00568 ++it;
00569 }
00570 }
00571 }
00572
00573 inline void StringList::stripAndPurgeEmpty ( const std::string & _letters )
00574 {
00575 for ( iterator it = begin(); it != end(); )
00576 {
00577 if ( it->strip(_letters).empty() )
00578 {
00579 it = erase(it);
00580 }
00581 else
00582 {
00583 ++it;
00584 }
00585 }
00586 }
00587 }
00588 }
00589
00590 #endif