00001 #ifndef CPPTL_CONSTSTRING_H_INCLUDED
00002 # define CPPTL_CONSTSTRING_H_INCLUDED
00003
00004 # include <cpptl/forwards.h>
00005 # include <string.h>
00006 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00007 # include <string>
00008 # include <iostream>
00009 # endif
00010
00012
00013 namespace CppTL {
00014 class ConstCharView
00015 {
00016 public:
00017 typedef unsigned int size_type;
00018 typedef char value_type;
00019
00020 ConstCharView()
00021 : begin_( "" )
00022 , end_( begin_ )
00023 {
00024 }
00025
00026 ConstCharView( const value_type *czstr )
00027 : begin_( czstr )
00028 {
00029 CPPTL_ASSERT_MESSAGE( czstr != 0, "Invalid zero terminated string" );
00030 end_ = begin_ + strlen( begin_ );
00031 }
00032
00033 ConstCharView( const value_type *cbegin, size_type length )
00034 : begin_( cbegin )
00035 , end_( cbegin + length )
00036 {
00037 }
00038
00039 ConstCharView( const value_type *cbegin, const value_type *cend )
00040 : begin_( cbegin )
00041 , end_( cend )
00042 {
00043 }
00044
00045 size_type length() const
00046 {
00047 return size_type(end_ - begin_);
00048 }
00049
00050 size_type size() const
00051 {
00052 return length();
00053 }
00054
00055 const value_type *c_str() const
00056 {
00057 return begin_;
00058 }
00059
00060 const value_type *begin() const
00061 {
00062 return begin_;
00063 }
00064
00065 const value_type *end() const
00066 {
00067 return end_;
00068 }
00069
00070 private:
00071 const value_type *begin_;
00072 const value_type *end_;
00073 };
00074
00075
00076 class StringConcatenator
00077 {
00078 public:
00079 typedef unsigned int size_type;
00080 typedef char value_type;
00081
00082 private:
00083 class SubString
00084 {
00085 public:
00086 SubString( const value_type *csz );
00087 SubString( const StringConcatenator &concatenator );
00088 SubString( const ConstString &string );
00089 SubString( const StringBuffer &buffer );
00090 SubString( const ConstCharView &constCharView );
00091 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00092 SubString( const std::string &string );
00093 # endif
00094 size_type length() const;
00095
00096 void copyToBuffer( value_type *buffer) const;
00097
00098 private:
00099 enum Kind
00100 {
00101 concatenator = 0,
00102 cszString,
00103 string,
00104 stringBuffer,
00105 constCharView,
00106 stdString
00107 } kind_;
00108 union
00109 {
00110 const char *csz_;
00111 const StringConcatenator *concatenator_;
00112 const ConstString *string_;
00113 const StringBuffer *buffer_;
00114 const ConstCharView *constCharView_;
00115 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00116 const std::string *stdString_;
00117 # endif
00118 };
00119 mutable size_type length_;
00120 };
00121
00122 public:
00123 StringConcatenator( const SubString &left,
00124 const SubString &right );
00125
00126 size_type length() const;
00127
00128 void copyToBuffer( value_type *buffer ) const;
00129
00130 private:
00131 SubString left_;
00132 SubString right_;
00133 };
00134
00135
00136 class ConstStringIterator
00137 {
00138 public:
00139 typedef char value_type;
00140 typedef unsigned int size_type;
00141
00142 ConstStringIterator()
00143 : current_( 0 )
00144 {
00145 }
00146
00147 ConstStringIterator( const value_type *current )
00148 : current_( current )
00149 {
00150 }
00151
00152 char operator *() const
00153 {
00154 return *current_;
00155 }
00156
00157 char operator[]( size_type index ) const
00158 {
00159 return current_[index];
00160 }
00161
00162 ConstStringIterator &operator ++()
00163 {
00164 ++current_;
00165 return *this;
00166 }
00167
00168 ConstStringIterator operator ++(int)
00169 {
00170 ConstStringIterator it( *this );
00171 ++current_;
00172 return it;
00173 }
00174
00175 ConstStringIterator &operator --()
00176 {
00177 --current_;
00178 return *this;
00179 }
00180
00181 ConstStringIterator operator --(int)
00182 {
00183 ConstStringIterator it( *this );
00184 --current_;
00185 return it;
00186 }
00187
00188 bool operator ==( const ConstStringIterator &other ) const
00189 {
00190 return current_ == other.current_;
00191 }
00192
00193 bool operator !=( const ConstStringIterator &other ) const
00194 {
00195 return current_ != other.current_;
00196 }
00197
00198 bool operator <( const ConstStringIterator &other ) const
00199 {
00200 return current_ < other.current_;
00201 }
00202
00203 bool operator <=( const ConstStringIterator &other ) const
00204 {
00205 return current_ <= other.current_;
00206 }
00207
00208 bool operator >( const ConstStringIterator &other ) const
00209 {
00210 return current_ > other.current_;
00211 }
00212
00213 bool operator >=( const ConstStringIterator &other ) const
00214 {
00215 return current_ >= other.current_;
00216 }
00217
00218 private:
00219 const value_type *current_;
00220 };
00221
00222
00223 class ConstString
00224 {
00225 public:
00226 typedef unsigned int size_type;
00227 typedef char value_type;
00228 typedef ConstStringIterator const_iterator;
00229
00230 ConstString();
00231 ConstString( const value_type *csz );
00232 ConstString( const value_type *begin, const value_type *end );
00233 ConstString( const value_type *begin, size_type length );
00234 ConstString( const StringConcatenator &concatenator );
00235 ConstString( const StringBuffer &buffer );
00236 ConstString( const ConstCharView &view );
00237 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00238 ConstString( const std::string &string );
00239 # endif
00240 ConstString( const ConstString &other );
00241
00242 ~ConstString();
00243
00244 ConstString &operator =( const ConstString &other );
00245 ConstString &operator =( const char *other );
00246 ConstString &operator =( const StringConcatenator &concatenator );
00247 ConstString &operator =( const StringBuffer &buffer );
00248 ConstString &operator =( const ConstCharView &view );
00249 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00250 ConstString &operator =( const std::string &other );
00251 # endif
00252 void swap( ConstString &other );
00253
00254 ConstString &operator +=( const ConstString &other );
00255 ConstString &operator +=( const char *other );
00256 ConstString &operator +=( const StringConcatenator &concatenator );
00257 ConstString &operator +=( const StringBuffer &buffer );
00258 ConstString &operator +=( const ConstCharView &view );
00259 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00260 ConstString &operator +=( const std::string &string );
00261 # endif
00262
00263 const value_type *c_str() const;
00264 const value_type *end_c_str() const;
00265 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00266 std::string str() const;
00267 # endif
00268
00269 ConstStringIterator begin() const;
00270 ConstStringIterator end() const;
00271
00272 size_type length() const;
00273 size_type size() const;
00274 bool empty() const;
00275
00276 value_type operator[]( size_type index ) const;
00277
00278 ConstString substr( size_type index,
00279 size_type length = size_type(-1) ) const;
00280
00281 private:
00282 size_type length_;
00283 char *buffer_;
00284 };
00285
00286 bool operator ==( const ConstString &left, const char *other );
00287 bool operator !=( const ConstString &left, const char *other );
00288 bool operator <( const ConstString &left, const char *other );
00289 bool operator <=( const ConstString &left, const char *other );
00290 bool operator >=( const ConstString &left, const char *other );
00291 bool operator >( const ConstString &left, const char *other );
00292
00293 bool operator ==( const ConstString &left, const ConstString &other );
00294 bool operator !=( const ConstString &left, const ConstString &other );
00295 bool operator <( const ConstString &left, const ConstString &other );
00296 bool operator <=( const ConstString &left, const ConstString &other );
00297 bool operator >=( const ConstString &left, const ConstString &other );
00298 bool operator >( const ConstString &left, const ConstString &other );
00299
00300 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00301 std::ostream &operator <<( std::ostream &os, const ConstString &str );
00302 std::istream &operator >>( std::istream &os, ConstString &str );
00303 # endif
00304
00305 class StringBuffer
00306 {
00307 public:
00308 typedef unsigned int size_type;
00309 typedef char value_type;
00310
00311 StringBuffer( unsigned int capacity = 127 );
00312 StringBuffer( const StringBuffer &other );
00313 ~StringBuffer();
00314
00315 StringBuffer &operator =( const StringBuffer &other );
00316 void swap( StringBuffer &other );
00317
00318 void reserve( size_type newCapacity );
00319 size_type capacity() const;
00320
00321 size_type length() const;
00322 void truncate( size_type length );
00323
00324 StringBuffer &operator +=( const StringConcatenator &other );
00325 StringBuffer &operator +=( const ConstString &other );
00326 StringBuffer &operator +=( const char *other );
00327 StringBuffer &operator +=( const ConstCharView &other );
00328 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00329 StringBuffer &operator +=( const std::string &other );
00330 # endif
00331
00332 char &operator[]( size_type index );
00333 char operator[]( size_type index ) const;
00334 const char *c_str() const;
00335
00336 ConstString substr( size_type index,
00337 size_type length = size_type(-1) ) const;
00338
00339 private:
00340 void prepareBuffer( size_type length );
00341
00342 char *buffer_;
00343 size_type length_;
00344 size_type capacity_;
00345 };
00346
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 inline CppTL::StringConcatenator
00359 operator +( const char *left, const CppTL::ConstString &right ) {
00360 return CppTL::StringConcatenator( left, right );
00361 }
00362
00363 inline CppTL::StringConcatenator
00364 operator +( const char *left, const CppTL::StringConcatenator &right ) {
00365 return CppTL::StringConcatenator( left, right );
00366 }
00367
00368 inline CppTL::StringConcatenator
00369 operator +( const char *left, const CppTL::StringBuffer &right ) {
00370 return CppTL::StringConcatenator( left, right );
00371 }
00372
00373 inline CppTL::StringConcatenator
00374 operator +( const char *left, const CppTL::ConstCharView &right ) {
00375 return CppTL::StringConcatenator( left, right );
00376 }
00377
00378
00379 inline CppTL::StringConcatenator
00380 operator +( const CppTL::ConstString &left, const char *right ) {
00381 return CppTL::StringConcatenator( left, right );
00382 }
00383
00384 inline CppTL::StringConcatenator
00385 operator +( const CppTL::ConstString &left, const CppTL::ConstString &right ) {
00386 return CppTL::StringConcatenator( left, right );
00387 }
00388
00389 inline CppTL::StringConcatenator
00390 operator +( const CppTL::ConstString &left, const CppTL::StringConcatenator &right ) {
00391 return CppTL::StringConcatenator( left, right );
00392 }
00393
00394 inline CppTL::StringConcatenator
00395 operator +( const CppTL::ConstString &left, const CppTL::StringBuffer &right ) {
00396 return CppTL::StringConcatenator( left, right );
00397 }
00398
00399 inline CppTL::StringConcatenator
00400 operator +( const CppTL::ConstString &left, const CppTL::ConstCharView &right ) {
00401 return CppTL::StringConcatenator( left, right );
00402 }
00403
00404
00405 inline CppTL::StringConcatenator
00406 operator +( const CppTL::StringConcatenator &left, const char *right ) {
00407 return CppTL::StringConcatenator( left, right );
00408 }
00409
00410 inline CppTL::StringConcatenator
00411 operator +( const CppTL::StringConcatenator &left, const CppTL::ConstString &right ) {
00412 return CppTL::StringConcatenator( left, right );
00413 }
00414
00415 inline CppTL::StringConcatenator
00416 operator +( const CppTL::StringConcatenator &left, const CppTL::StringConcatenator &right ) {
00417 return CppTL::StringConcatenator( left, right );
00418 }
00419
00420 inline CppTL::StringConcatenator
00421 operator +( const CppTL::StringConcatenator &left, const CppTL::StringBuffer &right ) {
00422 return CppTL::StringConcatenator( left, right );
00423 }
00424
00425 inline CppTL::StringConcatenator
00426 operator +( const CppTL::StringConcatenator &left, const CppTL::ConstCharView &right ) {
00427 return CppTL::StringConcatenator( left, right );
00428 }
00429
00430
00431 inline CppTL::StringConcatenator
00432 operator +( const CppTL::StringBuffer &left, const char *right ) {
00433 return CppTL::StringConcatenator( left, right );
00434 }
00435
00436 inline CppTL::StringConcatenator
00437 operator +( const CppTL::StringBuffer &left, const CppTL::ConstString &right ) {
00438 return CppTL::StringConcatenator( left, right );
00439 }
00440
00441 inline CppTL::StringConcatenator
00442 operator +( const CppTL::StringBuffer &left, const CppTL::StringConcatenator &right ) {
00443 return CppTL::StringConcatenator( left, right );
00444 }
00445
00446 inline CppTL::StringConcatenator
00447 operator +( const CppTL::StringBuffer &left, const CppTL::StringBuffer &right ) {
00448 return CppTL::StringConcatenator( left, right );
00449 }
00450
00451 inline CppTL::StringConcatenator
00452 operator +( const CppTL::StringBuffer &left, const CppTL::ConstCharView &right ) {
00453 return CppTL::StringConcatenator( left, right );
00454 }
00455
00456
00457 inline CppTL::StringConcatenator
00458 operator +( const CppTL::ConstCharView &left, const char *right ) {
00459 return CppTL::StringConcatenator( left, right );
00460 }
00461
00462 inline CppTL::StringConcatenator
00463 operator +( const CppTL::ConstCharView &left, const CppTL::ConstString &right ) {
00464 return CppTL::StringConcatenator( left, right );
00465 }
00466
00467 inline CppTL::StringConcatenator
00468 operator +( const CppTL::ConstCharView &left, const CppTL::StringConcatenator &right ) {
00469 return CppTL::StringConcatenator( left, right );
00470 }
00471
00472 inline CppTL::StringConcatenator
00473 operator +( const CppTL::ConstCharView &left, const CppTL::StringBuffer &right ) {
00474 return CppTL::StringConcatenator( left, right );
00475 }
00476
00477 inline CppTL::StringConcatenator
00478 operator +( const CppTL::ConstCharView &left, const CppTL::ConstCharView &right ) {
00479 return CppTL::StringConcatenator( left, right );
00480 }
00481
00482
00483 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00484 inline CppTL::StringConcatenator
00485 operator +( const CppTL::ConstString &left, const std::string &right ) {
00486 return CppTL::StringConcatenator( left, right );
00487 }
00488
00489 inline CppTL::StringConcatenator
00490 operator +( const CppTL::StringConcatenator &left, const std::string &right ) {
00491 return CppTL::StringConcatenator( left, right );
00492 }
00493
00494 inline CppTL::StringConcatenator
00495 operator +( const CppTL::StringBuffer &left, const std::string &right ) {
00496 return CppTL::StringConcatenator( left, right );
00497 }
00498
00499 inline CppTL::StringConcatenator
00500 operator +( const CppTL::ConstCharView &left, const std::string &right ) {
00501 return CppTL::StringConcatenator( left, right );
00502 }
00503
00504 inline CppTL::StringConcatenator
00505 operator +( const std::string &left, const CppTL::ConstString &right ) {
00506 return CppTL::StringConcatenator( left, right );
00507 }
00508
00509 inline CppTL::StringConcatenator
00510 operator +( const std::string &left, const CppTL::StringConcatenator &right ) {
00511 return CppTL::StringConcatenator( left, right );
00512 }
00513
00514 inline CppTL::StringConcatenator
00515 operator +( const std::string &left, const CppTL::StringBuffer &right ) {
00516 return CppTL::StringConcatenator( left, right );
00517 }
00518
00519 inline CppTL::StringConcatenator
00520 operator +( const std::string &left, const CppTL::ConstCharView &right ) {
00521 return CppTL::StringConcatenator( left, right );
00522 }
00523
00524 # endif
00525
00526
00527
00528 namespace CppTL {
00529
00530
00531
00532
00533
00534
00535
00536 inline
00537 StringConcatenator::StringConcatenator( const SubString &left,
00538 const SubString &right )
00539 : left_( left )
00540 , right_( right )
00541 {
00542 }
00543
00544
00545 inline StringConcatenator::size_type
00546 StringConcatenator::length() const
00547 {
00548 return left_.length() + right_.length();
00549 }
00550
00551
00552 inline void
00553 StringConcatenator::copyToBuffer( value_type *buffer ) const
00554 {
00555 left_.copyToBuffer( buffer );
00556 right_.copyToBuffer( buffer + left_.length() );
00557 }
00558
00559
00560
00561
00562 inline
00563 StringConcatenator::SubString::SubString( const value_type *csz )
00564 : kind_( cszString )
00565 , csz_( csz )
00566 , length_( value_type(-1) )
00567 {
00568 }
00569
00570
00571 inline
00572 StringConcatenator::SubString::SubString( const StringConcatenator &other )
00573 : kind_( concatenator )
00574 , concatenator_( &other )
00575 , length_( value_type(-1) )
00576 {
00577 }
00578
00579
00580 inline
00581 StringConcatenator::SubString::SubString( const ConstString &source )
00582 : kind_( string )
00583 , string_( &source )
00584 , length_( value_type(-1) )
00585 {
00586 }
00587
00588
00589 inline
00590 StringConcatenator::SubString::SubString( const StringBuffer &source )
00591 : kind_( stringBuffer )
00592 , buffer_( &source )
00593 , length_( value_type(-1) )
00594 {
00595 }
00596
00597
00598 inline
00599 StringConcatenator::SubString::SubString( const ConstCharView &view )
00600 : kind_( constCharView )
00601 , constCharView_( &view )
00602 , length_( view.length() )
00603 {
00604 }
00605
00606
00607 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00608 inline
00609 StringConcatenator::SubString::SubString( const std::string &source )
00610 : kind_( stdString )
00611 , stdString_( &source )
00612 , length_( value_type(-1) )
00613 {
00614 }
00615 # endif
00616
00617 inline StringConcatenator::size_type
00618 StringConcatenator::SubString::length() const
00619 {
00620 if ( length_ != value_type(-1) )
00621 return length_;
00622
00623 switch ( kind_ )
00624 {
00625 case concatenator:
00626 length_ = concatenator_->length();
00627 break;
00628 case cszString:
00629 length_ = size_type( strlen( csz_ ) );
00630 break;
00631 case string:
00632 length_ = string_->length();
00633 break;
00634 case stringBuffer:
00635 length_ = buffer_->length();
00636 break;
00637 case constCharView:
00638 length_ = constCharView_->length();
00639 break;
00640 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00641 case stdString:
00642 length_ = size_type( stdString_->length() );
00643 break;
00644 # endif
00645 default:
00646 CPPTL_ASSERT_MESSAGE( false, "unreachable" );
00647 break;
00648 }
00649 return length_;
00650 }
00651
00652 inline void
00653 StringConcatenator::SubString::copyToBuffer( value_type *buffer ) const
00654 {
00655 switch ( kind_ )
00656 {
00657 case concatenator:
00658 concatenator_->copyToBuffer( buffer );
00659 break;
00660 case cszString:
00661 memcpy( buffer, csz_, length() );
00662 break;
00663 case string:
00664 memcpy( buffer, string_->c_str(), length() );
00665 break;
00666 case stringBuffer:
00667 memcpy( buffer, buffer_->c_str(), length() );
00668 break;
00669 case constCharView:
00670 memcpy( buffer, constCharView_->begin(), length() );
00671 break;
00672 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00673 case stdString:
00674 memcpy( buffer, stdString_->c_str(), length() );
00675 break;
00676 # endif
00677 default:
00678 CPPTL_ASSERT_MESSAGE( false, "unreachable" );
00679 break;
00680 }
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 inline
00692 ConstString::ConstString()
00693 : length_( 0 )
00694 , buffer_( 0 )
00695 {
00696 }
00697
00698
00699 inline
00700 ConstString::ConstString( const value_type *csz )
00701 : length_( csz ? size_type(strlen( csz )) : 0 )
00702 , buffer_( new value_type[length_+1] )
00703 {
00704 memcpy( buffer_, csz, length_ );
00705 buffer_[ length_ ] = 0;
00706 }
00707
00708
00709 inline
00710 ConstString::ConstString( const value_type *begin, const value_type *end )
00711 : length_( size_type(end - begin) )
00712 , buffer_( new value_type[end-begin+1] )
00713 {
00714 memcpy( buffer_, begin, end-begin );
00715 buffer_[ length_ ] = 0;
00716 }
00717
00718
00719 inline
00720 ConstString::ConstString( const value_type *csz, size_type length )
00721 : length_( length )
00722 , buffer_( new value_type[length+1] )
00723 {
00724 memcpy( buffer_, csz, length );
00725 buffer_[ length_ ] = 0;
00726 }
00727
00728
00729 inline
00730 ConstString::ConstString( const ConstCharView &view )
00731 : length_( view.length() )
00732 , buffer_( new value_type[view.length()+1] )
00733 {
00734 memcpy( buffer_, view.begin(), view.length() );
00735 buffer_[ length_ ] = 0;
00736 }
00737
00738
00739 inline
00740 ConstString::ConstString( const StringConcatenator &concatenator )
00741 : length_( concatenator.length() )
00742 , buffer_( new value_type[length_+1] )
00743 {
00744 buffer_[length_] = 0;
00745 concatenator.copyToBuffer( buffer_ );
00746 }
00747
00748
00749 inline
00750 ConstString::ConstString( const StringBuffer &buffer )
00751 : length_( buffer.length() )
00752 , buffer_( new value_type[length_+1] )
00753 {
00754 buffer_[length_] = 0;
00755 memcpy( buffer_, buffer.c_str(), length_ );
00756 }
00757
00758
00759 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00760 inline
00761 ConstString::ConstString( const std::string &string )
00762 : length_( size_type(string.length()) )
00763 , buffer_( new value_type[length_+1] )
00764 {
00765 buffer_[length_] = 0;
00766 memcpy( buffer_, string.c_str(), length_ );
00767 }
00768 # endif
00769
00770
00771 inline
00772 ConstString::ConstString( const ConstString &other )
00773 : length_( other.length_ )
00774 , buffer_( 0 )
00775 {
00776 if ( length_ > 0 )
00777 {
00778 buffer_ = new value_type[length_+1];
00779 memcpy( buffer_, other.buffer_, length_+1 );
00780 }
00781 }
00782
00783
00784 inline
00785 ConstString::~ConstString()
00786 {
00787 delete [] buffer_;
00788 }
00789
00790
00791 inline ConstString &
00792 ConstString::operator =( const ConstString &other )
00793 {
00794 ConstString temp( other );
00795 swap( temp );
00796 return *this;
00797 }
00798
00799
00800 inline ConstString &
00801 ConstString::operator =( const char *other )
00802 {
00803 ConstString temp( other );
00804 swap( temp );
00805 return *this;
00806 }
00807
00808
00809 inline ConstString &
00810 ConstString::operator =( const StringConcatenator &concatenator )
00811 {
00812 ConstString temp( concatenator );
00813 swap( temp );
00814 return *this;
00815 }
00816
00817
00818 inline ConstString &
00819 ConstString::operator =( const StringBuffer &buffer )
00820 {
00821 ConstString temp( buffer );
00822 swap( temp );
00823 return *this;
00824 }
00825
00826
00827 inline ConstString &
00828 ConstString::operator =( const ConstCharView &view )
00829 {
00830 ConstString temp( view );
00831 swap( temp );
00832 return *this;
00833 }
00834
00835
00836 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00837 inline ConstString &
00838 ConstString::operator =( const std::string &string )
00839 {
00840 ConstString temp( string );
00841 swap( temp );
00842 return *this;
00843 }
00844 # endif
00845
00846
00847 inline ConstString &
00848 ConstString::operator +=( const ConstString &other )
00849 {
00850 return *this = *this + other;
00851 }
00852
00853
00854 inline ConstString &
00855 ConstString::operator +=( const char *other )
00856 {
00857 return *this = *this + other;
00858 }
00859
00860
00861 inline ConstString &
00862 ConstString::operator +=( const StringConcatenator &concatenator )
00863 {
00864 return *this = *this + concatenator;
00865 }
00866
00867
00868 inline ConstString &
00869 ConstString::operator +=( const StringBuffer &buffer )
00870 {
00871 return *this = *this + buffer;
00872 }
00873
00874
00875 inline ConstString &
00876 ConstString::operator +=( const ConstCharView &view )
00877 {
00878 return *this = *this + view;
00879 }
00880
00881
00882 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00883 inline ConstString &
00884 ConstString::operator +=( const std::string &string )
00885 {
00886 return *this = *this + string;
00887 }
00888 # endif
00889
00890
00891 inline void
00892 ConstString::swap( ConstString &other )
00893 {
00894 CppTL::swap( length_, other.length_ );
00895 CppTL::swap( buffer_, other.buffer_ );
00896 }
00897
00898
00899 inline const ConstString::value_type *
00900 ConstString::c_str() const
00901 {
00902 return buffer_ ? buffer_ : "";
00903 }
00904
00905
00906 inline
00907 const ConstString::value_type *
00908 ConstString::end_c_str() const
00909 {
00910 return buffer_ + length_;
00911 }
00912
00913
00914 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
00915 inline std::string
00916 ConstString::str() const
00917 {
00918 return buffer_ ? std::string( c_str(), end_c_str() )
00919 : std::string();
00920 }
00921 # endif
00922
00923
00924 inline ConstStringIterator
00925 ConstString::begin() const
00926 {
00927 return buffer_;
00928 }
00929
00930 inline ConstStringIterator
00931 ConstString::end() const
00932 {
00933 return buffer_ + length_;
00934 }
00935
00936
00937 inline
00938 ConstString::size_type
00939 ConstString::length() const
00940 {
00941 return length_;
00942 }
00943
00944
00945 inline
00946 ConstString::size_type
00947 ConstString::size() const
00948 {
00949 return length();
00950 }
00951
00952
00953 inline bool
00954 ConstString::empty() const
00955 {
00956 return length_ == 0;
00957 }
00958
00959 inline ConstString::value_type
00960 ConstString::operator[]( size_type index ) const
00961 {
00962 return buffer_[index];
00963 }
00964
00965
00966 inline ConstString
00967 ConstString::substr( size_type index,
00968 size_type length ) const
00969 {
00970 if ( index > length_ )
00971 index = length_;
00972 if ( length > length_ - index )
00973 length = length_ - index;
00974 return ConstString( buffer_ + index, length );
00975 }
00976
00977
00978
00979 inline bool operator ==( const ConstString &left, const char *other )
00980 {
00981 return strcmp( left.c_str(), other ) == 0;
00982 }
00983
00984 inline bool operator !=( const ConstString &left, const char *other )
00985 {
00986 return !(left == other );
00987 }
00988
00989 inline bool operator <( const ConstString &left, const char *other )
00990 {
00991 return strcmp( left.c_str(), other ) < 0;
00992 }
00993
00994 inline bool operator <=( const ConstString &left, const char *other )
00995 {
00996 return strcmp( left.c_str(), other ) <= 0;
00997 }
00998
00999 inline bool operator >=( const ConstString &left, const char *other )
01000 {
01001 return strcmp( left.c_str(), other ) >= 0;
01002 }
01003
01004 inline bool operator >( const ConstString &left, const char *other )
01005 {
01006 return strcmp( left.c_str(), other ) > 0;
01007 }
01008
01009
01010
01011
01012
01013 inline bool operator ==( const ConstString &left, const ConstString &other )
01014 {
01015 return left.length() == other.length() &&
01016 strcmp( left.c_str(), other.c_str() ) == 0;
01017 }
01018
01019 inline bool operator !=( const ConstString &left, const ConstString &other )
01020 {
01021 return !(left == other );
01022 }
01023
01024 inline bool operator <( const ConstString &left, const ConstString &other )
01025 {
01026 return strcmp( left.c_str(), other.c_str() ) < 0;
01027 }
01028
01029 inline bool operator <=( const ConstString &left, const ConstString &other )
01030 {
01031 return !( other > left );
01032 }
01033
01034 inline bool operator >=( const ConstString &left, const ConstString &other )
01035 {
01036 return !( other < left );
01037 }
01038
01039 inline bool operator >( const ConstString &left, const ConstString &other )
01040 {
01041 return strcmp( left.c_str(), other.c_str() ) > 0;
01042 }
01043
01044
01045 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
01046 inline std::ostream &operator <<( std::ostream &os, const ConstString &str )
01047 {
01048 return os << str.c_str();
01049 }
01050
01051 inline std::istream &operator >>( std::istream &is, ConstString &str )
01052 {
01053 std::string istr;
01054 is >> istr;
01055 str = istr;
01056 return is;
01057 }
01058 # endif
01059
01060
01061
01062
01063
01064
01065
01066 inline
01067 StringBuffer::StringBuffer( unsigned int capacity )
01068 : capacity_( capacity )
01069 , length_( 0 )
01070 , buffer_( new char[capacity+1] )
01071 {
01072 buffer_[0] = 0;
01073 }
01074
01075 inline
01076 StringBuffer::StringBuffer( const StringBuffer &other )
01077 : capacity_( other.length_ )
01078 , length_( other.length_ )
01079 , buffer_( new char[other.length_+1] )
01080 {
01081 memcpy( buffer_, other.buffer_, length_+1 );
01082 }
01083
01084 inline
01085 StringBuffer::~StringBuffer()
01086 {
01087 delete [] buffer_;
01088 }
01089
01090 inline StringBuffer &
01091 StringBuffer::operator =( const StringBuffer &other )
01092 {
01093 StringBuffer temp( other );
01094 swap( temp );
01095 return *this;
01096 }
01097
01098 inline void
01099 StringBuffer::swap( StringBuffer &other )
01100 {
01101 CppTL::swap( capacity_, other.capacity_ );
01102 CppTL::swap( length_, other.length_ );
01103 CppTL::swap( buffer_, other.buffer_ );
01104 }
01105
01106
01107 inline void
01108 StringBuffer::reserve( size_type newCapacity )
01109 {
01110 if ( newCapacity <= length_ + 1 )
01111 return;
01112
01113 char *newBuffer = new char[newCapacity+1];
01114 memcpy( newBuffer, buffer_, length_+1 );
01115 delete [] buffer_;
01116 buffer_ = newBuffer;
01117
01118 capacity_ = newCapacity;
01119 }
01120
01121 inline StringBuffer::size_type
01122 StringBuffer::capacity() const
01123 {
01124 return capacity_;
01125 }
01126
01127
01128 inline StringBuffer::size_type
01129 StringBuffer::length() const
01130 {
01131 return length_;
01132 }
01133
01134
01135 inline void
01136 StringBuffer::truncate( size_type length )
01137 {
01138 buffer_[length] = 0;
01139 length_ = length;
01140 }
01141
01142
01143 inline StringBuffer &
01144 StringBuffer::operator +=( const StringConcatenator &other )
01145 {
01146 size_type newLength = length_ + other.length();
01147 prepareBuffer( newLength );
01148 other.copyToBuffer( &buffer_[length_] );
01149 truncate(newLength);
01150 return *this;
01151 }
01152
01153 inline StringBuffer &
01154 StringBuffer::operator +=( const ConstString &other )
01155 {
01156 size_type newLength = length_ + other.length();
01157 prepareBuffer( newLength );
01158 memcpy( &buffer_[length_], other.c_str(), other.length() );
01159 truncate(newLength);
01160 return *this;
01161 }
01162
01163
01164 inline StringBuffer &
01165 StringBuffer::operator +=( const char *other )
01166 {
01167 size_type otherLength = size_type(strlen(other));
01168 size_type newLength = length_ + otherLength;
01169 prepareBuffer( newLength );
01170 memcpy( &buffer_[length_], other, otherLength );
01171 truncate(newLength);
01172 return *this;
01173 }
01174
01175
01176 inline StringBuffer &
01177 StringBuffer::operator +=( const ConstCharView &other )
01178 {
01179 size_type newLength = length_ + other.length();
01180 prepareBuffer( newLength );
01181 memcpy( &buffer_[length_], other.begin(), other.length() );
01182 truncate(newLength);
01183 return *this;
01184 }
01185
01186
01187 # ifndef CPPTL_CONSTSTRING_NO_STDSTRING
01188 inline StringBuffer &
01189 StringBuffer::operator +=( const std::string &other )
01190 {
01191 size_type newLength = length_ + other.length();
01192 prepareBuffer( newLength );
01193 memcpy( &buffer_[length_], other.c_str(), other.length() );
01194 truncate(newLength);
01195 return *this;
01196 }
01197 # endif
01198
01199
01200 inline char &
01201 StringBuffer::operator[]( size_type index )
01202 {
01203 return buffer_[index];
01204 }
01205
01206
01207 inline char
01208 StringBuffer::operator[]( size_type index ) const
01209 {
01210 return buffer_[index];
01211 }
01212
01213
01214 inline const char *
01215 StringBuffer::c_str() const
01216 {
01217 return buffer_;
01218 }
01219
01220
01221 inline ConstString
01222 StringBuffer::substr( size_type index,
01223 size_type length ) const
01224 {
01225 if ( index > length_ )
01226 index = length_;
01227 if ( length > length_ - index )
01228 length = length_ - index;
01229 return ConstString( buffer_ + index, length );
01230 }
01231
01232
01233 inline void
01234 StringBuffer::prepareBuffer( size_type length )
01235 {
01236 if ( length <= capacity_ )
01237 return;
01238 size_type newCapacity = (size_type(capacity_ * 1.43 + 16) & ~15) -1;
01239 if ( length > newCapacity )
01240 newCapacity = ((length + 16) & ~15) -1;
01241 reserve( newCapacity );
01242 }
01243
01244 }
01245
01246
01247
01248 #endif // CPPTL_CONSTSTRING_H_INCLUDED