MyGUI  3.2.1
MyGUI_UString.h
Go to the documentation of this file.
1 // Modified from OpenGUI under lenient license
2 // Original copyright details and licensing below:
3 // OpenGUI (http://opengui.sourceforge.net)
4 // This source code is released under the BSD License
5 
6 // Permission is given to the MyGUI project to use the contents of file within its
7 // source and binary applications, as well as any derivative works, in accordance
8 // with the terms of any license under which MyGUI is or will be distributed.
9 //
10 // MyGUI may relicense its copy of this file, as well as any OpenGUI released updates
11 // to this file, under any terms that it deems fit, and is not required to maintain
12 // the original BSD licensing terms of this file, however OpenGUI retains the right
13 // to present its copy of this file under the terms of any license under which
14 // OpenGUI is distributed.
15 //
16 // MyGUI is not required to release to OpenGUI any future changes that it makes to
17 // this file, and understands and agrees that any such changes that are released
18 // back to OpenGUI will become available under the terms of any license under which
19 // OpenGUI is distributed.
20 //
21 // For brevity, this permission text may be removed from this file if desired.
22 // The original record kept within the SourceForge (http://sourceforge.net/) tracker
23 // is sufficient.
24 //
25 // - Eric Shorkey (zero/zeroskill) <opengui@rightbracket.com> [January 20th, 2007]
26 
27 #ifndef __MYGUI_U_STRING_H__
28 #define __MYGUI_U_STRING_H__
29 
30 
31 #include "MyGUI_Prerequest.h"
32 #include "MyGUI_Types.h"
33 
34 // these are explained later
35 #include <iterator>
36 #include <string>
37 #include <stdexcept>
38 
39 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
40 // disable: warning C4275: non dll-interface class '***' used as base for dll-interface clas '***'
41 # pragma warning (push)
42 # pragma warning (disable : 4275)
43 #endif
44 
45 // Workaround for VC7:
46 // when build with /MD or /MDd, VC7 have both std::basic_string<unsigned short> and
47 // basic_string<__wchar_t> instantiated in msvcprt[d].lib/MSVCP71[D].dll, but the header
48 // files tells compiler that only one of them is over there (based on /Zc:wchar_t compile
49 // option). And since this file used both of them, causing compiler instantiating another
50 // one in user object code, which lead to duplicate symbols with msvcprt.lib/MSVCP71[D].dll.
51 //
52 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && (1300 <= MYGUI_COMP_VER && MYGUI_COMP_VER <= 1310)
53 
54 # if defined(_DLL_CPPLIB)
55 
56 namespace std
57 {
58  template class _CRTIMP2 basic_string<unsigned short, char_traits<unsigned short>,
59  allocator<unsigned short> >;
60 
61  template class _CRTIMP2 basic_string<__wchar_t, char_traits<__wchar_t>,
62  allocator<__wchar_t> >;
63 }
64 
65 # endif // defined(_DLL_CPPLIB)
66 
67 #endif // MYGUI_COMPILER == MYGUI_COMPILER_MSVC && MYGUI_COMP_VER == 1300
68 
69 
70 namespace MyGUI
71 {
72 
73  /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS
74  =NOTICE=
75  This class is not a complete Unicode solution. It purposefully does not
76  provide certain functionality, such as proper lexical sorting for
77  Unicode values. It does provide comparison operators for the sole purpose
78  of using UString as an index with std::map and other operator< sorted
79  containers, but it should NOT be relied upon for meaningful lexical
80  operations, such as alphabetical sorts. If you need this type of
81  functionality, look into using ICU instead (http://icu.sourceforge.net/).
82 
83  =REQUIREMENTS=
84  There are a few requirements for proper operation. They are fairly small,
85  and shouldn't restrict usage on any reasonable target.
86  * Compiler must support unsigned 16-bit integer types
87  * Compiler must support signed 32-bit integer types
88  * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such
89  using the WCHAR_UTF16 macro as outlined below.
90  * You must include <iterator>, <string>, and <wchar>. Probably more, but
91  these are the most obvious.
92 
93  =REQUIRED PREPROCESSOR MACROS=
94  This class requires two preprocessor macros to be defined in order to
95  work as advertised.
96  INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int)
97  UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short)
98 
99  Additionally, a third macro should be defined to control the evaluation of wchar_t:
100  WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points,
101  such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit
102  integer representing UTF-32 code points.
103  */
104 
105  // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS
106 #ifdef __STDC_ISO_10646__
107 // for any compiler that provides this, wchar_t is guaranteed to hold any Unicode value with a single code point (32-bit or larger)
108 // so we can safely skip the rest of the testing
109 #else // #ifdef __STDC_ISO_10646__
110 #if defined( __WIN32__ ) || defined( _WIN32 )
111 #define WCHAR_UTF16 // All currently known Windows platforms utilize UTF-16 encoding in wchar_t
112 #else // #if defined( __WIN32__ ) || defined( _WIN32 )
113 #if MYGUI_COMPILER != MYGUI_COMPILER_GCCE
114 #if WCHAR_MAX <= 0xFFFF // this is a last resort fall back test; WCHAR_MAX is defined in <wchar.h>
115 #define WCHAR_UTF16 // best we can tell, wchar_t is not larger than 16-bit
116 #endif // #if WCHAR_MAX <= 0xFFFF
117 #endif
118 #endif // #if defined( __WIN32__ ) || defined( _WIN32 )
119 #endif // #ifdef __STDC_ISO_10646__
120 
121 
122 // MYGUI_IS_NATIVE_WCHAR_T means that wchar_t isn't a typedef of
123 // uint16_t or uint32_t.
124 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
125 
126 // Don't define wchar_t related functions since it'll duplicate
127 // with UString::code_point related functions when compile
128 // without /Zc:wchar_t, because in this case both of them are
129 // a typedef of uint16_t.
130 # if defined(_NATIVE_WCHAR_T_DEFINED)
131 # define MYGUI_IS_NATIVE_WCHAR_T 1
132 # else
133 # define MYGUI_IS_NATIVE_WCHAR_T 0
134 # endif
135 #elif MYGUI_PLATFORM == MYGUI_PLATFORM_SYMBIAN
136 # define MYGUI_IS_NATIVE_WCHAR_T 0
137 #else // MYGUI_COMPILER != MYGUI_COMPILER_MSVC
138 
139 // Assumed wchar_t is natively for other compilers
140 # define MYGUI_IS_NATIVE_WCHAR_T 1
141 
142 #endif // MYGUI_COMPILER == MYGUI_COMPILER_MSVC
143 
145 
171  // constants used in UTF-8 conversions
172  static const unsigned char _lead1 = 0xC0; //110xxxxx
173  static const unsigned char _lead1_mask = 0x1F; //00011111
174  static const unsigned char _lead2 = 0xE0; //1110xxxx
175  static const unsigned char _lead2_mask = 0x0F; //00001111
176  static const unsigned char _lead3 = 0xF0; //11110xxx
177  static const unsigned char _lead3_mask = 0x07; //00000111
178  static const unsigned char _lead4 = 0xF8; //111110xx
179  static const unsigned char _lead4_mask = 0x03; //00000011
180  static const unsigned char _lead5 = 0xFC; //1111110x
181  static const unsigned char _lead5_mask = 0x01; //00000001
182  static const unsigned char _cont = 0x80; //10xxxxxx
183  static const unsigned char _cont_mask = 0x3F; //00111111
184 
185  public:
187  typedef size_t size_type;
189  static const size_type npos = static_cast<size_type>(~0);
190 
193 
196 
199 
200  typedef std::basic_string<code_point> dstring; // data string
201 
203  typedef std::basic_string<unicode_char> utf32string;
204 
206  class MYGUI_EXPORT invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */
207  public:
209  explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) {
210  /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */
211  }
212  };
213 
214  //#########################################################################
216  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 */
217  friend class UString;
218  protected:
219  _base_iterator();
220 
221  void _seekFwd( size_type c );
222  void _seekRev( size_type c );
223  void _become( const _base_iterator& i );
224  bool _test_begin() const;
225  bool _test_end() const;
226  size_type _get_index() const;
227  void _jump_to( size_type index );
228 
229  unicode_char _getCharacter() const;
230  int _setCharacter( unicode_char uc );
231 
232  void _moveNext();
233  void _movePrev();
234 
235  dstring::iterator mIter;
237  };
238 
239  //#########################################################################
240  // FORWARD ITERATORS
241  //#########################################################################
242  class _const_fwd_iterator; // forward declaration
243 
245  class MYGUI_EXPORT _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
246  friend class _const_fwd_iterator;
247  public:
248  _fwd_iterator();
249  _fwd_iterator( const _fwd_iterator& i );
250 
252  _fwd_iterator& operator++();
254  _fwd_iterator operator++( int );
255 
257  _fwd_iterator& operator--();
259  _fwd_iterator operator--( int );
260 
262  _fwd_iterator operator+( difference_type n );
264  _fwd_iterator operator-( difference_type n );
265 
267  _fwd_iterator& operator+=( difference_type n );
269  _fwd_iterator& operator-=( difference_type n );
270 
272  value_type& operator*() const;
273 
275  value_type& operator[]( difference_type n ) const;
276 
278  _fwd_iterator& moveNext();
280  _fwd_iterator& movePrev();
282  unicode_char getCharacter() const;
284  int setCharacter( unicode_char uc );
285  };
286 
287 
288 
289  //#########################################################################
291  class MYGUI_EXPORT _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
292  public:
296 
298  _const_fwd_iterator& operator++();
300  _const_fwd_iterator operator++( int );
301 
303  _const_fwd_iterator& operator--();
305  _const_fwd_iterator operator--( int );
306 
308  _const_fwd_iterator operator+( difference_type n );
310  _const_fwd_iterator operator-( difference_type n );
311 
313  _const_fwd_iterator& operator+=( difference_type n );
315  _const_fwd_iterator& operator-=( difference_type n );
316 
318  const value_type& operator*() const;
319 
321  const value_type& operator[]( difference_type n ) const;
322 
324  _const_fwd_iterator& moveNext();
326  _const_fwd_iterator& movePrev();
328  unicode_char getCharacter() const;
329 
331  friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
333  friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
335  friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
337  friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
339  friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
341  friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
343  friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
344 
345  };
346 
347  //#########################################################################
348  // REVERSE ITERATORS
349  //#########################################################################
350  class _const_rev_iterator; // forward declaration
352  class MYGUI_EXPORT _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
353  friend class _const_rev_iterator;
354  public:
355  _rev_iterator();
356  _rev_iterator( const _rev_iterator& i );
357 
359  _rev_iterator& operator++();
361  _rev_iterator operator++( int );
362 
364  _rev_iterator& operator--();
366  _rev_iterator operator--( int );
367 
369  _rev_iterator operator+( difference_type n );
371  _rev_iterator operator-( difference_type n );
372 
374  _rev_iterator& operator+=( difference_type n );
376  _rev_iterator& operator-=( difference_type n );
377 
379  value_type& operator*() const;
380 
382  value_type& operator[]( difference_type n ) const;
383  };
384  //#########################################################################
386  class MYGUI_EXPORT _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
387  public:
392  _const_rev_iterator& operator++();
394  _const_rev_iterator operator++( int );
395 
397  _const_rev_iterator& operator--();
399  _const_rev_iterator operator--( int );
400 
402  _const_rev_iterator operator+( difference_type n );
404  _const_rev_iterator operator-( difference_type n );
405 
407  _const_rev_iterator& operator+=( difference_type n );
409  _const_rev_iterator& operator-=( difference_type n );
410 
412  const value_type& operator*() const;
413 
415  const value_type& operator[]( difference_type n ) const;
416 
418  friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right );
420  friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right );
422  friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right );
424  friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right );
426  friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right );
428  friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right );
430  friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right );
431  };
432  //#########################################################################
433 
438 
439 
441 
442 
443  UString();
445  UString( const UString& copy );
447  UString( size_type length, const code_point& ch );
449  UString( const code_point* str );
451  UString( const code_point* str, size_type length );
453  UString( const UString& str, size_type index, size_type length );
454 #if MYGUI_IS_NATIVE_WCHAR_T
455 
456  UString( const wchar_t* w_str );
458  UString( const wchar_t* w_str, size_type length );
459 #endif
460 
461  UString( const std::wstring& wstr );
463  UString( const char* c_str );
465  UString( const char* c_str, size_type length );
467  UString( const std::string& str );
468 
470  ~UString();
472 
474 
476 
477 
478  size_type size() const;
480  size_type length() const;
482 
483  size_type length_Characters() const;
485  size_type max_size() const;
487  void reserve( size_type size );
489  void resize( size_type num, const code_point& val = 0 );
491  void swap( UString& from );
493  bool empty() const;
495  const code_point* c_str() const;
497  const code_point* data() const;
499  size_type capacity() const;
501  void clear();
503 
504  UString substr( size_type index, size_type num = npos ) const;
506  void push_back( unicode_char val );
507 #if MYGUI_IS_NATIVE_WCHAR_T
508 
509  void push_back( wchar_t val );
510 #endif
511 
512 
514  void push_back( code_point val );
516 
517  void push_back( char val );
519  bool inString( unicode_char ch ) const;
521 
523 
525 
526 
527  const std::string& asUTF8() const;
529  const char* asUTF8_c_str() const;
531  const utf32string& asUTF32() const;
533  const unicode_char* asUTF32_c_str() const;
535  const std::wstring& asWStr() const;
537  const wchar_t* asWStr_c_str() const;
539 
541 
543 
544 
545  code_point& at( size_type loc );
547  const code_point& at( size_type loc ) const;
549 
553  unicode_char getChar( size_type loc ) const;
555 
563  int setChar( size_type loc, unicode_char ch );
565 
567 
569 
570 
571  iterator begin();
573  const_iterator begin() const;
575  iterator end();
577  const_iterator end() const;
579  reverse_iterator rbegin();
581  const_reverse_iterator rbegin() const;
583  reverse_iterator rend();
585  const_reverse_iterator rend() const;
587 
589 
591 
592 
593  UString& assign( iterator start, iterator end );
595  UString& assign( const UString& str );
597  UString& assign( const code_point* str );
599  UString& assign( const code_point* str, size_type num );
601  UString& assign( const UString& str, size_type index, size_type len );
603  UString& assign( size_type num, const code_point& ch );
605  UString& assign( const std::wstring& wstr );
606 #if MYGUI_IS_NATIVE_WCHAR_T
607 
608  UString& assign( const wchar_t* w_str );
610  UString& assign( const wchar_t* w_str, size_type num );
611 #endif
612 
613  UString& assign( const std::string& str );
615  UString& assign( const char* c_str );
617  UString& assign( const char* c_str, size_type num );
619 
621 
623 
624 
625  UString& append( const UString& str );
627  UString& append( const code_point* str );
629  UString& append( const UString& str, size_type index, size_type len );
631  UString& append( const code_point* str, size_type num );
633  UString& append( size_type num, code_point ch );
635  UString& append( iterator start, iterator end );
636 #if MYGUI_IS_NATIVE_WCHAR_T
637 
638  UString& append( const wchar_t* w_str, size_type num );
640  UString& append( size_type num, wchar_t ch );
641 #endif
642 
643  UString& append( const char* c_str, size_type num );
645  UString& append( size_type num, char ch );
647  UString& append( size_type num, unicode_char ch );
649 
651 
653 
654 
655  iterator insert( iterator i, const code_point& ch );
657  UString& insert( size_type index, const UString& str );
659  UString& insert( size_type index, const code_point* str ) {
660  mData.insert( index, str );
661  return *this;
662  }
664  UString& insert( size_type index1, const UString& str, size_type index2, size_type num );
666  void insert( iterator i, iterator start, iterator end );
668  UString& insert( size_type index, const code_point* str, size_type num );
669 #if MYGUI_IS_NATIVE_WCHAR_T
670 
671  UString& insert( size_type index, const wchar_t* w_str, size_type num );
672 #endif
673 
674  UString& insert( size_type index, const char* c_str, size_type num );
676  UString& insert( size_type index, size_type num, code_point ch );
677 #if MYGUI_IS_NATIVE_WCHAR_T
678 
679  UString& insert( size_type index, size_type num, wchar_t ch );
680 #endif
681 
682  UString& insert( size_type index, size_type num, char ch );
684  UString& insert( size_type index, size_type num, unicode_char ch );
686  void insert( iterator i, size_type num, const code_point& ch );
687 #if MYGUI_IS_NATIVE_WCHAR_T
688 
689  void insert( iterator i, size_type num, const wchar_t& ch );
690 #endif
691 
692  void insert( iterator i, size_type num, const char& ch );
694  void insert( iterator i, size_type num, const unicode_char& ch );
696 
698 
700 
701 
702  iterator erase( iterator loc );
704  iterator erase( iterator start, iterator end );
706  UString& erase( size_type index = 0, size_type num = npos );
708 
710 
712 
713 
714  UString& replace( size_type index1, size_type num1, const UString& str );
716  UString& replace( size_type index1, size_type num1, const UString& str, size_type num2 );
718  UString& replace( size_type index1, size_type num1, const UString& str, size_type index2, size_type num2 );
720  UString& replace( iterator start, iterator end, const UString& str, size_type num = npos );
722  UString& replace( size_type index, size_type num1, size_type num2, code_point ch );
724  UString& replace( iterator start, iterator end, size_type num, code_point ch );
726 
728 
730 
731 
732  int compare( const UString& str ) const;
734  int compare( const code_point* str ) const;
736  int compare( size_type index, size_type length, const UString& str ) const;
738  int compare( size_type index, size_type length, const UString& str, size_type index2, size_type length2 ) const;
740  int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const;
741 #if MYGUI_IS_NATIVE_WCHAR_T
742 
743  int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const;
744 #endif
745 
746  int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const;
748 
750 
752 
753 
754 
755  size_type find( const UString& str, size_type index = 0 ) const;
757 
758  size_type find( const code_point* cp_str, size_type index, size_type length ) const;
760 
761  size_type find( const char* c_str, size_type index, size_type length ) const;
762 #if MYGUI_IS_NATIVE_WCHAR_T
763 
764 
765  size_type find( const wchar_t* w_str, size_type index, size_type length ) const;
766 #endif
767 
768 
769  size_type find( char ch, size_type index = 0 ) const;
771 
772  size_type find( code_point ch, size_type index = 0 ) const;
773 #if MYGUI_IS_NATIVE_WCHAR_T
774 
775 
776  size_type find( wchar_t ch, size_type index = 0 ) const;
777 #endif
778 
779 
780  size_type find( unicode_char ch, size_type index = 0 ) const;
781 
783  size_type rfind( const UString& str, size_type index = 0 ) const;
785  size_type rfind( const code_point* cp_str, size_type index, size_type num ) const;
787  size_type rfind( const char* c_str, size_type index, size_type num ) const;
788 #if MYGUI_IS_NATIVE_WCHAR_T
789 
790  size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const;
791 #endif
792 
793  size_type rfind( char ch, size_type index = 0 ) const;
795  size_type rfind( code_point ch, size_type index ) const;
796 #if MYGUI_IS_NATIVE_WCHAR_T
797 
798  size_type rfind( wchar_t ch, size_type index = 0 ) const;
799 #endif
800 
801  size_type rfind( unicode_char ch, size_type index = 0 ) const;
803 
805 
807 
808 
809  size_type find_first_of( const UString &str, size_type index = 0, size_type num = npos ) const;
811  size_type find_first_of( code_point ch, size_type index = 0 ) const;
813  size_type find_first_of( char ch, size_type index = 0 ) const;
814 #if MYGUI_IS_NATIVE_WCHAR_T
815 
816  size_type find_first_of( wchar_t ch, size_type index = 0 ) const;
817 #endif
818 
819  size_type find_first_of( unicode_char ch, size_type index = 0 ) const;
820 
822  size_type find_first_not_of( const UString& str, size_type index = 0, size_type num = npos ) const;
824  size_type find_first_not_of( code_point ch, size_type index = 0 ) const;
826  size_type find_first_not_of( char ch, size_type index = 0 ) const;
827 #if MYGUI_IS_NATIVE_WCHAR_T
828 
829  size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const;
830 #endif
831 
832  size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const;
833 
835  size_type find_last_of( const UString& str, size_type index = npos, size_type num = npos ) const;
837  size_type find_last_of( code_point ch, size_type index = npos ) const;
839  size_type find_last_of( char ch, size_type index = npos ) const {
840  return find_last_of( static_cast<code_point>( ch ), index );
841  }
842 #if MYGUI_IS_NATIVE_WCHAR_T
843 
844  size_type find_last_of( wchar_t ch, size_type index = npos ) const;
845 #endif
846 
847  size_type find_last_of( unicode_char ch, size_type index = npos ) const;
848 
850  size_type find_last_not_of( const UString& str, size_type index = npos, size_type num = npos ) const;
852  size_type find_last_not_of( code_point ch, size_type index = npos ) const;
854  size_type find_last_not_of( char ch, size_type index = npos ) const;
855 #if MYGUI_IS_NATIVE_WCHAR_T
856 
857  size_type find_last_not_of( wchar_t ch, size_type index = npos ) const;
858 #endif
859 
860  size_type find_last_not_of( unicode_char ch, size_type index = npos ) const;
862 
864 
866 
867 
868  bool operator<( const UString& right ) const;
870  bool operator<=( const UString& right ) const;
872  bool operator>( const UString& right ) const;
874  bool operator>=( const UString& right ) const;
876  bool operator==( const UString& right ) const;
878  bool operator!=( const UString& right ) const;
880  UString& operator=( const UString& s );
882  UString& operator=( code_point ch );
884  UString& operator=( char ch );
885 #if MYGUI_IS_NATIVE_WCHAR_T
886 
887  UString& operator=( wchar_t ch );
888 #endif
889 
890  UString& operator=( unicode_char ch );
892  code_point& operator[]( size_type index );
894  const code_point& operator[]( size_type index ) const;
896 
898 
900 
901 
902  operator std::string() const;
904  operator std::wstring() const;
906 
908 
910 
911 
912  static bool _utf16_independent_char( code_point cp );
914  static bool _utf16_surrogate_lead( code_point cp );
916  static bool _utf16_surrogate_follow( code_point cp );
918  static size_t _utf16_char_length( code_point cp );
920  static size_t _utf16_char_length( unicode_char uc );
922 
926  static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc );
928 
933  static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] );
935 
937 
939 
940 
941  static bool _utf8_start_char( unsigned char cp );
943  static size_t _utf8_char_length( unsigned char cp );
945  static size_t _utf8_char_length( unicode_char uc );
946 
948  static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc );
950  static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] );
951 
953  static size_type _verifyUTF8( const unsigned char* c_str );
955  static size_type _verifyUTF8( const std::string& str );
957 
958  private:
959  //template<class ITER_TYPE> friend class _iterator;
960  dstring mData;
961 
963  enum BufferType {
964  bt_none,
965  bt_string,
966  bt_wstring,
967  bt_utf32string
968  };
969 
971  void _init();
972 
974  // Scratch buffer
976  void _cleanBuffer() const;
977 
979  void _getBufferStr() const;
981  void _getBufferWStr() const;
983  void _getBufferUTF32Str() const;
984 
985  void _load_buffer_UTF8() const;
986  void _load_buffer_WStr() const;
987  void _load_buffer_UTF32() const;
988 
989  mutable BufferType m_bufferType; // identifies the data type held in m_buffer
990  mutable size_t m_bufferSize; // size of the CString buffer
991 
992  // multi-purpose buffer used everywhere we need a throw-away buffer
993  union {
994  mutable void* mVoidBuffer;
995  mutable std::string* mStrBuffer;
996  mutable std::wstring* mWStrBuffer;
998  }
999  m_buffer;
1000  };
1001 
1003  inline UString operator+( const UString& s1, const UString& s2 ) {
1004  return UString( s1 ).append( s2 );
1005  }
1008  return UString( s1 ).append( 1, c );
1009  }
1012  return UString( s1 ).append( 1, c );
1013  }
1015  inline UString operator+( const UString& s1, char c ) {
1016  return UString( s1 ).append( 1, c );
1017  }
1018 #if MYGUI_IS_NATIVE_WCHAR_T
1019 
1020  inline UString operator+( const UString& s1, wchar_t c ) {
1021  return UString( s1 ).append( 1, c );
1022  }
1023 #endif
1024 
1026  return UString().append( 1, c ).append( s2 );
1027  }
1030  return UString().append( 1, c ).append( s2 );
1031  }
1033  inline UString operator+( char c, const UString& s2 ) {
1034  return UString().append( 1, c ).append( s2 );
1035  }
1036 #if MYGUI_IS_NATIVE_WCHAR_T
1037 
1038  inline UString operator+( wchar_t c, const UString& s2 ) {
1039  return UString().append( 1, c ).append( s2 );
1040  }
1041 #endif
1042 
1043  // (const) forward iterator common operators
1045  return ( left.mIter - right.mIter );
1046  }
1047  inline bool operator==( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1048  return left.mIter == right.mIter;
1049  }
1050  inline bool operator!=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1051  return left.mIter != right.mIter;
1052  }
1053  inline bool operator<( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1054  return left.mIter < right.mIter;
1055  }
1056  inline bool operator<=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1057  return left.mIter <= right.mIter;
1058  }
1059  inline bool operator>( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1060  return left.mIter > right.mIter;
1061  }
1062  inline bool operator>=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1063  return left.mIter >= right.mIter;
1064  }
1065 
1066  // (const) reverse iterator common operators
1067  // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator
1069  return ( right.mIter - left.mIter );
1070  }
1071  inline bool operator==( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1072  return left.mIter == right.mIter;
1073  }
1074  inline bool operator!=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1075  return left.mIter != right.mIter;
1076  }
1077  inline bool operator<( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1078  return right.mIter < left.mIter;
1079  }
1080  inline bool operator<=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1081  return right.mIter <= left.mIter;
1082  }
1083  inline bool operator>( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1084  return right.mIter > left.mIter;
1085  }
1086  inline bool operator>=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1087  return right.mIter >= left.mIter;
1088  }
1089 
1091  inline std::ostream& operator << ( std::ostream& os, const UString& s ) {
1092  return os << s.asUTF8();
1093  }
1094 
1096  inline std::wostream& operator << ( std::wostream& os, const UString& s ) {
1097  return os << s.asWStr();
1098  }
1099 
1100 } // namespace MyGUI
1101 
1102 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
1103 # pragma warning (pop)
1104 #endif
1105 
1106 #endif // __MYGUI_U_STRING_H__