MyGUI  3.2.0
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 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
00040 // disable: warning C4275: non dll-interface class '***' used as base for dll-interface clas '***'
00041 #   pragma warning (disable : 4275)
00042 #endif
00043 
00044 // Workaround for VC7:
00045 //      when build with /MD or /MDd, VC7 have both std::basic_string<unsigned short> and
00046 // basic_string<__wchar_t> instantiated in msvcprt[d].lib/MSVCP71[D].dll, but the header
00047 // files tells compiler that only one of them is over there (based on /Zc:wchar_t compile
00048 // option). And since this file used both of them, causing compiler instantiating another
00049 // one in user object code, which lead to duplicate symbols with msvcprt.lib/MSVCP71[D].dll.
00050 //
00051 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && (1300 <= MYGUI_COMP_VER && MYGUI_COMP_VER <= 1310)
00052 
00053 # if defined(_DLL_CPPLIB)
00054 
00055 namespace std
00056 {
00057     template class _CRTIMP2 basic_string<unsigned short, char_traits<unsigned short>,
00058         allocator<unsigned short> >;
00059 
00060     template class _CRTIMP2 basic_string<__wchar_t, char_traits<__wchar_t>,
00061         allocator<__wchar_t> >;
00062 }
00063 
00064 # endif // defined(_DLL_CPPLIB)
00065 
00066 #endif  // MYGUI_COMPILER == MYGUI_COMPILER_MSVC && MYGUI_COMP_VER == 1300
00067 
00068 
00069 namespace MyGUI
00070 {
00071 
00072     /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS
00073     =NOTICE=
00074     This class is not a complete Unicode solution. It purposefully does not
00075     provide certain functionality, such as proper lexical sorting for
00076     Unicode values. It does provide comparison operators for the sole purpose
00077     of using UString as an index with std::map and other operator< sorted
00078     containers, but it should NOT be relied upon for meaningful lexical
00079     operations, such as alphabetical sorts. If you need this type of
00080     functionality, look into using ICU instead (http://icu.sourceforge.net/).
00081 
00082     =REQUIREMENTS=
00083     There are a few requirements for proper operation. They are fairly small,
00084     and shouldn't restrict usage on any reasonable target.
00085     * Compiler must support unsigned 16-bit integer types
00086     * Compiler must support signed 32-bit integer types
00087     * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such
00088         using the WCHAR_UTF16 macro as outlined below.
00089     * You must include <iterator>, <string>, and <wchar>. Probably more, but
00090         these are the most obvious.
00091 
00092     =REQUIRED PREPROCESSOR MACROS=
00093     This class requires two preprocessor macros to be defined in order to
00094     work as advertised.
00095     INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int)
00096     UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short)
00097 
00098     Additionally, a third macro should be defined to control the evaluation of wchar_t:
00099     WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points,
00100         such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit
00101         integer representing UTF-32 code points.
00102     */
00103 
00104     // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS
00105 #ifdef __STDC_ISO_10646__
00106 // for any compiler that provides this, wchar_t is guaranteed to hold any Unicode value with a single code point (32-bit or larger)
00107 // so we can safely skip the rest of the testing
00108 #else // #ifdef __STDC_ISO_10646__
00109 #if defined( __WIN32__ ) || defined( _WIN32 )
00110 #define WCHAR_UTF16 // All currently known Windows platforms utilize UTF-16 encoding in wchar_t
00111 #else // #if defined( __WIN32__ ) || defined( _WIN32 )
00112 #if MYGUI_COMPILER != MYGUI_COMPILER_GCCE
00113 #if WCHAR_MAX <= 0xFFFF // this is a last resort fall back test; WCHAR_MAX is defined in <wchar.h>
00114 #define WCHAR_UTF16 // best we can tell, wchar_t is not larger than 16-bit
00115 #endif // #if WCHAR_MAX <= 0xFFFF
00116 #endif
00117 #endif // #if defined( __WIN32__ ) || defined( _WIN32 )
00118 #endif // #ifdef __STDC_ISO_10646__
00119 
00120 
00121 // MYGUI_IS_NATIVE_WCHAR_T means that wchar_t isn't a typedef of
00122 // uint16_t or uint32_t.
00123 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
00124 
00125 // Don't define wchar_t related functions since it'll duplicate
00126 // with UString::code_point related functions when compile
00127 // without /Zc:wchar_t, because in this case both of them are
00128 // a typedef of uint16_t.
00129 # if defined(_NATIVE_WCHAR_T_DEFINED)
00130 #   define MYGUI_IS_NATIVE_WCHAR_T      1
00131 # else
00132 #   define MYGUI_IS_NATIVE_WCHAR_T      0
00133 # endif
00134 #elif MYGUI_PLATFORM == MYGUI_PLATFORM_SYMBIAN
00135 #   define MYGUI_IS_NATIVE_WCHAR_T      0
00136 #else   // MYGUI_COMPILER != MYGUI_COMPILER_MSVC
00137 
00138 // Assumed wchar_t is natively for other compilers
00139 #   define MYGUI_IS_NATIVE_WCHAR_T     1
00140 
00141 #endif  // MYGUI_COMPILER == MYGUI_COMPILER_MSVC
00142 
00144 
00169     class MYGUI_EXPORT UString {
00170         // constants used in UTF-8 conversions
00171         static const unsigned char _lead1 = 0xC0;      //110xxxxx
00172         static const unsigned char _lead1_mask = 0x1F; //00011111
00173         static const unsigned char _lead2 = 0xE0;      //1110xxxx
00174         static const unsigned char _lead2_mask = 0x0F; //00001111
00175         static const unsigned char _lead3 = 0xF0;      //11110xxx
00176         static const unsigned char _lead3_mask = 0x07; //00000111
00177         static const unsigned char _lead4 = 0xF8;      //111110xx
00178         static const unsigned char _lead4_mask = 0x03; //00000011
00179         static const unsigned char _lead5 = 0xFC;      //1111110x
00180         static const unsigned char _lead5_mask = 0x01; //00000001
00181         static const unsigned char _cont = 0x80;       //10xxxxxx
00182         static const unsigned char _cont_mask = 0x3F;  //00111111
00183 
00184     public:
00186         typedef size_t size_type;
00188         static const size_type npos = static_cast<size_type>(~0);
00189 
00191         typedef uint32 unicode_char;
00192 
00194         typedef uint16 code_point;
00195 
00197         typedef code_point value_type;
00198 
00199         typedef std::basic_string<code_point> dstring; // data string
00200 
00202         typedef std::basic_string<unicode_char> utf32string;
00203 
00205     class MYGUI_EXPORT invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */
00206         public:
00208             explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) {
00209                 /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */
00210             }
00211         };
00212 
00213         //#########################################################################
00215     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 */
00216             friend class UString;
00217         protected:
00218             _base_iterator();
00219 
00220             void _seekFwd( size_type c );
00221             void _seekRev( size_type c );
00222             void _become( const _base_iterator& i );
00223             bool _test_begin() const;
00224             bool _test_end() const;
00225             size_type _get_index() const;
00226             void _jump_to( size_type index );
00227 
00228             unicode_char _getCharacter() const;
00229             int _setCharacter( unicode_char uc );
00230 
00231             void _moveNext();
00232             void _movePrev();
00233 
00234             dstring::iterator mIter;
00235             UString* mString;
00236         };
00237 
00238         //#########################################################################
00239         // FORWARD ITERATORS
00240         //#########################################################################
00241         class _const_fwd_iterator; // forward declaration
00242 
00244     class MYGUI_EXPORT _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00245             friend class _const_fwd_iterator;
00246         public:
00247             _fwd_iterator();
00248             _fwd_iterator( const _fwd_iterator& i );
00249 
00251             _fwd_iterator& operator++();
00253             _fwd_iterator operator++( int );
00254 
00256             _fwd_iterator& operator--();
00258             _fwd_iterator operator--( int );
00259 
00261             _fwd_iterator operator+( difference_type n );
00263             _fwd_iterator operator-( difference_type n );
00264 
00266             _fwd_iterator& operator+=( difference_type n );
00268             _fwd_iterator& operator-=( difference_type n );
00269 
00271             value_type& operator*() const;
00272 
00274             value_type& operator[]( difference_type n ) const;
00275 
00277             _fwd_iterator& moveNext();
00279             _fwd_iterator& movePrev();
00281             unicode_char getCharacter() const;
00283             int setCharacter( unicode_char uc );
00284         };
00285 
00286 
00287 
00288         //#########################################################################
00290     class MYGUI_EXPORT _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00291         public:
00292             _const_fwd_iterator();
00293             _const_fwd_iterator( const _const_fwd_iterator& i );
00294             _const_fwd_iterator( const _fwd_iterator& i );
00295 
00297             _const_fwd_iterator& operator++();
00299             _const_fwd_iterator operator++( int );
00300 
00302             _const_fwd_iterator& operator--();
00304             _const_fwd_iterator operator--( int );
00305 
00307             _const_fwd_iterator operator+( difference_type n );
00309             _const_fwd_iterator operator-( difference_type n );
00310 
00312             _const_fwd_iterator& operator+=( difference_type n );
00314             _const_fwd_iterator& operator-=( difference_type n );
00315 
00317             const value_type& operator*() const;
00318 
00320             const value_type& operator[]( difference_type n ) const;
00321 
00323             _const_fwd_iterator& moveNext();
00325             _const_fwd_iterator& movePrev();
00327             unicode_char getCharacter() const;
00328 
00330             friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00332             friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00334             friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00336             friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00338             friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00340             friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00342             friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
00343 
00344         };
00345 
00346         //#########################################################################
00347         // REVERSE ITERATORS
00348         //#########################################################################
00349         class _const_rev_iterator; // forward declaration
00351     class MYGUI_EXPORT _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00352             friend class _const_rev_iterator;
00353         public:
00354             _rev_iterator();
00355             _rev_iterator( const _rev_iterator& i );
00356 
00358             _rev_iterator& operator++();
00360             _rev_iterator operator++( int );
00361 
00363             _rev_iterator& operator--();
00365             _rev_iterator operator--( int );
00366 
00368             _rev_iterator operator+( difference_type n );
00370             _rev_iterator operator-( difference_type n );
00371 
00373             _rev_iterator& operator+=( difference_type n );
00375             _rev_iterator& operator-=( difference_type n );
00376 
00378             value_type& operator*() const;
00379 
00381             value_type& operator[]( difference_type n ) const;
00382         };
00383         //#########################################################################
00385     class MYGUI_EXPORT _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
00386         public:
00387             _const_rev_iterator();
00388             _const_rev_iterator( const _const_rev_iterator& i );
00389             _const_rev_iterator( const _rev_iterator& i );
00391             _const_rev_iterator& operator++();
00393             _const_rev_iterator operator++( int );
00394 
00396             _const_rev_iterator& operator--();
00398             _const_rev_iterator operator--( int );
00399 
00401             _const_rev_iterator operator+( difference_type n );
00403             _const_rev_iterator operator-( difference_type n );
00404 
00406             _const_rev_iterator& operator+=( difference_type n );
00408             _const_rev_iterator& operator-=( difference_type n );
00409 
00411             const value_type& operator*() const;
00412 
00414             const value_type& operator[]( difference_type n ) const;
00415 
00417             friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right );
00419             friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right );
00421             friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00423             friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right );
00425             friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00427             friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right );
00429             friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right );
00430         };
00431         //#########################################################################
00432 
00433         typedef _fwd_iterator iterator;                     
00434         typedef _rev_iterator reverse_iterator;             
00435         typedef _const_fwd_iterator const_iterator;         
00436         typedef _const_rev_iterator const_reverse_iterator; 
00437 
00438 
00440 
00441 
00442         UString();
00444         UString( const UString& copy );
00446         UString( size_type length, const code_point& ch );
00448         UString( const code_point* str );
00450         UString( const code_point* str, size_type length );
00452         UString( const UString& str, size_type index, size_type length );
00453 #if MYGUI_IS_NATIVE_WCHAR_T
00454 
00455         UString( const wchar_t* w_str );
00457         UString( const wchar_t* w_str, size_type length );
00458 #endif
00459 
00460         UString( const std::wstring& wstr );
00462         UString( const char* c_str );
00464         UString( const char* c_str, size_type length );
00466         UString( const std::string& str );
00467 
00469         ~UString();
00471 
00473 
00475 
00476 
00477         size_type size() const;
00479         size_type length() const;
00481 
00482         size_type length_Characters() const;
00484         size_type max_size() const;
00486         void reserve( size_type size );
00488         void resize( size_type num, const code_point& val = 0 );
00490         void swap( UString& from );
00492         bool empty() const;
00494         const code_point* c_str() const;
00496         const code_point* data() const;
00498         size_type capacity() const;
00500         void clear();
00502 
00503         UString substr( size_type index, size_type num = npos ) const;
00505         void push_back( unicode_char val );
00506 #if MYGUI_IS_NATIVE_WCHAR_T
00507 
00508         void push_back( wchar_t val );
00509 #endif
00510 
00511 
00513         void push_back( code_point val );
00515 
00516         void push_back( char val );
00518         bool inString( unicode_char ch ) const;
00520 
00522 
00524 
00525 
00526         const std::string& asUTF8() const;
00528         const char* asUTF8_c_str() const;
00530         const utf32string& asUTF32() const;
00532         const unicode_char* asUTF32_c_str() const;
00534         const std::wstring& asWStr() const;
00536         const wchar_t* asWStr_c_str() const;
00538 
00540 
00542 
00543 
00544         code_point& at( size_type loc );
00546         const code_point& at( size_type loc ) const;
00548 
00552         unicode_char getChar( size_type loc ) const;
00554 
00562         int setChar( size_type loc, unicode_char ch );
00564 
00566 
00568 
00569 
00570         iterator begin();
00572         const_iterator begin() const;
00574         iterator end();
00576         const_iterator end() const;
00578         reverse_iterator rbegin();
00580         const_reverse_iterator rbegin() const;
00582         reverse_iterator rend();
00584         const_reverse_iterator rend() const;
00586 
00588 
00590 
00591 
00592         UString& assign( iterator start, iterator end );
00594         UString& assign( const UString& str );
00596         UString& assign( const code_point* str );
00598         UString& assign( const code_point* str, size_type num );
00600         UString& assign( const UString& str, size_type index, size_type len );
00602         UString& assign( size_type num, const code_point& ch );
00604         UString& assign( const std::wstring& wstr );
00605 #if MYGUI_IS_NATIVE_WCHAR_T
00606 
00607         UString& assign( const wchar_t* w_str );
00609         UString& assign( const wchar_t* w_str, size_type num );
00610 #endif
00611 
00612         UString& assign( const std::string& str );
00614         UString& assign( const char* c_str );
00616         UString& assign( const char* c_str, size_type num );
00618 
00620 
00622 
00623 
00624         UString& append( const UString& str );
00626         UString& append( const code_point* str );
00628         UString& append( const UString& str, size_type index, size_type len );
00630         UString& append( const code_point* str, size_type num );
00632         UString& append( size_type num, code_point ch );
00634         UString& append( iterator start, iterator end );
00635 #if MYGUI_IS_NATIVE_WCHAR_T
00636 
00637         UString& append( const wchar_t* w_str, size_type num );
00639         UString& append( size_type num, wchar_t ch );
00640 #endif
00641 
00642         UString& append( const char* c_str, size_type num );
00644         UString& append( size_type num, char ch );
00646         UString& append( size_type num, unicode_char ch );
00648 
00650 
00652 
00653 
00654         iterator insert( iterator i, const code_point& ch );
00656         UString& insert( size_type index, const UString& str );
00658         UString& insert( size_type index, const code_point* str ) {
00659             mData.insert( index, str );
00660             return *this;
00661         }
00663         UString& insert( size_type index1, const UString& str, size_type index2, size_type num );
00665         void insert( iterator i, iterator start, iterator end );
00667         UString& insert( size_type index, const code_point* str, size_type num );
00668 #if MYGUI_IS_NATIVE_WCHAR_T
00669 
00670         UString& insert( size_type index, const wchar_t* w_str, size_type num );
00671 #endif
00672 
00673         UString& insert( size_type index, const char* c_str, size_type num );
00675         UString& insert( size_type index, size_type num, code_point ch );
00676 #if MYGUI_IS_NATIVE_WCHAR_T
00677 
00678         UString& insert( size_type index, size_type num, wchar_t ch );
00679 #endif
00680 
00681         UString& insert( size_type index, size_type num, char ch );
00683         UString& insert( size_type index, size_type num, unicode_char ch );
00685         void insert( iterator i, size_type num, const code_point& ch );
00686 #if MYGUI_IS_NATIVE_WCHAR_T
00687 
00688         void insert( iterator i, size_type num, const wchar_t& ch );
00689 #endif
00690 
00691         void insert( iterator i, size_type num, const char& ch );
00693         void insert( iterator i, size_type num, const unicode_char& ch );
00695 
00697 
00699 
00700 
00701         iterator erase( iterator loc );
00703         iterator erase( iterator start, iterator end );
00705         UString& erase( size_type index = 0, size_type num = npos );
00707 
00709 
00711 
00712 
00713         UString& replace( size_type index1, size_type num1, const UString& str );
00715         UString& replace( size_type index1, size_type num1, const UString& str, size_type num2 );
00717         UString& replace( size_type index1, size_type num1, const UString& str, size_type index2, size_type num2 );
00719         UString& replace( iterator start, iterator end, const UString& str, size_type num = npos );
00721         UString& replace( size_type index, size_type num1, size_type num2, code_point ch );
00723         UString& replace( iterator start, iterator end, size_type num, code_point ch );
00725 
00727 
00729 
00730 
00731         int compare( const UString& str ) const;
00733         int compare( const code_point* str ) const;
00735         int compare( size_type index, size_type length, const UString& str ) const;
00737         int compare( size_type index, size_type length, const UString& str, size_type index2, size_type length2 ) const;
00739         int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const;
00740 #if MYGUI_IS_NATIVE_WCHAR_T
00741 
00742         int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const;
00743 #endif
00744 
00745         int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const;
00747 
00749 
00751 
00752 
00753 
00754         size_type find( const UString& str, size_type index = 0 ) const;
00756 
00757         size_type find( const code_point* cp_str, size_type index, size_type length ) const;
00759 
00760         size_type find( const char* c_str, size_type index, size_type length ) const;
00761 #if MYGUI_IS_NATIVE_WCHAR_T
00762 
00763 
00764         size_type find( const wchar_t* w_str, size_type index, size_type length ) const;
00765 #endif
00766 
00767 
00768         size_type find( char ch, size_type index = 0 ) const;
00770 
00771         size_type find( code_point ch, size_type index = 0 ) const;
00772 #if MYGUI_IS_NATIVE_WCHAR_T
00773 
00774 
00775         size_type find( wchar_t ch, size_type index = 0 ) const;
00776 #endif
00777 
00778 
00779         size_type find( unicode_char ch, size_type index = 0 ) const;
00780 
00782         size_type rfind( const UString& str, size_type index = 0 ) const;
00784         size_type rfind( const code_point* cp_str, size_type index, size_type num ) const;
00786         size_type rfind( const char* c_str, size_type index, size_type num ) const;
00787 #if MYGUI_IS_NATIVE_WCHAR_T
00788 
00789         size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const;
00790 #endif
00791 
00792         size_type rfind( char ch, size_type index = 0 ) const;
00794         size_type rfind( code_point ch, size_type index ) const;
00795 #if MYGUI_IS_NATIVE_WCHAR_T
00796 
00797         size_type rfind( wchar_t ch, size_type index = 0 ) const;
00798 #endif
00799 
00800         size_type rfind( unicode_char ch, size_type index = 0 ) const;
00802 
00804 
00806 
00807 
00808         size_type find_first_of( const UString &str, size_type index = 0, size_type num = npos ) const;
00810         size_type find_first_of( code_point ch, size_type index = 0 ) const;
00812         size_type find_first_of( char ch, size_type index = 0 ) const;
00813 #if MYGUI_IS_NATIVE_WCHAR_T
00814 
00815         size_type find_first_of( wchar_t ch, size_type index = 0 ) const;
00816 #endif
00817 
00818         size_type find_first_of( unicode_char ch, size_type index = 0 ) const;
00819 
00821         size_type find_first_not_of( const UString& str, size_type index = 0, size_type num = npos ) const;
00823         size_type find_first_not_of( code_point ch, size_type index = 0 ) const;
00825         size_type find_first_not_of( char ch, size_type index = 0 ) const;
00826 #if MYGUI_IS_NATIVE_WCHAR_T
00827 
00828         size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const;
00829 #endif
00830 
00831         size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const;
00832 
00834         size_type find_last_of( const UString& str, size_type index = npos, size_type num = npos ) const;
00836         size_type find_last_of( code_point ch, size_type index = npos ) const;
00838         size_type find_last_of( char ch, size_type index = npos ) const {
00839             return find_last_of( static_cast<code_point>( ch ), index );
00840         }
00841 #if MYGUI_IS_NATIVE_WCHAR_T
00842 
00843         size_type find_last_of( wchar_t ch, size_type index = npos ) const;
00844 #endif
00845 
00846         size_type find_last_of( unicode_char ch, size_type index = npos ) const;
00847 
00849         size_type find_last_not_of( const UString& str, size_type index = npos, size_type num = npos ) const;
00851         size_type find_last_not_of( code_point ch, size_type index = npos ) const;
00853         size_type find_last_not_of( char ch, size_type index = npos ) const;
00854 #if MYGUI_IS_NATIVE_WCHAR_T
00855 
00856         size_type find_last_not_of( wchar_t ch, size_type index = npos ) const;
00857 #endif
00858 
00859         size_type find_last_not_of( unicode_char ch, size_type index = npos ) const;
00861 
00863 
00865 
00866 
00867         bool operator<( const UString& right ) const;
00869         bool operator<=( const UString& right ) const;
00871         bool operator>( const UString& right ) const;
00873         bool operator>=( const UString& right ) const;
00875         bool operator==( const UString& right ) const;
00877         bool operator!=( const UString& right ) const;
00879         UString& operator=( const UString& s );
00881         UString& operator=( code_point ch );
00883         UString& operator=( char ch );
00884 #if MYGUI_IS_NATIVE_WCHAR_T
00885 
00886         UString& operator=( wchar_t ch );
00887 #endif
00888 
00889         UString& operator=( unicode_char ch );
00891         code_point& operator[]( size_type index );
00893         const code_point& operator[]( size_type index ) const;
00895 
00897 
00899 
00900 
00901         operator std::string() const;
00903         operator std::wstring() const;
00905 
00907 
00909 
00910 
00911         static bool _utf16_independent_char( code_point cp );
00913         static bool _utf16_surrogate_lead( code_point cp );
00915         static bool _utf16_surrogate_follow( code_point cp );
00917         static size_t _utf16_char_length( code_point cp );
00919         static size_t _utf16_char_length( unicode_char uc );
00921 
00925         static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc );
00927 
00932         static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] );
00934 
00936 
00938 
00939 
00940         static bool _utf8_start_char( unsigned char cp );
00942         static size_t _utf8_char_length( unsigned char cp );
00944         static size_t _utf8_char_length( unicode_char uc );
00945 
00947         static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc );
00949         static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] );
00950 
00952         static size_type _verifyUTF8( const unsigned char* c_str );
00954         static size_type _verifyUTF8( const std::string& str );
00956 
00957     private:
00958         //template<class ITER_TYPE> friend class _iterator;
00959         dstring mData;
00960 
00962         enum BufferType {
00963             bt_none,
00964             bt_string,
00965             bt_wstring,
00966             bt_utf32string
00967         };
00968 
00970         void _init();
00971 
00973         // Scratch buffer
00975         void _cleanBuffer() const;
00976 
00978         void _getBufferStr() const;
00980         void _getBufferWStr() const;
00982         void _getBufferUTF32Str() const;
00983 
00984         void _load_buffer_UTF8() const;
00985         void _load_buffer_WStr() const;
00986         void _load_buffer_UTF32() const;
00987 
00988         mutable BufferType m_bufferType; // identifies the data type held in m_buffer
00989         mutable size_t m_bufferSize; // size of the CString buffer
00990 
00991         // multi-purpose buffer used everywhere we need a throw-away buffer
00992         union {
00993             mutable void* mVoidBuffer;
00994             mutable std::string* mStrBuffer;
00995             mutable std::wstring* mWStrBuffer;
00996             mutable utf32string* mUTF32StrBuffer;
00997         }
00998         m_buffer;
00999     };
01000 
01002     inline UString operator+( const UString& s1, const UString& s2 ) {
01003         return UString( s1 ).append( s2 );
01004     }
01006     inline UString operator+( const UString& s1, UString::code_point c ) {
01007         return UString( s1 ).append( 1, c );
01008     }
01010     inline UString operator+( const UString& s1, UString::unicode_char c ) {
01011         return UString( s1 ).append( 1, c );
01012     }
01014     inline UString operator+( const UString& s1, char c ) {
01015         return UString( s1 ).append( 1, c );
01016     }
01017 #if MYGUI_IS_NATIVE_WCHAR_T
01018 
01019     inline UString operator+( const UString& s1, wchar_t c ) {
01020         return UString( s1 ).append( 1, c );
01021     }
01022 #endif
01023 
01024     inline UString operator+( UString::code_point c, const UString& s2 ) {
01025         return UString().append( 1, c ).append( s2 );
01026     }
01028     inline UString operator+( UString::unicode_char c, const UString& s2 ) {
01029         return UString().append( 1, c ).append( s2 );
01030     }
01032     inline UString operator+( char c, const UString& s2 ) {
01033         return UString().append( 1, c ).append( s2 );
01034     }
01035 #if MYGUI_IS_NATIVE_WCHAR_T
01036 
01037     inline UString operator+( wchar_t c, const UString& s2 ) {
01038         return UString().append( 1, c ).append( s2 );
01039     }
01040 #endif
01041 
01042     // (const) forward iterator common operators
01043     inline UString::size_type operator-( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01044         return ( left.mIter - right.mIter );
01045     }
01046     inline bool operator==( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01047         return left.mIter == right.mIter;
01048     }
01049     inline bool operator!=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01050         return left.mIter != right.mIter;
01051     }
01052     inline bool operator<( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01053         return left.mIter < right.mIter;
01054     }
01055     inline bool operator<=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01056         return left.mIter <= right.mIter;
01057     }
01058     inline bool operator>( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01059         return left.mIter > right.mIter;
01060     }
01061     inline bool operator>=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
01062         return left.mIter >= right.mIter;
01063     }
01064 
01065     // (const) reverse iterator common operators
01066     // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator
01067     inline UString::size_type operator-( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01068         return ( right.mIter - left.mIter );
01069     }
01070     inline bool operator==( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01071         return left.mIter == right.mIter;
01072     }
01073     inline bool operator!=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01074         return left.mIter != right.mIter;
01075     }
01076     inline bool operator<( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01077         return right.mIter < left.mIter;
01078     }
01079     inline bool operator<=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01080         return right.mIter <= left.mIter;
01081     }
01082     inline bool operator>( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01083         return right.mIter > left.mIter;
01084     }
01085     inline bool operator>=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
01086         return right.mIter >= left.mIter;
01087     }
01088 
01090     inline std::ostream& operator << ( std::ostream& os, const UString& s ) {
01091         return os << s.asUTF8();
01092     }
01093 
01095     inline std::wostream& operator << ( std::wostream& os, const UString& s ) {
01096         return os << s.asWStr();
01097     }
01098 
01099 } // namespace MyGUI
01100 
01101 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
01102 #   pragma warning (default : 4275)
01103 #endif
01104 
01105 #endif  // __MYGUI_U_STRING_H__