MyGUI  3.2.0
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 (disable : 4275)
42 #endif
43 
44 // Workaround for VC7:
45 // when build with /MD or /MDd, VC7 have both std::basic_string<unsigned short> and
46 // basic_string<__wchar_t> instantiated in msvcprt[d].lib/MSVCP71[D].dll, but the header
47 // files tells compiler that only one of them is over there (based on /Zc:wchar_t compile
48 // option). And since this file used both of them, causing compiler instantiating another
49 // one in user object code, which lead to duplicate symbols with msvcprt.lib/MSVCP71[D].dll.
50 //
51 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && (1300 <= MYGUI_COMP_VER && MYGUI_COMP_VER <= 1310)
52 
53 # if defined(_DLL_CPPLIB)
54 
55 namespace std
56 {
57  template class _CRTIMP2 basic_string<unsigned short, char_traits<unsigned short>,
58  allocator<unsigned short> >;
59 
60  template class _CRTIMP2 basic_string<__wchar_t, char_traits<__wchar_t>,
61  allocator<__wchar_t> >;
62 }
63 
64 # endif // defined(_DLL_CPPLIB)
65 
66 #endif // MYGUI_COMPILER == MYGUI_COMPILER_MSVC && MYGUI_COMP_VER == 1300
67 
68 
69 namespace MyGUI
70 {
71 
72  /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS
73  =NOTICE=
74  This class is not a complete Unicode solution. It purposefully does not
75  provide certain functionality, such as proper lexical sorting for
76  Unicode values. It does provide comparison operators for the sole purpose
77  of using UString as an index with std::map and other operator< sorted
78  containers, but it should NOT be relied upon for meaningful lexical
79  operations, such as alphabetical sorts. If you need this type of
80  functionality, look into using ICU instead (http://icu.sourceforge.net/).
81 
82  =REQUIREMENTS=
83  There are a few requirements for proper operation. They are fairly small,
84  and shouldn't restrict usage on any reasonable target.
85  * Compiler must support unsigned 16-bit integer types
86  * Compiler must support signed 32-bit integer types
87  * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such
88  using the WCHAR_UTF16 macro as outlined below.
89  * You must include <iterator>, <string>, and <wchar>. Probably more, but
90  these are the most obvious.
91 
92  =REQUIRED PREPROCESSOR MACROS=
93  This class requires two preprocessor macros to be defined in order to
94  work as advertised.
95  INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int)
96  UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short)
97 
98  Additionally, a third macro should be defined to control the evaluation of wchar_t:
99  WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points,
100  such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit
101  integer representing UTF-32 code points.
102  */
103 
104  // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS
105 #ifdef __STDC_ISO_10646__
106 // for any compiler that provides this, wchar_t is guaranteed to hold any Unicode value with a single code point (32-bit or larger)
107 // so we can safely skip the rest of the testing
108 #else // #ifdef __STDC_ISO_10646__
109 #if defined( __WIN32__ ) || defined( _WIN32 )
110 #define WCHAR_UTF16 // All currently known Windows platforms utilize UTF-16 encoding in wchar_t
111 #else // #if defined( __WIN32__ ) || defined( _WIN32 )
112 #if MYGUI_COMPILER != MYGUI_COMPILER_GCCE
113 #if WCHAR_MAX <= 0xFFFF // this is a last resort fall back test; WCHAR_MAX is defined in <wchar.h>
114 #define WCHAR_UTF16 // best we can tell, wchar_t is not larger than 16-bit
115 #endif // #if WCHAR_MAX <= 0xFFFF
116 #endif
117 #endif // #if defined( __WIN32__ ) || defined( _WIN32 )
118 #endif // #ifdef __STDC_ISO_10646__
119 
120 
121 // MYGUI_IS_NATIVE_WCHAR_T means that wchar_t isn't a typedef of
122 // uint16_t or uint32_t.
123 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
124 
125 // Don't define wchar_t related functions since it'll duplicate
126 // with UString::code_point related functions when compile
127 // without /Zc:wchar_t, because in this case both of them are
128 // a typedef of uint16_t.
129 # if defined(_NATIVE_WCHAR_T_DEFINED)
130 # define MYGUI_IS_NATIVE_WCHAR_T 1
131 # else
132 # define MYGUI_IS_NATIVE_WCHAR_T 0
133 # endif
134 #elif MYGUI_PLATFORM == MYGUI_PLATFORM_SYMBIAN
135 # define MYGUI_IS_NATIVE_WCHAR_T 0
136 #else // MYGUI_COMPILER != MYGUI_COMPILER_MSVC
137 
138 // Assumed wchar_t is natively for other compilers
139 # define MYGUI_IS_NATIVE_WCHAR_T 1
140 
141 #endif // MYGUI_COMPILER == MYGUI_COMPILER_MSVC
142 
144 
170  // constants used in UTF-8 conversions
171  static const unsigned char _lead1 = 0xC0; //110xxxxx
172  static const unsigned char _lead1_mask = 0x1F; //00011111
173  static const unsigned char _lead2 = 0xE0; //1110xxxx
174  static const unsigned char _lead2_mask = 0x0F; //00001111
175  static const unsigned char _lead3 = 0xF0; //11110xxx
176  static const unsigned char _lead3_mask = 0x07; //00000111
177  static const unsigned char _lead4 = 0xF8; //111110xx
178  static const unsigned char _lead4_mask = 0x03; //00000011
179  static const unsigned char _lead5 = 0xFC; //1111110x
180  static const unsigned char _lead5_mask = 0x01; //00000001
181  static const unsigned char _cont = 0x80; //10xxxxxx
182  static const unsigned char _cont_mask = 0x3F; //00111111
183 
184  public:
186  typedef size_t size_type;
188  static const size_type npos = static_cast<size_type>(~0);
189 
192 
195 
198 
199  typedef std::basic_string<code_point> dstring; // data string
200 
202  typedef std::basic_string<unicode_char> utf32string;
203 
205  class MYGUI_EXPORT invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */
206  public:
208  explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) {
209  /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */
210  }
211  };
212 
213  //#########################################################################
215  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 */
216  friend class UString;
217  protected:
218  _base_iterator();
219 
220  void _seekFwd( size_type c );
221  void _seekRev( size_type c );
222  void _become( const _base_iterator& i );
223  bool _test_begin() const;
224  bool _test_end() const;
225  size_type _get_index() const;
226  void _jump_to( size_type index );
227 
228  unicode_char _getCharacter() const;
229  int _setCharacter( unicode_char uc );
230 
231  void _moveNext();
232  void _movePrev();
233 
234  dstring::iterator mIter;
236  };
237 
238  //#########################################################################
239  // FORWARD ITERATORS
240  //#########################################################################
241  class _const_fwd_iterator; // forward declaration
242 
244  class MYGUI_EXPORT _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
245  friend class _const_fwd_iterator;
246  public:
247  _fwd_iterator();
248  _fwd_iterator( const _fwd_iterator& i );
249 
251  _fwd_iterator& operator++();
253  _fwd_iterator operator++( int );
254 
256  _fwd_iterator& operator--();
258  _fwd_iterator operator--( int );
259 
261  _fwd_iterator operator+( difference_type n );
263  _fwd_iterator operator-( difference_type n );
264 
266  _fwd_iterator& operator+=( difference_type n );
268  _fwd_iterator& operator-=( difference_type n );
269 
271  value_type& operator*() const;
272 
274  value_type& operator[]( difference_type n ) const;
275 
277  _fwd_iterator& moveNext();
279  _fwd_iterator& movePrev();
281  unicode_char getCharacter() const;
283  int setCharacter( unicode_char uc );
284  };
285 
286 
287 
288  //#########################################################################
290  class MYGUI_EXPORT _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
291  public:
295 
297  _const_fwd_iterator& operator++();
299  _const_fwd_iterator operator++( int );
300 
302  _const_fwd_iterator& operator--();
304  _const_fwd_iterator operator--( int );
305 
307  _const_fwd_iterator operator+( difference_type n );
309  _const_fwd_iterator operator-( difference_type n );
310 
312  _const_fwd_iterator& operator+=( difference_type n );
314  _const_fwd_iterator& operator-=( difference_type n );
315 
317  const value_type& operator*() const;
318 
320  const value_type& operator[]( difference_type n ) const;
321 
323  _const_fwd_iterator& moveNext();
325  _const_fwd_iterator& movePrev();
327  unicode_char getCharacter() const;
328 
330  friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
332  friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
334  friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
336  friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
338  friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
340  friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
342  friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right );
343 
344  };
345 
346  //#########################################################################
347  // REVERSE ITERATORS
348  //#########################################################################
349  class _const_rev_iterator; // forward declaration
351  class MYGUI_EXPORT _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
352  friend class _const_rev_iterator;
353  public:
354  _rev_iterator();
355  _rev_iterator( const _rev_iterator& i );
356 
358  _rev_iterator& operator++();
360  _rev_iterator operator++( int );
361 
363  _rev_iterator& operator--();
365  _rev_iterator operator--( int );
366 
368  _rev_iterator operator+( difference_type n );
370  _rev_iterator operator-( difference_type n );
371 
373  _rev_iterator& operator+=( difference_type n );
375  _rev_iterator& operator-=( difference_type n );
376 
378  value_type& operator*() const;
379 
381  value_type& operator[]( difference_type n ) const;
382  };
383  //#########################################################################
385  class MYGUI_EXPORT _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */
386  public:
391  _const_rev_iterator& operator++();
393  _const_rev_iterator operator++( int );
394 
396  _const_rev_iterator& operator--();
398  _const_rev_iterator operator--( int );
399 
401  _const_rev_iterator operator+( difference_type n );
403  _const_rev_iterator operator-( difference_type n );
404 
406  _const_rev_iterator& operator+=( difference_type n );
408  _const_rev_iterator& operator-=( difference_type n );
409 
411  const value_type& operator*() const;
412 
414  const value_type& operator[]( difference_type n ) const;
415 
417  friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right );
419  friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right );
421  friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right );
423  friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right );
425  friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right );
427  friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right );
429  friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right );
430  };
431  //#########################################################################
432 
437 
438 
440 
441 
442  UString();
444  UString( const UString& copy );
446  UString( size_type length, const code_point& ch );
448  UString( const code_point* str );
450  UString( const code_point* str, size_type length );
452  UString( const UString& str, size_type index, size_type length );
453 #if MYGUI_IS_NATIVE_WCHAR_T
454 
455  UString( const wchar_t* w_str );
457  UString( const wchar_t* w_str, size_type length );
458 #endif
459 
460  UString( const std::wstring& wstr );
462  UString( const char* c_str );
464  UString( const char* c_str, size_type length );
466  UString( const std::string& str );
467 
469  ~UString();
471 
473 
475 
476 
477  size_type size() const;
479  size_type length() const;
481 
482  size_type length_Characters() const;
484  size_type max_size() const;
486  void reserve( size_type size );
488  void resize( size_type num, const code_point& val = 0 );
490  void swap( UString& from );
492  bool empty() const;
494  const code_point* c_str() const;
496  const code_point* data() const;
498  size_type capacity() const;
500  void clear();
502 
503  UString substr( size_type index, size_type num = npos ) const;
505  void push_back( unicode_char val );
506 #if MYGUI_IS_NATIVE_WCHAR_T
507 
508  void push_back( wchar_t val );
509 #endif
510 
511 
513  void push_back( code_point val );
515 
516  void push_back( char val );
518  bool inString( unicode_char ch ) const;
520 
522 
524 
525 
526  const std::string& asUTF8() const;
528  const char* asUTF8_c_str() const;
530  const utf32string& asUTF32() const;
532  const unicode_char* asUTF32_c_str() const;
534  const std::wstring& asWStr() const;
536  const wchar_t* asWStr_c_str() const;
538 
540 
542 
543 
544  code_point& at( size_type loc );
546  const code_point& at( size_type loc ) const;
548 
552  unicode_char getChar( size_type loc ) const;
554 
562  int setChar( size_type loc, unicode_char ch );
564 
566 
568 
569 
570  iterator begin();
572  const_iterator begin() const;
574  iterator end();
576  const_iterator end() const;
578  reverse_iterator rbegin();
580  const_reverse_iterator rbegin() const;
582  reverse_iterator rend();
584  const_reverse_iterator rend() const;
586 
588 
590 
591 
592  UString& assign( iterator start, iterator end );
594  UString& assign( const UString& str );
596  UString& assign( const code_point* str );
598  UString& assign( const code_point* str, size_type num );
600  UString& assign( const UString& str, size_type index, size_type len );
602  UString& assign( size_type num, const code_point& ch );
604  UString& assign( const std::wstring& wstr );
605 #if MYGUI_IS_NATIVE_WCHAR_T
606 
607  UString& assign( const wchar_t* w_str );
609  UString& assign( const wchar_t* w_str, size_type num );
610 #endif
611 
612  UString& assign( const std::string& str );
614  UString& assign( const char* c_str );
616  UString& assign( const char* c_str, size_type num );
618 
620 
622 
623 
624  UString& append( const UString& str );
626  UString& append( const code_point* str );
628  UString& append( const UString& str, size_type index, size_type len );
630  UString& append( const code_point* str, size_type num );
632  UString& append( size_type num, code_point ch );
634  UString& append( iterator start, iterator end );
635 #if MYGUI_IS_NATIVE_WCHAR_T
636 
637  UString& append( const wchar_t* w_str, size_type num );
639  UString& append( size_type num, wchar_t ch );
640 #endif
641 
642  UString& append( const char* c_str, size_type num );
644  UString& append( size_type num, char ch );
646  UString& append( size_type num, unicode_char ch );
648 
650 
652 
653 
654  iterator insert( iterator i, const code_point& ch );
656  UString& insert( size_type index, const UString& str );
658  UString& insert( size_type index, const code_point* str ) {
659  mData.insert( index, str );
660  return *this;
661  }
663  UString& insert( size_type index1, const UString& str, size_type index2, size_type num );
665  void insert( iterator i, iterator start, iterator end );
667  UString& insert( size_type index, const code_point* str, size_type num );
668 #if MYGUI_IS_NATIVE_WCHAR_T
669 
670  UString& insert( size_type index, const wchar_t* w_str, size_type num );
671 #endif
672 
673  UString& insert( size_type index, const char* c_str, size_type num );
675  UString& insert( size_type index, size_type num, code_point ch );
676 #if MYGUI_IS_NATIVE_WCHAR_T
677 
678  UString& insert( size_type index, size_type num, wchar_t ch );
679 #endif
680 
681  UString& insert( size_type index, size_type num, char ch );
683  UString& insert( size_type index, size_type num, unicode_char ch );
685  void insert( iterator i, size_type num, const code_point& ch );
686 #if MYGUI_IS_NATIVE_WCHAR_T
687 
688  void insert( iterator i, size_type num, const wchar_t& ch );
689 #endif
690 
691  void insert( iterator i, size_type num, const char& ch );
693  void insert( iterator i, size_type num, const unicode_char& ch );
695 
697 
699 
700 
701  iterator erase( iterator loc );
703  iterator erase( iterator start, iterator end );
705  UString& erase( size_type index = 0, size_type num = npos );
707 
709 
711 
712 
713  UString& replace( size_type index1, size_type num1, const UString& str );
715  UString& replace( size_type index1, size_type num1, const UString& str, size_type num2 );
717  UString& replace( size_type index1, size_type num1, const UString& str, size_type index2, size_type num2 );
719  UString& replace( iterator start, iterator end, const UString& str, size_type num = npos );
721  UString& replace( size_type index, size_type num1, size_type num2, code_point ch );
723  UString& replace( iterator start, iterator end, size_type num, code_point ch );
725 
727 
729 
730 
731  int compare( const UString& str ) const;
733  int compare( const code_point* str ) const;
735  int compare( size_type index, size_type length, const UString& str ) const;
737  int compare( size_type index, size_type length, const UString& str, size_type index2, size_type length2 ) const;
739  int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const;
740 #if MYGUI_IS_NATIVE_WCHAR_T
741 
742  int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const;
743 #endif
744 
745  int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const;
747 
749 
751 
752 
753 
754  size_type find( const UString& str, size_type index = 0 ) const;
756 
757  size_type find( const code_point* cp_str, size_type index, size_type length ) const;
759 
760  size_type find( const char* c_str, size_type index, size_type length ) const;
761 #if MYGUI_IS_NATIVE_WCHAR_T
762 
763 
764  size_type find( const wchar_t* w_str, size_type index, size_type length ) const;
765 #endif
766 
767 
768  size_type find( char ch, size_type index = 0 ) const;
770 
771  size_type find( code_point ch, size_type index = 0 ) const;
772 #if MYGUI_IS_NATIVE_WCHAR_T
773 
774 
775  size_type find( wchar_t ch, size_type index = 0 ) const;
776 #endif
777 
778 
779  size_type find( unicode_char ch, size_type index = 0 ) const;
780 
782  size_type rfind( const UString& str, size_type index = 0 ) const;
784  size_type rfind( const code_point* cp_str, size_type index, size_type num ) const;
786  size_type rfind( const char* c_str, size_type index, size_type num ) const;
787 #if MYGUI_IS_NATIVE_WCHAR_T
788 
789  size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const;
790 #endif
791 
792  size_type rfind( char ch, size_type index = 0 ) const;
794  size_type rfind( code_point ch, size_type index ) const;
795 #if MYGUI_IS_NATIVE_WCHAR_T
796 
797  size_type rfind( wchar_t ch, size_type index = 0 ) const;
798 #endif
799 
800  size_type rfind( unicode_char ch, size_type index = 0 ) const;
802 
804 
806 
807 
808  size_type find_first_of( const UString &str, size_type index = 0, size_type num = npos ) const;
810  size_type find_first_of( code_point ch, size_type index = 0 ) const;
812  size_type find_first_of( char ch, size_type index = 0 ) const;
813 #if MYGUI_IS_NATIVE_WCHAR_T
814 
815  size_type find_first_of( wchar_t ch, size_type index = 0 ) const;
816 #endif
817 
818  size_type find_first_of( unicode_char ch, size_type index = 0 ) const;
819 
821  size_type find_first_not_of( const UString& str, size_type index = 0, size_type num = npos ) const;
823  size_type find_first_not_of( code_point ch, size_type index = 0 ) const;
825  size_type find_first_not_of( char ch, size_type index = 0 ) const;
826 #if MYGUI_IS_NATIVE_WCHAR_T
827 
828  size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const;
829 #endif
830 
831  size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const;
832 
834  size_type find_last_of( const UString& str, size_type index = npos, size_type num = npos ) const;
836  size_type find_last_of( code_point ch, size_type index = npos ) const;
838  size_type find_last_of( char ch, size_type index = npos ) const {
839  return find_last_of( static_cast<code_point>( ch ), index );
840  }
841 #if MYGUI_IS_NATIVE_WCHAR_T
842 
843  size_type find_last_of( wchar_t ch, size_type index = npos ) const;
844 #endif
845 
846  size_type find_last_of( unicode_char ch, size_type index = npos ) const;
847 
849  size_type find_last_not_of( const UString& str, size_type index = npos, size_type num = npos ) const;
851  size_type find_last_not_of( code_point ch, size_type index = npos ) const;
853  size_type find_last_not_of( char ch, size_type index = npos ) const;
854 #if MYGUI_IS_NATIVE_WCHAR_T
855 
856  size_type find_last_not_of( wchar_t ch, size_type index = npos ) const;
857 #endif
858 
859  size_type find_last_not_of( unicode_char ch, size_type index = npos ) const;
861 
863 
865 
866 
867  bool operator<( const UString& right ) const;
869  bool operator<=( const UString& right ) const;
871  bool operator>( const UString& right ) const;
873  bool operator>=( const UString& right ) const;
875  bool operator==( const UString& right ) const;
877  bool operator!=( const UString& right ) const;
879  UString& operator=( const UString& s );
881  UString& operator=( code_point ch );
883  UString& operator=( char ch );
884 #if MYGUI_IS_NATIVE_WCHAR_T
885 
886  UString& operator=( wchar_t ch );
887 #endif
888 
889  UString& operator=( unicode_char ch );
891  code_point& operator[]( size_type index );
893  const code_point& operator[]( size_type index ) const;
895 
897 
899 
900 
901  operator std::string() const;
903  operator std::wstring() const;
905 
907 
909 
910 
911  static bool _utf16_independent_char( code_point cp );
913  static bool _utf16_surrogate_lead( code_point cp );
915  static bool _utf16_surrogate_follow( code_point cp );
917  static size_t _utf16_char_length( code_point cp );
919  static size_t _utf16_char_length( unicode_char uc );
921 
925  static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc );
927 
932  static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] );
934 
936 
938 
939 
940  static bool _utf8_start_char( unsigned char cp );
942  static size_t _utf8_char_length( unsigned char cp );
944  static size_t _utf8_char_length( unicode_char uc );
945 
947  static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc );
949  static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] );
950 
952  static size_type _verifyUTF8( const unsigned char* c_str );
954  static size_type _verifyUTF8( const std::string& str );
956 
957  private:
958  //template<class ITER_TYPE> friend class _iterator;
959  dstring mData;
960 
962  enum BufferType {
963  bt_none,
964  bt_string,
965  bt_wstring,
966  bt_utf32string
967  };
968 
970  void _init();
971 
973  // Scratch buffer
975  void _cleanBuffer() const;
976 
978  void _getBufferStr() const;
980  void _getBufferWStr() const;
982  void _getBufferUTF32Str() const;
983 
984  void _load_buffer_UTF8() const;
985  void _load_buffer_WStr() const;
986  void _load_buffer_UTF32() const;
987 
988  mutable BufferType m_bufferType; // identifies the data type held in m_buffer
989  mutable size_t m_bufferSize; // size of the CString buffer
990 
991  // multi-purpose buffer used everywhere we need a throw-away buffer
992  union {
993  mutable void* mVoidBuffer;
994  mutable std::string* mStrBuffer;
995  mutable std::wstring* mWStrBuffer;
997  }
998  m_buffer;
999  };
1000 
1002  inline UString operator+( const UString& s1, const UString& s2 ) {
1003  return UString( s1 ).append( s2 );
1004  }
1007  return UString( s1 ).append( 1, c );
1008  }
1011  return UString( s1 ).append( 1, c );
1012  }
1014  inline UString operator+( const UString& s1, char c ) {
1015  return UString( s1 ).append( 1, c );
1016  }
1017 #if MYGUI_IS_NATIVE_WCHAR_T
1018 
1019  inline UString operator+( const UString& s1, wchar_t c ) {
1020  return UString( s1 ).append( 1, c );
1021  }
1022 #endif
1023 
1025  return UString().append( 1, c ).append( s2 );
1026  }
1029  return UString().append( 1, c ).append( s2 );
1030  }
1032  inline UString operator+( char c, const UString& s2 ) {
1033  return UString().append( 1, c ).append( s2 );
1034  }
1035 #if MYGUI_IS_NATIVE_WCHAR_T
1036 
1037  inline UString operator+( wchar_t c, const UString& s2 ) {
1038  return UString().append( 1, c ).append( s2 );
1039  }
1040 #endif
1041 
1042  // (const) forward iterator common operators
1044  return ( left.mIter - right.mIter );
1045  }
1046  inline bool operator==( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1047  return left.mIter == right.mIter;
1048  }
1049  inline bool operator!=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1050  return left.mIter != right.mIter;
1051  }
1052  inline bool operator<( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1053  return left.mIter < right.mIter;
1054  }
1055  inline bool operator<=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1056  return left.mIter <= right.mIter;
1057  }
1058  inline bool operator>( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1059  return left.mIter > right.mIter;
1060  }
1061  inline bool operator>=( const UString::_const_fwd_iterator& left, const UString::_const_fwd_iterator& right ) {
1062  return left.mIter >= right.mIter;
1063  }
1064 
1065  // (const) reverse iterator common operators
1066  // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator
1068  return ( right.mIter - left.mIter );
1069  }
1070  inline bool operator==( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1071  return left.mIter == right.mIter;
1072  }
1073  inline bool operator!=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1074  return left.mIter != right.mIter;
1075  }
1076  inline bool operator<( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1077  return right.mIter < left.mIter;
1078  }
1079  inline bool operator<=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1080  return right.mIter <= left.mIter;
1081  }
1082  inline bool operator>( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1083  return right.mIter > left.mIter;
1084  }
1085  inline bool operator>=( const UString::_const_rev_iterator& left, const UString::_const_rev_iterator& right ) {
1086  return right.mIter >= left.mIter;
1087  }
1088 
1090  inline std::ostream& operator << ( std::ostream& os, const UString& s ) {
1091  return os << s.asUTF8();
1092  }
1093 
1095  inline std::wostream& operator << ( std::wostream& os, const UString& s ) {
1096  return os << s.asWStr();
1097  }
1098 
1099 } // namespace MyGUI
1100 
1101 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC
1102 # pragma warning (default : 4275)
1103 #endif
1104 
1105 #endif // __MYGUI_U_STRING_H__