CppUnit project page CppUnit home page

conststring.h

Go to the documentation of this file.
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> // operator << & >>
00008 #  include <iostream> // operator << & >>
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 } // namespace CppTL
00348 
00349 
00350 
00351 // //////////////////////////////////////////////////////////////////
00352 // //////////////////////////////////////////////////////////////////
00353 // operator +, in global namespace... 
00354 // implementation generated by conststring.py
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 // class StringConcatenator
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 // class StringConcatenator::SubString
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 // class ConstString
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 // ConstString / const char *
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 // ConstString / ConstString
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 // class StringBuffer
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 } // namespace CppTL
01245 
01246 
01247 
01248 #endif // CPPTL_CONSTSTRING_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers