MyGUI  3.0.3
MyGUI_UString.h
Go to the documentation of this file.
00001 // Modified from OpenGUI under lenient license
00002 // Original copyright details and licensing below:
00003 // OpenGUI (http://opengui.sourceforge.net)
00004 // This source code is released under the BSD License
00005 
00006 // Permission is given to the MyGUI project to use the contents of file within its
00007 // source and binary applications, as well as any derivative works, in accordance
00008 // with the terms of any license under which MyGUI is or will be distributed.
00009 //
00010 // MyGUI may relicense its copy of this file, as well as any OpenGUI released updates
00011 // to this file, under any terms that it deems fit, and is not required to maintain
00012 // the original BSD licensing terms of this file, however OpenGUI retains the right
00013 // to present its copy of this file under the terms of any license under which
00014 // OpenGUI is distributed.
00015 //
00016 // MyGUI is not required to release to OpenGUI any future changes that it makes to
00017 // this file, and understands and agrees that any such changes that are released
00018 // back to OpenGUI will become available under the terms of any license under which
00019 // OpenGUI is distributed.
00020 //
00021 // For brevity, this permission text may be removed from this file if desired.
00022 // The original record kept within the SourceForge (http://sourceforge.net/) tracker
00023 // is sufficient.
00024 //
00025 // - Eric Shorkey (zero/zeroskill) <opengui@rightbracket.com> [January 20th, 2007]
00026 
00027 #ifndef __MYGUI_U_STRING_H__
00028 #define __MYGUI_U_STRING_H__
00029 
00030 
00031 #include "MyGUI_Prerequest.h"
00032 #include "MyGUI_Types.h"
00033 
00034 // these are explained later
00035 #include <iterator>
00036 #include <string>
00037 #include <stdexcept>
00038 
00039 // Workaround for VC7:
00040 //      when build with /MD or /MDd, VC7 have both std::basic_string<unsigned short> and
00041 // basic_string<__wchar_t> instantiated in msvcprt[d].lib/MSVCP71[D].dll, but the header
00042 // files tells compiler that only one of them is over there (based on /Zc:wchar_t compile
00043 // option). And since this file used both of them, causing compiler instantiating another
00044 // one in user object code, which lead to duplicate symbols with msvcprt.lib/MSVCP71[D].dll.
00045 //
00046 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && (1300 <= MYGUI_COMP_VER && MYGUI_COMP_VER <= 1310)
00047 
00048 # if defined(_DLL_CPPLIB)
00049 
00050 namespace std
00051 {
00052     template class _CRTIMP2 basic_string<unsigned short, char_traits<unsigned short>,
00053         allocator<unsigned short> >;
00054 
00055     template class _CRTIMP2 basic_string<__wchar_t, char_traits<__wchar_t>,
00056         allocator<__wchar_t> >;
00057 }
00058 
00059 # endif // defined(_DLL_CPPLIB)
00060 
00061 #endif  // MYGUI_COMPILER == MYGUI_COMPILER_MSVC && MYGUI_COMP_VER == 1300
00062 
00063 
00064 namespace MyGUI
00065 {
00066 
00067     /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS
00068     =NOTICE=
00069     This class is not a complete Unicode solution. It purposefully does not
00070     provide certain functionality, such as proper lexical sorting for
00071     Unicode values. It does provide comparison operators for the sole purpose
00072     of using UString as an index with std::map and other operator< sorted
00073     containers, but it should NOT be relied upon for meaningful lexical
00074     operations, such as alphabetical sorts. If you need this type of
00075     functionality, look into using ICU instead (http://icu.sourceforge.net/).
00076 
00077     =REQUIREMENTS=
00078     There are a few requirements for proper operation. They are fairly small,
00079     and shouldn't restrict usage on any reasonable target.
00080     * Compiler must support unsigned 16-bit integer types
00081     * Compiler must support signed 32-bit integer types
00082     * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such
00083         using the WCHAR_UTF16 macro as outlined below.
00084     * You must include <iterator>, <string>, and <wchar>. Probably more, but
00085         these are the most obvious.
00086 
00087     =REQUIRED PREPROCESSOR MACROS=
00088     This class requires two preprocessor macros to be defined in order to
00089     work as advertised.
00090     INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int)
00091     UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short)
00092 
00093     Additionally, a third macro should be defined to control the evaluation of wchar_t:
00094     WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points,
00095         such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit
00096         integer representing UTF-32 code points.
00097     */
00098 
00099     // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS
00100 #ifdef __STDC_ISO_10646__
00101 // for any compiler that provides this, wchar_t is guaranteed to hold any Unicode value with a single code point (32-bit or larger)
00102 // so we can safely skip the rest of the testing
00103 #else // #ifdef __STDC_ISO_10646__
00104 #if defined( __WIN32__ ) || defined( _WIN32 )
00105 #define WCHAR_UTF16 // All currently known Windows platforms utilize UTF-16 encoding in wchar_t
00106 #else // #if defined( __WIN32__ ) || defined( _WIN32 )
00107 #if MYGUI_COMPILER != MYGUI_COMPILER_GCCE
00108 #if WCHAR_MAX <= 0xFFFF // this is a last resort fall back test; WCHAR_MAX is defined in <wchar.h>
00109 #define WCHAR_UTF16 // best we can tell, wchar_t is not larger than 16-bit
00110 #endif // #if WCHAR_MAX <= 0xFFFF
00111 #endif
00112 #endif // #if defined( __WIN32__ ) || defined( _WIN32 )
00113 #endif // #ifdef __STDC_ISO_10646__
00114 
00115 
00116 // MYGUI_IS_NATIVE_WCHAR_T means that wchar_t isn't a typedef of
00117 // uint16_t or uint32_t.
00118 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
00119 
00120 // Don't define wchar_t related functions since it'll duplicate
00121 // with UString::code_point related functions when compile
00122 // without /Zc:wchar_t, because in this case both of them are
00123 // a typedef of uint16_t.
00124 # if defined(_NATIVE_WCHAR_T_DEFINED)
00125 #   define MYGUI_IS_NATIVE_WCHAR_T      1
00126 # else
00127 #   define MYGUI_IS_NATIVE_WCHAR_T      0
00128 # endif
00129 #elif MYGUI_PLATFORM == MYGUI_PLATFORM_SYMBIAN
00130 #   define MYGUI_IS_NATIVE_WCHAR_T      0
00131 #else   // MYGUI_COMPILER != MYGUI_COMPILER_MSVC
00132 
00133 // Assumed wchar_t is natively for other compilers
00134 #   define MYGUI_IS_NATIVE_WCHAR_T     1
00135 
00136 #endif  // MYGUI_COMPILER == MYGUI_COMPILER_MSVC
00137 
00139 
00164     class MYGUI_EXPORT UString {
00165         // constants used in UTF-8 conversions
00166         static const unsigned char _lead1 = 0xC0;      //110xxxxx
00167         static const unsigned char _lead1_mask = 0x1F; //00011111
00168         static const unsigned char _lead2 = 0xE0;      //1110xxxx
00169         static const unsigned char _lead2_mask = 0x0F; //00001111
00170         static const unsigned char _lead3 = 0xF0;      //11110xxx
00171         static const unsigned char _lead3_mask = 0x07; //00000111
00172         static const unsigned char _lead4 = 0xF8;      //111110xx
00173         static const unsigned char _lead4_mask = 0x03; //00000011
00174         static const unsigned char _lead5 = 0xFC;      //1111110x
00175         static const unsigned char _lead5_mask = 0x01; //00000001
00176         static const unsigned char _cont = 0x80;       //10xxxxxx
00177         static const unsigned char _cont_mask = 0x3F;  //00111111
00178 
00179     public:
00181         typedef size_t size_type;
00183         static const size_type npos = static_cast<size_type>(~0);
00184 
00186         typedef uint32 unicode_char;
00187 
00189         typedef uint16 code_point;
00190 
00192         typedef code_point value_type;
00193 
00194         typedef std::basic_string<code_point> dstring; // data string
00195 
00197         typedef std::basic_string<unicode_char> utf32string;
00198 
00200     class MYGUI_EXPORT invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */
00201         public:
00203             explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) {
00204                 /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */
00205             }
00206         };
00207 
00208         //#########################################################################
00210     class MYGUI_EXPORT _base_iterator: public std::iterator<std::random_access_iterator_tag, value_type> { /* i don't know why the beautifier is freaking out on this line */
00211             friend class UString;
00212         protected:
00213             _base_iterator();
00214 
00215             void _seekFwd( size_type c );
00216             void _seekRev( size_type c );
00217             void _become( const _base_iterator& i );
00218             bool _test_begin() const;
00219             bool _test_end() const;
00220             size_type _get_index() const;
00221             void _jump_to( size_type index );
00222 
00223             unicode_char _getCharacter() const;
00224             int _setCharacter( unicode_char uc );
00225 
00226             void _moveNext();
00227             void _movePrev();
00228 
00229             dstring::iterator mIter;
00230             UString* mString;
00231         };
00232 
00233         //#########################################################################
00234         // FORWARD ITERATORS
00235         //#########################################################################
00236         class _const_fwd_iterator; // forward declaration
00237 
00239     class MYGUI_EXPORT _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00240             friend class _const_fwd_iterator;
00241         public:
00242             _fwd_iterator();
00243             _fwd_iterator( const _fwd_iterator& i );
00244 
00246             _fwd_iterator& operator++();
00248             _fwd_iterator operator++( int );
00249 
00251             _fwd_iterator& operator--();
00253             _fwd_iterator operator--( int );
00254 
00256             _fwd_iterator operator+( difference_type n );
00258             _fwd_iterator operator-( difference_type n );
00259 
00261             _fwd_iterator& operator+=( difference_type n );
00263             _fwd_iterator& operator-=( difference_type n );
00264 
00266             value_type& operator*() const;
00267 
00269             value_type& operator[]( difference_type n ) const;
00270 
00272             _fwd_iterator& moveNext();
00274             _fwd_iterator& movePrev();
00276             unicode_char getCharacter() const;
00278             int setCharacter( unicode_char uc );
00279         };
00280 
00281 
00282 
00283         //#########################################################################
00285     class MYGUI_EXPORT _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00286         public:
00287             _const_fwd_iterator();
00288             _const_fwd_iterator( const _const_fwd_iterator& i );
00289             _const_fwd_iterator( const _fwd_iterator& i );
00290 
00292             _const_fwd_iterator& operator++();
00294             _const_fwd_iterator operator++( int );
00295 
00297             _const_fwd_iterator& operator--();
00299             _const_fwd_iterator operator--( int );
00300 
00302             _const_fwd_iterator operator+( difference_type n );
00304             _const_fwd_iterator operator-( difference_type n );
00305 
00307             _const_fwd_iterator& operator+=( difference_type n );
00309             _const_fwd_iterator& operator-=( difference_type n );
00310 
00312             const value_type& operator*() const;
00313 
00315             const value_type& operator[]( difference_type n ) const;
00316 
00318             _const_fwd_iterator& moveNext();
00320             _const_fwd_iterator& movePrev();
00322             unicode_char getCharacter() const;
00323 
00325             friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00327             friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00329             friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00331             friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00333             friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00335             friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00337             friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00338 
00339         };
00340 
00341         //#########################################################################
00342         // REVERSE ITERATORS
00343         //#########################################################################
00344         class _const_rev_iterator; // forward declaration
00346     class MYGUI_EXPORT _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00347             friend class _const_rev_iterator;
00348         public:
00349             _rev_iterator();
00350             _rev_iterator( const _rev_iterator& i );
00351 
00353             _rev_iterator& operator++();
00355             _rev_iterator operator++( int );
00356 
00358             _rev_iterator& operator--();
00360             _rev_iterator operator--( int );
00361 
00363             _rev_iterator operator+( difference_type n );
00365             _rev_iterator operator-( difference_type n );
00366 
00368             _rev_iterator& operator+=( difference_type n );
00370             _rev_iterator& operator-=( difference_type n );
00371 
00373             value_type& operator*() const;
00374 
00376             value_type& operator[]( difference_type n ) const;
00377         };
00378         //#########################################################################
00380     class MYGUI_EXPORT _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00381         public:
00382             _const_rev_iterator();
00383             _const_rev_iterator( const _const_rev_iterator& i );
00384             _const_rev_iterator( const _rev_iterator& i );
00386             _const_rev_iterator& operator++();
00388             _const_rev_iterator operator++( int );
00389 
00391             _const_rev_iterator& operator--();
00393             _const_rev_iterator operator--( int );
00394 
00396             _const_rev_iterator operator+( difference_type n );
00398             _const_rev_iterator operator-( difference_type n );
00399 
00401             _const_rev_iterator& operator+=( difference_type n );
00403             _const_rev_iterator& operator-=( difference_type n );
00404 
00406             const value_type& operator*() const;
00407 
00409             const value_type& operator[]( difference_type n ) const;
00410 
00412             friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right );
00414             friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right );
00416             friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00418             friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right );
00420             friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00422             friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right );
00424             friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00425         };
00426         //#########################################################################
00427 
00428         typedef _fwd_iterator iterator;                     
00429         typedef _rev_iterator reverse_iterator;             
00430         typedef _const_fwd_iterator const_iterator;         
00431         typedef _const_rev_iterator const_reverse_iterator; 
00432 
00433 
00435 
00436 
00437         UString();
00439         UString( const UString& copy );
00441         UString( size_type length, const code_point& ch );
00443         UString( const code_point* str );
00445         UString( const code_point* str, size_type length );
00447         UString( const UString& str, size_type index, size_type length );
00448 #if MYGUI_IS_NATIVE_WCHAR_T
00449 
00450         UString( const wchar_t* w_str );
00452         UString( const wchar_t* w_str, size_type length );
00453 #endif
00454 
00455         UString( const std::wstring& wstr );
00457         UString( const char* c_str );
00459         UString( const char* c_str, size_type length );
00461         UString( const std::string& str );
00462 
00464         ~UString();
00466 
00468 
00470 
00471 
00472         size_type size() const;
00474         size_type length() const;
00476 
00477         size_type length_Characters() const;
00479         size_type max_size() const;
00481         void reserve( size_type size );
00483         void resize( size_type num, const code_point& val = 0 );
00485         void swap( UString& from );
00487         bool empty() const;
00489         const code_point* c_str() const;
00491         const code_point* data() const;
00493         size_type capacity() const;
00495         void clear();
00497 
00498         UString substr( size_type index, size_type num = npos ) const;
00500         void push_back( unicode_char val );
00501 #if MYGUI_IS_NATIVE_WCHAR_T
00502 
00503         void push_back( wchar_t val );
00504 #endif
00505 
00506 
00508         void push_back( code_point val );
00510 
00511         void push_back( char val );
00513         bool inString( unicode_char ch ) const;
00515 
00517 
00519 
00520 
00521         const std::string& asUTF8() const;
00523         const char* asUTF8_c_str() const;
00525         const utf32string& asUTF32() const;
00527         const unicode_char* asUTF32_c_str() const;
00529         const std::wstring& asWStr() const;
00531         const wchar_t* asWStr_c_str() const;
00533 
00535 
00537 
00538 
00539         code_point& at( size_type loc );
00541         const code_point& at( size_type loc ) const;
00543 
00547         unicode_char getChar( size_type loc ) const;
00549 
00557         int setChar( size_type loc, unicode_char ch );
00559 
00561 
00563 
00564 
00565         iterator begin();
00567         const_iterator begin() const;
00569         iterator end();
00571         const_iterator end() const;
00573         reverse_iterator rbegin();
00575         const_reverse_iterator rbegin() const;
00577         reverse_iterator rend();
00579         const_reverse_iterator rend() const;
00581 
00583 
00585 
00586 
00587         UString& assign( iterator start, iterator end );
00589         UString& assign( const UString& str );
00591         UString& assign( const code_point* str );
00593         UString& assign( const code_point* str, size_type num );
00595         UString& assign( const UString& str, size_type index, size_type len );
00597         UString& assign( size_type num, const code_point& ch );
00599         UString& assign( const std::wstring& wstr );
00600 #if MYGUI_IS_NATIVE_WCHAR_T
00601 
00602         UString& assign( const wchar_t* w_str );
00604         UString& assign( const wchar_t* w_str, size_type num );
00605 #endif
00606 
00607         UString& assign( const std::string& str );
00609         UString& assign( const char* c_str );
00611         UString& assign( const char* c_str, size_type num );
00613 
00615 
00617 
00618 
00619         UString& append( const UString& str );
00621         UString& append( const code_point* str );
00623         UString& append( const UString& str, size_type index, size_type len );
00625         UString& append( const code_point* str, size_type num );
00627         UString& append( size_type num, code_point ch );
00629         UString& append( iterator start, iterator end );
00630 #if MYGUI_IS_NATIVE_WCHAR_T
00631 
00632         UString& append( const wchar_t* w_str, size_type num );
00634         UString& append( size_type num, wchar_t ch );
00635 #endif
00636 
00637         UString& append( const char* c_str, size_type num );
00639         UString& append( size_type num, char ch );
00641         UString& append( size_type num, unicode_char ch );
00643 
00645 
00647 
00648 
00649         iterator insert( iterator i, const code_point& ch );
00651         UString& insert( size_type index, const UString& str );
00653         UString& insert( size_type index, const code_point* str ) {
00654             mData.insert( index, str );
00655             return *this;
00656         }
00658         UString& insert( size_type index1, const UString& str, size_type index2, size_type num );
00660         void insert( iterator i, iterator start, iterator end );
00662         UString& insert( size_type index, const code_point* str, size_type num );
00663 #if MYGUI_IS_NATIVE_WCHAR_T
00664 
00665         UString& insert( size_type index, const wchar_t* w_str, size_type num );
00666 #endif
00667 
00668         UString& insert( size_type index, const char* c_str, size_type num );
00670         UString& insert( size_type index, size_type num, code_point ch );
00671 #if MYGUI_IS_NATIVE_WCHAR_T
00672 
00673         UString& insert( size_type index, size_type num, wchar_t ch );
00674 #endif
00675 
00676         UString& insert( size_type index, size_type num, char ch );
00678         UString& insert( size_type index, size_type num, unicode_char ch );
00680         void insert( iterator i, size_type num, const code_point& ch );
00681 #if MYGUI_IS_NATIVE_WCHAR_T
00682 
00683         void insert( iterator i, size_type num, const wchar_t& ch );
00684 #endif
00685 
00686         void insert( iterator i, size_type num, const char& ch );
00688         void insert( iterator i, size_type num, const unicode_char& ch );
00690 
00692 
00694 
00695 
00696         iterator erase( iterator loc );
00698         iterator erase( iterator start, iterator end );
00700         UString& erase( size_type index = 0, size_type num = npos );
00702 
00704 
00706 
00707 
00708         UString& replace( size_type index1, size_type num1, const UString& str );
00710         UString& replace( size_type index1, size_type num1, const UString& str, size_type num2 );
00712         UString& replace( size_type index1, size_type num1, const UString& str, size_type index2, size_type num2 );
00714         UString& replace( iterator start, iterator end, const UString& str, size_type num = npos );
00716         UString& replace( size_type index, size_type num1, size_type num2, code_point ch );
00718         UString& replace( iterator start, iterator end, size_type num, code_point ch );
00720 
00722 
00724 
00725 
00726         int compare( const UString& str ) const;
00728         int compare( const code_point* str ) const;
00730         int compare( size_type index, size_type length, const UString& str ) const;
00732         int compare( size_type index, size_type length, const UString& str, size_type index2, size_type length2 ) const;
00734         int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const;
00735 #if MYGUI_IS_NATIVE_WCHAR_T
00736 
00737         int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const;
00738 #endif
00739 
00740         int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const;
00742 
00744 
00746 
00747 
00748 
00749         size_type find( const UString& str, size_type index = 0 ) const;
00751 
00752         size_type find( const code_point* cp_str, size_type index, size_type length ) const;
00754 
00755         size_type find( const char* c_str, size_type index, size_type length ) const;
00756 #if MYGUI_IS_NATIVE_WCHAR_T
00757 
00758 
00759         size_type find( const wchar_t* w_str, size_type index, size_type length ) const;
00760 #endif
00761 
00762 
00763         size_type find( char ch, size_type index = 0 ) const;
00765 
00766         size_type find( code_point ch, size_type index = 0 ) const;
00767 #if MYGUI_IS_NATIVE_WCHAR_T
00768 
00769 
00770         size_type find( wchar_t ch, size_type index = 0 ) const;
00771 #endif
00772 
00773 
00774         size_type find( unicode_char ch, size_type index = 0 ) const;
00775 
00777         size_type rfind( const UString& str, size_type index = 0 ) const;
00779         size_type rfind( const code_point* cp_str, size_type index, size_type num ) const;
00781         size_type rfind( const char* c_str, size_type index, size_type num ) const;
00782 #if MYGUI_IS_NATIVE_WCHAR_T
00783 
00784         size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const;
00785 #endif
00786 
00787         size_type rfind( char ch, size_type index = 0 ) const;
00789         size_type rfind( code_point ch, size_type index ) const;
00790 #if MYGUI_IS_NATIVE_WCHAR_T
00791 
00792         size_type rfind( wchar_t ch, size_type index = 0 ) const;
00793 #endif
00794 
00795         size_type rfind( unicode_char ch, size_type index = 0 ) const;
00797 
00799 
00801 
00802 
00803         size_type find_first_of( const UString &str, size_type index = 0, size_type num = npos ) const;
00805         size_type find_first_of( code_point ch, size_type index = 0 ) const;
00807         size_type find_first_of( char ch, size_type index = 0 ) const;
00808 #if MYGUI_IS_NATIVE_WCHAR_T
00809 
00810         size_type find_first_of( wchar_t ch, size_type index = 0 ) const;
00811 #endif
00812 
00813         size_type find_first_of( unicode_char ch, size_type index = 0 ) const;
00814 
00816         size_type find_first_not_of( const UString& str, size_type index = 0, size_type num = npos ) const;
00818         size_type find_first_not_of( code_point ch, size_type index = 0 ) const;
00820         size_type find_first_not_of( char ch, size_type index = 0 ) const;
00821 #if MYGUI_IS_NATIVE_WCHAR_T
00822 
00823         size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const;
00824 #endif
00825 
00826         size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const;
00827 
00829         size_type find_last_of( const UString& str, size_type index = npos, size_type num = npos ) const;
00831         size_type find_last_of( code_point ch, size_type index = npos ) const;
00833         size_type find_last_of( char ch, size_type index = npos ) const {
00834             return find_last_of( static_cast<code_point>( ch ), index );
00835         }
00836 #if MYGUI_IS_NATIVE_WCHAR_T
00837 
00838         size_type find_last_of( wchar_t ch, size_type index = npos ) const;
00839 #endif
00840 
00841         size_type find_last_of( unicode_char ch, size_type index = npos ) const;
00842 
00844         size_type find_last_not_of( const UString& str, size_type index = npos, size_type num = npos ) const;
00846         size_type find_last_not_of( code_point ch, size_type index = npos ) const;
00848         size_type find_last_not_of( char ch, size_type index = npos ) const;
00849 #if MYGUI_IS_NATIVE_WCHAR_T
00850 
00851         size_type find_last_not_of( wchar_t ch, size_type index = npos ) const;
00852 #endif
00853 
00854         size_type find_last_not_of( unicode_char ch, size_type index = npos ) const;
00856 
00858 
00860 
00861 
00862         bool operator<( const UString& right ) const;
00864         bool operator<=( const UString& right ) const;
00866         bool operator>( const UString& right ) const;
00868         bool operator>=( const UString& right ) const;
00870         bool operator==( const UString& right ) const;
00872         bool operator!=( const UString& right ) const;
00874         UString& operator=( const UString& s );
00876         UString& operator=( code_point ch );
00878         UString& operator=( char ch );
00879 #if MYGUI_IS_NATIVE_WCHAR_T
00880 
00881         UString& operator=( wchar_t ch );
00882 #endif
00883 
00884         UString& operator=( unicode_char ch );
00886         code_point& operator[]( size_type index );
00888         const code_point& operator[]( size_type index ) const;
00890 
00892 
00894 
00895 
00896         operator std::string() const;
00898         operator std::wstring() const;
00900 
00902 
00904 
00905 
00906         static bool _utf16_independent_char( code_point cp );
00908         static bool _utf16_surrogate_lead( code_point cp );
00910         static bool _utf16_surrogate_follow( code_point cp );
00912         static size_t _utf16_char_length( code_point cp );
00914         static size_t _utf16_char_length( unicode_char uc );
00916 
00920         static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc );
00922 
00927         static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] );
00929 
00931 
00933 
00934 
00935         static bool _utf8_start_char( unsigned char cp );
00937         static size_t _utf8_char_length( unsigned char cp );
00939         static size_t _utf8_char_length( unicode_char uc );
00940 
00942         static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc );
00944         static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] );
00945 
00947         static size_type _verifyUTF8( const unsigned char* c_str );
00949         static size_type _verifyUTF8( const std::string& str );
00951 
00952     private:
00953         //template<class ITER_TYPE> friend class _iterator;
00954         dstring mData;
00955 
00957         enum BufferType {
00958             bt_none,
00959             bt_string,
00960             bt_wstring,
00961             bt_utf32string
00962         };
00963 
00965         void _init();
00966 
00968         // Scratch buffer
00970         void _cleanBuffer() const;
00971 
00973         void _getBufferStr() const;
00975         void _getBufferWStr() const;
00977         void _getBufferUTF32Str() const;
00978 
00979         void _load_buffer_UTF8() const;
00980         void _load_buffer_WStr() const;
00981         void _load_buffer_UTF32() const;
00982 
00983         mutable BufferType m_bufferType; // identifies the data type held in m_buffer
00984         mutable size_t m_bufferSize; // size of the CString buffer
00985 
00986         // multi-purpose buffer used everywhere we need a throw-away buffer
00987         union {
00988             mutable void* mVoidBuffer;
00989             mutable std::string* mStrBuffer;
00990             mutable std::wstring* mWStrBuffer;
00991             mutable utf32string* mUTF32StrBuffer;
00992         }
00993         m_buffer;
00994     };
00995 
00997     inline UString operator+( const UString& s1, const UString& s2 ) {
00998         return UString( s1 ).append( s2 );
00999     }
01001     inline UString operator+( const UString& s1, UString::code_point c ) {
01002         return UString( s1 ).append( 1, c );
01003     }
01005     inline UString operator+( const UString& s1, UString::unicode_char c ) {
01006         return UString( s1 ).append( 1, c );
01007     }
01009     inline UString operator+( const UString& s1, char c ) {
01010         return UString( s1 ).append( 1, c );
01011     }
01012 #if MYGUI_IS_NATIVE_WCHAR_T
01013 
01014     inline UString operator+( const UString& s1, wchar_t c ) {
01015         return UString( s1 ).append( 1, c );
01016     }
01017 #endif
01018 
01019     inline UString operator+( UString::code_point c, const UString& s2 ) {
01020         return UString().append( 1, c ).append( s2 );
01021     }
01023     inline UString operator+( UString::unicode_char c, const UString& s2 ) {
01024         return UString().append( 1, c ).append( s2 );
01025     }
01027     inline UString operator+( char c, const UString& s2 ) {
01028         return UString().append( 1, c ).append( s2 );
01029     }
01030 #if MYGUI_IS_NATIVE_WCHAR_T
01031 
01032     inline UString operator+( wchar_t c, const UString& s2 ) {
01033         return UString().append( 1, c ).append( s2 );
01034     }
01035 #endif
01036 
01037     // (const) forward iterator common operators
01038     inline UString::size_type operator-( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01039         return ( left.mIter - right.mIter );
01040     }
01041     inline bool operator==( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01042         return left.mIter == right.mIter;
01043     }
01044     inline bool operator!=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01045         return left.mIter != right.mIter;
01046     }
01047     inline bool operator<( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01048         return left.mIter < right.mIter;
01049     }
01050     inline bool operator<=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01051         return left.mIter <= right.mIter;
01052     }
01053     inline bool operator>( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01054         return left.mIter > right.mIter;
01055     }
01056     inline bool operator>=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01057         return left.mIter >= right.mIter;
01058     }
01059 
01060     // (const) reverse iterator common operators
01061     // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator
01062     inline UString::size_type operator-( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01063         return ( right.mIter - left.mIter );
01064     }
01065     inline bool operator==( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01066         return left.mIter == right.mIter;
01067     }
01068     inline bool operator!=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01069         return left.mIter != right.mIter;
01070     }
01071     inline bool operator<( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01072         return right.mIter < left.mIter;
01073     }
01074     inline bool operator<=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01075         return right.mIter <= left.mIter;
01076     }
01077     inline bool operator>( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01078         return right.mIter > left.mIter;
01079     }
01080     inline bool operator>=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01081         return right.mIter >= left.mIter;
01082     }
01083 
01085     inline std::ostream& operator << ( std::ostream& os, const UString& s ) {
01086         return os << s.asUTF8();
01087     }
01088 
01090     inline std::wostream& operator << ( std::wostream& os, const UString& s ) {
01091         return os << s.asWStr();
01092     }
01093 
01094 } // namespace MyGUI
01095 
01096 #endif  // __MYGUI_U_STRING_H__