00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _CEGUIString_h_
00031 #define _CEGUIString_h_
00032
00033 #include "CEGUIBase.h"
00034 #include <string>
00035 #include <string.h>
00036 #include <stdexcept>
00037
00038
00039 namespace CEGUI
00040 {
00041 #define STR_QUICKBUFF_SIZE 32
00042
00043
00044
00045 typedef uint8 utf8;
00046
00047 typedef uint32 utf32;
00048
00057 class CEGUIEXPORT String
00058 {
00059 public:
00060
00061
00062
00063 typedef utf32 value_type;
00064 typedef size_t size_type;
00065 typedef ptrdiff_t difference_type;
00066 typedef utf32& reference;
00067 typedef const utf32& const_reference;
00068 typedef utf32* pointer;
00069 typedef const utf32* const_pointer;
00070
00071 static const size_type npos;
00072
00073 private:
00074
00075
00076
00077 size_type d_cplength;
00078 size_type d_reserve;
00079
00080 mutable utf8* d_encodedbuff;
00081 mutable size_type d_encodeddatlen;
00082 mutable size_type d_encodedbufflen;
00083
00084 utf32 d_quickbuff[STR_QUICKBUFF_SIZE];
00085 utf32* d_buffer;
00086
00087 public:
00088
00089
00090
00095 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00096 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32>
00097 #else
00098 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32, std::ptrdiff_t, const utf32*, const utf32&>
00099 #endif
00100 {
00101
00102 public:
00104
00106 const utf32* d_ptr;
00107
00108
00110
00112 const_iterator(void)
00113 {
00114 d_ptr = 0;
00115 }
00116 const_iterator(const_pointer ptr)
00117 {
00118 d_ptr = ptr;
00119 }
00120
00121 const_reference operator*() const
00122 {
00123 return *d_ptr;
00124 }
00125
00126 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00127 # pragma warning (push)
00128 # pragma warning (disable : 4284)
00129 #endif
00130 const_pointer operator->() const
00131 {
00132 return &**this;
00133 }
00134
00135 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00136 # pragma warning (pop)
00137 #endif
00138
00139 const_iterator& operator++()
00140 {
00141 ++d_ptr;
00142 return *this;
00143 }
00144
00145 const_iterator operator++(int)
00146 {
00147 const_iterator temp = *this;
00148 ++*this;
00149 return temp;
00150 }
00151
00152 const_iterator& operator--()
00153 {
00154 --d_ptr;
00155 return *this;
00156 }
00157
00158 const_iterator operator--(int)
00159 {
00160 const_iterator temp = *this;
00161 --*this;
00162 return temp;
00163 }
00164
00165 const_iterator& operator+=(difference_type offset)
00166 {
00167 d_ptr += offset;
00168 return *this;
00169 }
00170
00171 const_iterator operator+(difference_type offset) const
00172 {
00173 const_iterator temp = *this;
00174 return temp += offset;
00175 }
00176
00177 const_iterator& operator-=(difference_type offset)
00178 {
00179 return *this += -offset;
00180 }
00181
00182 const_iterator operator-(difference_type offset) const
00183 {
00184 const_iterator temp = *this;
00185 return temp -= offset;
00186 }
00187
00188 difference_type operator-(const const_iterator& iter) const
00189 {
00190 return d_ptr - iter.d_ptr;
00191 }
00192
00193 const_reference operator[](difference_type offset) const
00194 {
00195 return *(*this + offset);
00196 }
00197
00198 bool operator==(const const_iterator& iter) const
00199 {
00200 return d_ptr == iter.d_ptr;
00201 }
00202
00203 bool operator!=(const const_iterator& iter) const
00204 {
00205 return !(*this == iter);
00206 }
00207
00208 bool operator<(const const_iterator& iter) const
00209 {
00210 return d_ptr < iter.d_ptr;
00211 }
00212
00213 bool operator>(const const_iterator& iter) const
00214 {
00215 return (!(iter < *this));
00216 }
00217
00218 bool operator<=(const const_iterator& iter) const
00219 {
00220 return (!(iter < *this));
00221 }
00222
00223 bool operator>=(const const_iterator& iter) const
00224 {
00225 return (!(*this < iter));
00226 }
00227
00228 friend const_iterator operator+(difference_type offset, const const_iterator& iter)
00229 {
00230 return iter + offset;
00231 }
00232
00233 };
00234
00239 class iterator : public const_iterator
00240 {
00241 public:
00242 iterator(void) {}
00243 iterator(pointer ptr) : const_iterator(ptr) {}
00244
00245
00246 reference operator*() const
00247 {
00248 return ((reference)**(const_iterator *)this);
00249 }
00250
00251 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00252 # pragma warning (push)
00253 # pragma warning (disable : 4284)
00254 #endif
00255
00256 pointer operator->() const
00257 {
00258 return &**this;
00259 }
00260
00261 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00262 # pragma warning (pop)
00263 #endif
00264
00265 iterator& operator++()
00266 {
00267 ++this->d_ptr;
00268 return *this;
00269 }
00270
00271 iterator operator++(int)
00272 {
00273 iterator temp = *this;
00274 ++*this;
00275 return temp;
00276 }
00277
00278 iterator& operator--()
00279 {
00280 --this->d_ptr;
00281 return *this;
00282 }
00283
00284 iterator operator--(int)
00285 {
00286 iterator temp = *this;
00287 --*this;
00288 return temp;
00289 }
00290
00291 iterator& operator+=(difference_type offset)
00292 {
00293 this->d_ptr += offset;
00294 return *this;
00295 }
00296
00297 iterator operator+(difference_type offset) const
00298 {
00299 iterator temp = *this;
00300 return temp += offset;
00301 }
00302
00303 iterator& operator-=(difference_type offset)
00304 {
00305 return *this += -offset;
00306 }
00307
00308 iterator operator-(difference_type offset) const
00309 {
00310 iterator temp = *this;
00311 return temp -= offset;
00312 }
00313
00314 difference_type operator-(const const_iterator& iter) const
00315 {
00316 return ((const_iterator)*this - iter);
00317 }
00318
00319 reference operator[](difference_type offset) const
00320 {
00321 return *(*this + offset);
00322 }
00323
00324 friend iterator operator+(difference_type offset, const iterator& iter)
00325 {
00326 return iter + offset;
00327 }
00328
00329 };
00330
00335 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
00336 typedef std::reverse_iterator<const_iterator, const_pointer, const_reference, difference_type> const_reverse_iterator;
00337 #else
00338 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00339 #endif
00340
00345 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
00346 typedef std::reverse_iterator<iterator, pointer, reference, difference_type> reverse_iterator;
00347 #else
00348 typedef std::reverse_iterator<iterator> reverse_iterator;
00349 #endif
00350
00351 public:
00357 struct FastLessCompare
00358 {
00359 bool operator() (const String& a, const String& b) const
00360 {
00361 const size_t la = a.length();
00362 const size_t lb = b.length();
00363 if (la == lb)
00364 return (memcmp(a.ptr(), b.ptr(), la*sizeof(utf32)) < 0);
00365 return (la < lb);
00366 }
00367 };
00368
00369 public:
00371
00373
00377 String(void)
00378 {
00379 init();
00380 }
00381
00386 ~String(void);
00387
00389
00391
00401 String(const String& str)
00402 {
00403 init();
00404 assign(str);
00405 }
00406
00407
00424 String(const String& str, size_type str_idx, size_type str_num = npos)
00425 {
00426 init();
00427 assign(str, str_idx, str_num);
00428 }
00429
00431
00433
00449 String(const std::string& std_str)
00450 {
00451 init();
00452 assign(std_str);
00453 }
00454
00477 String(const std::string& std_str, size_type str_idx, size_type str_num = npos)
00478 {
00479 init();
00480 assign(std_str, str_idx, str_num);
00481 }
00482
00483
00485
00487
00505 String(const utf8* utf8_str)
00506 {
00507 init();
00508 assign(utf8_str);
00509 }
00510
00537 String(const utf8* utf8_str, size_type chars_len)
00538 {
00539 init();
00540 assign(utf8_str, chars_len);
00541 }
00542
00544
00546
00561 String(size_type num, utf32 code_point)
00562 {
00563 init();
00564 assign(num, code_point);
00565 }
00566
00568
00570
00584 String(const_iterator iter_beg, const_iterator iter_end)
00585 {
00586 init();
00587 append(iter_beg, iter_end);
00588 }
00589
00590
00592
00594
00606 String(const char* cstr)
00607 {
00608 init();
00609 assign(cstr);
00610 }
00611
00627 String(const char* chars, size_type chars_len)
00628 {
00629 init();
00630 assign(chars, chars_len);
00631 }
00632
00633
00635
00637
00644 size_type size(void) const
00645 {
00646 return d_cplength;
00647 }
00648
00656 size_type length(void) const
00657 {
00658 return d_cplength;
00659 }
00660
00668 bool empty(void) const
00669 {
00670 return (d_cplength == 0);
00671 }
00672
00682 static size_type max_size(void)
00683 {
00684 return (((size_type)-1) / sizeof(utf32));
00685 }
00686
00688
00690
00691
00700 size_type capacity(void) const
00701 {
00702 return d_reserve - 1;
00703 }
00704
00705
00720 void reserve(size_type num = 0)
00721 {
00722 if (num == 0)
00723 trim();
00724 else
00725 grow(num);
00726 }
00727
00729
00731
00746 int compare(const String& str) const
00747 {
00748 return compare(0, d_cplength, str);
00749 }
00750
00780 int compare(size_type idx, size_type len, const String& str, size_type str_idx = 0, size_type str_len = npos) const
00781 {
00782 if ((d_cplength < idx) || (str.d_cplength < str_idx))
00783 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
00784
00785 if ((len == npos) || (idx + len > d_cplength))
00786 len = d_cplength - idx;
00787
00788 if ((str_len == npos) || (str_idx + str_len > str.d_cplength))
00789 str_len = str.d_cplength - str_idx;
00790
00791 int val = (len == 0) ? 0 : utf32_comp_utf32(&ptr()[idx], &str.ptr()[str_idx], (len < str_len) ? len : str_len);
00792
00793 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
00794 }
00795
00796
00816 int compare(const std::string& std_str) const
00817 {
00818 return compare(0, d_cplength, std_str);
00819 }
00820
00821
00855 int compare(size_type idx, size_type len, const std::string& std_str, size_type str_idx = 0, size_type str_len = npos) const
00856 {
00857 if (d_cplength < idx)
00858 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
00859
00860 if (std_str.size() < str_idx)
00861 CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
00862
00863 if ((len == npos) || (idx + len > d_cplength))
00864 len = d_cplength - idx;
00865
00866 if ((str_len == npos) || (str_idx + str_len > std_str.size()))
00867 str_len = (size_type)std_str.size() - str_idx;
00868
00869 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], &std_str.c_str()[str_idx], (len < str_len) ? len : str_len);
00870
00871 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
00872 }
00873
00874
00896 int compare(const utf8* utf8_str) const
00897 {
00898 return compare(0, d_cplength, utf8_str, encoded_size(utf8_str));
00899 }
00900
00901
00931 int compare(size_type idx, size_type len, const utf8* utf8_str) const
00932 {
00933 return compare(idx, len, utf8_str, encoded_size(utf8_str));
00934 }
00935
00969 int compare(size_type idx, size_type len, const utf8* utf8_str, size_type str_cplen) const
00970 {
00971 if (d_cplength < idx)
00972 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
00973
00974 if (str_cplen == npos)
00975 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
00976
00977 if ((len == npos) || (idx + len > d_cplength))
00978 len = d_cplength - idx;
00979
00980 int val = (len == 0) ? 0 : utf32_comp_utf8(&ptr()[idx], utf8_str, (len < str_cplen) ? len : str_cplen);
00981
00982 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_cplen) ? -1 : (len == str_cplen) ? 0 : 1;
00983 }
00984
00985
01001 int compare(const char* cstr) const
01002 {
01003 return compare(0, d_cplength, cstr, strlen(cstr));
01004 }
01005
01006
01030 int compare(size_type idx, size_type len, const char* cstr) const
01031 {
01032 return compare(idx, len, cstr, strlen(cstr));
01033 }
01034
01035
01063 int compare(size_type idx, size_type len, const char* chars, size_type chars_len) const
01064 {
01065 if (d_cplength < idx)
01066 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
01067
01068 if (chars_len == npos)
01069 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
01070
01071 if ((len == npos) || (idx + len > d_cplength))
01072 len = d_cplength - idx;
01073
01074 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], chars, (len < chars_len) ? len : chars_len);
01075
01076 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < chars_len) ? -1 : (len == chars_len) ? 0 : 1;
01077 }
01078
01079
01081
01083
01097 reference operator[](size_type idx)
01098 {
01099 return (ptr()[idx]);
01100 }
01101
01116 value_type operator[](size_type idx) const
01117 {
01118 return ptr()[idx];
01119 }
01120
01133 reference at(size_type idx)
01134 {
01135 if (d_cplength <= idx)
01136 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
01137
01138 return ptr()[idx];
01139 }
01140
01153 const_reference at(size_type idx) const
01154 {
01155 if (d_cplength <= idx)
01156 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
01157
01158 return ptr()[idx];
01159 }
01160
01161
01163
01165
01178 const char* c_str(void) const
01179 {
01180 return (const char*)build_utf8_buff();
01181 }
01182
01196 const utf8* data(void) const
01197 {
01198 return build_utf8_buff();
01199 }
01200
01205 utf32* ptr(void)
01206 {
01207 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
01208 }
01209
01214 const utf32* ptr(void) const
01215 {
01216 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
01217 }
01218
01219
01220
01241 size_type copy(utf8* buf, size_type len = npos, size_type idx = 0) const
01242 {
01243 if (d_cplength < idx)
01244 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
01245
01246 if (len == npos)
01247 len = d_cplength;
01248
01249 return encode(&ptr()[idx], buf, npos, len);
01250 }
01251
01253
01255
01271 size_type utf8_stream_len(size_type num = npos, size_type idx = 0) const
01272 {
01273 using namespace std;
01274
01275 if (d_cplength < idx)
01276 CEGUI_THROW(out_of_range("Index was out of range for CEGUI::String object"));
01277
01278 size_type maxlen = d_cplength - idx;
01279
01280 return encoded_size(&ptr()[idx], ceguimin(num, maxlen));
01281 }
01282
01284
01286
01296 String& operator=(const String& str)
01297 {
01298 return assign(str);
01299 }
01300
01319 String& assign(const String& str, size_type str_idx = 0, size_type str_num = npos)
01320 {
01321 if (str.d_cplength < str_idx)
01322 CEGUI_THROW(std::out_of_range("Index was out of range for CEGUI::String object"));
01323
01324 if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
01325 str_num = str.d_cplength - str_idx;
01326
01327 grow(str_num);
01328 setlen(str_num);
01329 memcpy(ptr(), &str.ptr()[str_idx], str_num * sizeof(utf32));
01330
01331 return *this;
01332 }
01333
01350 String& operator=(const std::string& std_str)
01351 {
01352 return assign(std_str);
01353 }
01354
01378 String& assign(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
01379 {
01380 if (std_str.size() < str_idx)
01381 CEGUI_THROW(std::out_of_range("Index was out of range for std::string object"));
01382
01383 if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
01384 str_num = (size_type)std_str.size() - str_idx;
01385
01386 grow(str_num);
01387 setlen(str_num);
01388
01389 while(str_num--)
01390 {
01391 ((*this)[str_num]) = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num + str_idx]));
01392 }
01393
01394 return *this;
01395 }
01396
01415 String& operator=(const utf8* utf8_str)
01416 {
01417 return assign(utf8_str, utf_length(utf8_str));
01418 }
01419
01438 String& assign(const utf8* utf8_str)
01439 {
01440 return assign(utf8_str, utf_length(utf8_str));
01441 }
01442
01464 String& assign(const utf8* utf8_str, size_type str_num)
01465 {
01466 if (str_num == npos)
01467 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
01468
01469 size_type enc_sze = encoded_size(utf8_str, str_num);
01470
01471 grow(enc_sze);
01472 encode(utf8_str, ptr(), d_reserve, str_num);
01473 setlen(enc_sze);
01474 return *this;
01475 }
01476
01487 String& operator=(utf32 code_point)
01488 {
01489 return assign(1, code_point);
01490 }
01491
01507 String& assign(size_type num, utf32 code_point)
01508 {
01509 if (num == npos)
01510 CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
01511
01512 grow(num);
01513 setlen(num);
01514 utf32* p = ptr();
01515
01516 while(num--)
01517 *p++ = code_point;
01518
01519 return *this;
01520 }
01521
01522
01535 String& operator=(const char* cstr)
01536 {
01537 return assign(cstr, strlen(cstr));
01538 }
01539
01540
01553 String& assign(const char* cstr)
01554 {
01555 return assign(cstr, strlen(cstr));
01556 }
01557
01558
01574 String& assign(const char* chars, size_type chars_len)
01575 {
01576 grow(chars_len);
01577 utf32* pt = ptr();
01578
01579 for (size_type i = 0; i < chars_len; ++i)
01580 {
01581 *pt++ = static_cast<utf32>(static_cast<unsigned char>(*chars++));
01582 }
01583
01584 setlen(chars_len);
01585 return *this;
01586 }
01587
01588
01599 void swap(String& str)
01600 {
01601 size_type temp_len = d_cplength;
01602 d_cplength = str.d_cplength;
01603 str.d_cplength = temp_len;
01604
01605 size_type temp_res = d_reserve;
01606 d_reserve = str.d_reserve;
01607 str.d_reserve = temp_res;
01608
01609 utf32* temp_buf = d_buffer;
01610 d_buffer = str.d_buffer;
01611 str.d_buffer = temp_buf;
01612
01613
01614 if (temp_res <= STR_QUICKBUFF_SIZE)
01615 {
01616 utf32 temp_qbf[STR_QUICKBUFF_SIZE];
01617
01618 memcpy(temp_qbf, d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
01619 memcpy(d_quickbuff, str.d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
01620 memcpy(str.d_quickbuff, temp_qbf, STR_QUICKBUFF_SIZE * sizeof(utf32));
01621 }
01622
01623 }
01624
01626
01628
01640 String& operator+=(const String& str)
01641 {
01642 return append(str);
01643 }
01644
01664 String& append(const String& str, size_type str_idx = 0, size_type str_num = npos)
01665 {
01666 if (str.d_cplength < str_idx)
01667 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
01668
01669 if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
01670 str_num = str.d_cplength - str_idx;
01671
01672 grow(d_cplength + str_num);
01673 memcpy(&ptr()[d_cplength], &str.ptr()[str_idx], str_num * sizeof(utf32));
01674 setlen(d_cplength + str_num);
01675 return *this;
01676 }
01677
01678
01695 String& operator+=(const std::string& std_str)
01696 {
01697 return append(std_str);
01698 }
01699
01723 String& append(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
01724 {
01725 if (std_str.size() < str_idx)
01726 CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
01727
01728 if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
01729 str_num = (size_type)std_str.size() - str_idx;
01730
01731 size_type newsze = d_cplength + str_num;
01732
01733 grow(newsze);
01734 utf32* pt = &ptr()[newsze-1];
01735
01736 while(str_num--)
01737 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num]));
01738
01739 setlen(newsze);
01740 return *this;
01741 }
01742
01743
01762 String& operator+=(const utf8* utf8_str)
01763 {
01764 return append(utf8_str, utf_length(utf8_str));
01765 }
01766
01785 String& append(const utf8* utf8_str)
01786 {
01787 return append(utf8_str, utf_length(utf8_str));
01788 }
01789
01790
01812 String& append(const utf8* utf8_str, size_type len)
01813 {
01814 if (len == npos)
01815 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
01816
01817 size_type encsz = encoded_size(utf8_str, len);
01818 size_type newsz = d_cplength + encsz;
01819
01820 grow(newsz);
01821 encode(utf8_str, &ptr()[d_cplength], encsz, len);
01822 setlen(newsz);
01823
01824 return *this;
01825 }
01826
01827
01840 String& operator+=(utf32 code_point)
01841 {
01842 return append(1, code_point);
01843 }
01844
01860 String& append(size_type num, utf32 code_point)
01861 {
01862 if (num == npos)
01863 CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
01864
01865 size_type newsz = d_cplength + num;
01866 grow(newsz);
01867
01868 utf32* p = &ptr()[d_cplength];
01869
01870 while(num--)
01871 *p++ = code_point;
01872
01873 setlen(newsz);
01874
01875 return *this;
01876 }
01877
01890 void push_back(utf32 code_point)
01891 {
01892 append(1, code_point);
01893 }
01894
01910 String& append(const_iterator iter_beg, const_iterator iter_end)
01911 {
01912 return replace(end(), end(), iter_beg, iter_end);
01913 }
01914
01915
01928 String& operator+=(const char* cstr)
01929 {
01930 return append(cstr, strlen(cstr));
01931 }
01932
01933
01946 String& append(const char* cstr)
01947 {
01948 return append(cstr, strlen(cstr));
01949 }
01950
01951
01967 String& append(const char* chars, size_type chars_len)
01968 {
01969 if (chars_len == npos)
01970 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
01971
01972 size_type newsz = d_cplength + chars_len;
01973
01974 grow(newsz);
01975
01976 utf32* pt = &ptr()[newsz-1];
01977
01978 while(chars_len--)
01979 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
01980
01981 setlen(newsz);
01982
01983 return *this;
01984 }
01985
01986
01988
01990
02006 String& insert(size_type idx, const String& str)
02007 {
02008 return insert(idx, str, 0, npos);
02009 }
02010
02033 String& insert(size_type idx, const String& str, size_type str_idx, size_type str_num)
02034 {
02035 if ((d_cplength < idx) || (str.d_cplength < str_idx))
02036 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02037
02038 if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
02039 str_num = str.d_cplength - str_idx;
02040
02041 size_type newsz = d_cplength + str_num;
02042 grow(newsz);
02043 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02044 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
02045 setlen(newsz);
02046
02047 return *this;
02048 }
02049
02070 String& insert(size_type idx, const std::string& std_str)
02071 {
02072 return insert(idx, std_str, 0, npos);
02073 }
02074
02101 String& insert(size_type idx, const std::string& std_str, size_type str_idx, size_type str_num)
02102 {
02103 if (d_cplength < idx)
02104 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02105
02106 if (std_str.size() < str_idx)
02107 CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
02108
02109 if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
02110 str_num = (size_type)std_str.size() - str_idx;
02111
02112 size_type newsz = d_cplength + str_num;
02113 grow(newsz);
02114
02115 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02116
02117 utf32* pt = &ptr()[idx + str_num - 1];
02118
02119 while(str_num--)
02120 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
02121
02122 setlen(newsz);
02123
02124 return *this;
02125 }
02126
02149 String& insert(size_type idx, const utf8* utf8_str)
02150 {
02151 return insert(idx, utf8_str, utf_length(utf8_str));
02152 }
02153
02179 String& insert(size_type idx, const utf8* utf8_str, size_type len)
02180 {
02181 if (d_cplength < idx)
02182 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02183
02184 if (len == npos)
02185 CEGUI_THROW(std::length_error("Length of utf8 encoded string can not be 'npos'"));
02186
02187 size_type encsz = encoded_size(utf8_str, len);
02188 size_type newsz = d_cplength + encsz;
02189
02190 grow(newsz);
02191 memmove(&ptr()[idx + encsz], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02192 encode(utf8_str, &ptr()[idx], encsz, len);
02193 setlen(newsz);
02194
02195 return *this;
02196 }
02197
02217 String& insert(size_type idx, size_type num, utf32 code_point)
02218 {
02219 if (d_cplength < idx)
02220 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02221
02222 if (num == npos)
02223 CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
02224
02225 size_type newsz = d_cplength + num;
02226 grow(newsz);
02227
02228 memmove(&ptr()[idx + num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02229
02230 utf32* pt = &ptr()[idx + num - 1];
02231
02232 while(num--)
02233 *pt-- = code_point;
02234
02235 setlen(newsz);
02236
02237 return *this;
02238 }
02239
02258 void insert(iterator pos, size_type num, utf32 code_point)
02259 {
02260 insert(safe_iter_dif(pos, begin()), num, code_point);
02261 }
02262
02278 iterator insert(iterator pos, utf32 code_point)
02279 {
02280 insert(pos, 1, code_point);
02281 return pos;
02282 }
02283
02302 void insert(iterator iter_pos, const_iterator iter_beg, const_iterator iter_end)
02303 {
02304 replace(iter_pos, iter_pos, iter_beg, iter_end);
02305 }
02306
02307
02324 String& insert(size_type idx, const char* cstr)
02325 {
02326 return insert(idx, cstr, strlen(cstr));
02327 }
02328
02329
02349 String& insert(size_type idx, const char* chars, size_type chars_len)
02350 {
02351 if (d_cplength < idx)
02352 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02353
02354 if (chars_len == npos)
02355 CEGUI_THROW(std::length_error("Length of char array can not be 'npos'"));
02356
02357 size_type newsz = d_cplength + chars_len;
02358
02359 grow(newsz);
02360 memmove(&ptr()[idx + chars_len], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02361
02362 utf32* pt = &ptr()[idx + chars_len - 1];
02363
02364 while(chars_len--)
02365 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
02366
02367 setlen(newsz);
02368
02369 return *this;
02370 }
02371
02372
02374
02376
02383 void clear(void)
02384 {
02385 setlen(0);
02386 trim();
02387 }
02388
02396 String& erase(void)
02397 {
02398 clear();
02399 return *this;
02400 }
02401
02414 String& erase(size_type idx)
02415 {
02416 return erase(idx, 1);
02417 }
02418
02434 String& erase(size_type idx, size_type len = npos)
02435 {
02436
02437 if (len == 0)
02438 return *this;
02439
02440 if (d_cplength <= idx)
02441 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02442
02443 if (len == npos)
02444 len = d_cplength - idx;
02445
02446 size_type newsz = d_cplength - len;
02447
02448 memmove(&ptr()[idx], &ptr()[idx + len], (d_cplength - idx - len) * sizeof(utf32));
02449 setlen(newsz);
02450 return *this;
02451 }
02452
02463 String& erase(iterator pos)
02464 {
02465 return erase(safe_iter_dif(pos, begin()), 1);
02466 }
02467
02481 String& erase(iterator iter_beg, iterator iter_end)
02482 {
02483 return erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
02484 }
02485
02487
02489
02501 void resize(size_type num)
02502 {
02503 resize(num, utf32());
02504 }
02505
02521 void resize(size_type num, utf32 code_point)
02522 {
02523 if (num < d_cplength)
02524 {
02525 setlen(num);
02526 }
02527 else
02528 {
02529 append(num - d_cplength, code_point);
02530 }
02531
02532 }
02533
02535
02537
02556 String& replace(size_type idx, size_type len, const String& str)
02557 {
02558 return replace(idx, len, str, 0, npos);
02559 }
02560
02582 String& replace(iterator iter_beg, iterator iter_end, const String& str)
02583 {
02584 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), str, 0, npos);
02585 }
02586
02612 String& replace(size_type idx, size_type len, const String& str, size_type str_idx, size_type str_num)
02613 {
02614 if ((d_cplength < idx) || (str.d_cplength < str_idx))
02615 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02616
02617 if (((str_idx + str_num) > str.d_cplength) || (str_num == npos))
02618 str_num = str.d_cplength - str_idx;
02619
02620 if (((len + idx) > d_cplength) || (len == npos))
02621 len = d_cplength - idx;
02622
02623 size_type newsz = d_cplength + str_num - len;
02624
02625 grow(newsz);
02626
02627 if ((idx + len) < d_cplength)
02628 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02629
02630 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
02631 setlen(newsz);
02632
02633 return *this;
02634 }
02635
02636
02660 String& replace(size_type idx, size_type len, const std::string& std_str)
02661 {
02662 return replace(idx, len, std_str, 0, npos);
02663 }
02664
02690 String& replace(iterator iter_beg, iterator iter_end, const std::string& std_str)
02691 {
02692 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), std_str, 0, npos);
02693 }
02694
02724 String& replace(size_type idx, size_type len, const std::string& std_str, size_type str_idx, size_type str_num)
02725 {
02726 if (d_cplength < idx)
02727 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02728
02729 if (std_str.size() < str_idx)
02730 CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
02731
02732 if (((str_idx + str_num) > std_str.size()) || (str_num == npos))
02733 str_num = (size_type)std_str.size() - str_idx;
02734
02735 if (((len + idx) > d_cplength) || (len == npos))
02736 len = d_cplength - idx;
02737
02738 size_type newsz = d_cplength + str_num - len;
02739
02740 grow(newsz);
02741
02742 if ((idx + len) < d_cplength)
02743 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02744
02745 utf32* pt = &ptr()[idx + str_num - 1];
02746
02747 while (str_num--)
02748 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
02749
02750 setlen(newsz);
02751
02752 return *this;
02753 }
02754
02755
02781 String& replace(size_type idx, size_type len, const utf8* utf8_str)
02782 {
02783 return replace(idx, len, utf8_str, utf_length(utf8_str));
02784 }
02785
02813 String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str)
02814 {
02815 return replace(iter_beg, iter_end, utf8_str, utf_length(utf8_str));
02816 }
02817
02846 String& replace(size_type idx, size_type len, const utf8* utf8_str, size_type str_len)
02847 {
02848 if (d_cplength < idx)
02849 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02850
02851 if (str_len == npos)
02852 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
02853
02854 if (((len + idx) > d_cplength) || (len == npos))
02855 len = d_cplength - idx;
02856
02857 size_type encsz = encoded_size(utf8_str, str_len);
02858 size_type newsz = d_cplength + encsz - len;
02859
02860 grow(newsz);
02861
02862 if ((idx + len) < d_cplength)
02863 memmove(&ptr()[idx + encsz], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02864
02865 encode(utf8_str, &ptr()[idx], encsz, str_len);
02866
02867 setlen(newsz);
02868 return *this;
02869 }
02870
02901 String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str, size_type str_len)
02902 {
02903 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), utf8_str, str_len);
02904 }
02905
02928 String& replace(size_type idx, size_type len, size_type num, utf32 code_point)
02929 {
02930 if (d_cplength < idx)
02931 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
02932
02933 if (num == npos)
02934 CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
02935
02936 if (((len + idx) > d_cplength) || (len == npos))
02937 len = d_cplength - idx;
02938
02939 size_type newsz = d_cplength + num - len;
02940
02941 grow(newsz);
02942
02943 if ((idx + len) < d_cplength)
02944 memmove(&ptr()[idx + num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02945
02946 utf32* pt = &ptr()[idx + num - 1];
02947
02948 while (num--)
02949 *pt-- = code_point;
02950
02951 setlen(newsz);
02952
02953 return *this;
02954 }
02955
02980 String& replace(iterator iter_beg, iterator iter_end, size_type num, utf32 code_point)
02981 {
02982 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), num, code_point);
02983 }
02984
02985
03010 String& replace(iterator iter_beg, iterator iter_end, const_iterator iter_newBeg, const_iterator iter_newEnd)
03011 {
03012 if (iter_newBeg == iter_newEnd)
03013 {
03014 erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
03015 }
03016 else
03017 {
03018 size_type str_len = safe_iter_dif(iter_newEnd, iter_newBeg);
03019 size_type idx = safe_iter_dif(iter_beg, begin());
03020 size_type len = safe_iter_dif(iter_end, iter_beg);
03021
03022 if ((len + idx) > d_cplength)
03023 len = d_cplength - idx;
03024
03025 size_type newsz = d_cplength + str_len - len;
03026
03027 grow(newsz);
03028
03029 if ((idx + len) < d_cplength)
03030 memmove(&ptr()[idx + str_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
03031
03032 memcpy(&ptr()[idx], iter_newBeg.d_ptr, str_len * sizeof(utf32));
03033 setlen(newsz);
03034 }
03035
03036 return *this;
03037 }
03038
03039
03059 String& replace(size_type idx, size_type len, const char* cstr)
03060 {
03061 return replace(idx, len, cstr, strlen(cstr));
03062 }
03063
03064
03086 String& replace(iterator iter_beg, iterator iter_end, const char* cstr)
03087 {
03088 return replace(iter_beg, iter_end, cstr, strlen(cstr));
03089 }
03090
03091
03114 String& replace(size_type idx, size_type len, const char* chars, size_type chars_len)
03115 {
03116 if (d_cplength < idx)
03117 CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
03118
03119 if (chars_len == npos)
03120 CEGUI_THROW(std::length_error("Length for the char array can not be 'npos'"));
03121
03122 if (((len + idx) > d_cplength) || (len == npos))
03123 len = d_cplength - idx;
03124
03125 size_type newsz = d_cplength + chars_len - len;
03126
03127 grow(newsz);
03128
03129 if ((idx + len) < d_cplength)
03130 memmove(&ptr()[idx + chars_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
03131
03132 utf32* pt = &ptr()[idx + chars_len - 1];
03133
03134 while (chars_len--)
03135 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
03136
03137 setlen(newsz);
03138 return *this;
03139 }
03140
03141
03166 String& replace(iterator iter_beg, iterator iter_end, const char* chars, size_type chars_len)
03167 {
03168 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), chars, chars_len);
03169 }
03170
03171
03173
03175
03189 size_type find(utf32 code_point, size_type idx = 0) const
03190 {
03191 if (idx < d_cplength)
03192 {
03193 const utf32* pt = &ptr()[idx];
03194
03195 while (idx < d_cplength)
03196 {
03197 if (*pt++ == code_point)
03198 return idx;
03199
03200 ++idx;
03201 }
03202
03203 }
03204
03205 return npos;
03206 }
03207
03222 size_type rfind(utf32 code_point, size_type idx = npos) const
03223 {
03224 if (idx >= d_cplength)
03225 idx = d_cplength - 1;
03226
03227 if (d_cplength > 0)
03228 {
03229 const utf32* pt = &ptr()[idx];
03230
03231 do
03232 {
03233 if (*pt-- == code_point)
03234 return idx;
03235
03236 } while (idx-- != 0);
03237
03238 }
03239
03240 return npos;
03241 }
03242
03244
03246
03260 size_type find(const String& str, size_type idx = 0) const
03261 {
03262 if ((str.d_cplength == 0) && (idx < d_cplength))
03263 return idx;
03264
03265 if (idx < d_cplength)
03266 {
03267
03268 while (d_cplength - idx >= str.d_cplength)
03269 {
03270 if (0 == compare(idx, str.d_cplength, str))
03271 return idx;
03272
03273 ++idx;
03274 }
03275
03276 }
03277
03278 return npos;
03279 }
03280
03295 size_type rfind(const String& str, size_type idx = npos) const
03296 {
03297 if (str.d_cplength == 0)
03298 return (idx < d_cplength) ? idx : d_cplength;
03299
03300 if (str.d_cplength <= d_cplength)
03301 {
03302 if (idx > (d_cplength - str.d_cplength))
03303 idx = d_cplength - str.d_cplength;
03304
03305 do
03306 {
03307 if (0 == compare(idx, str.d_cplength, str))
03308 return idx;
03309
03310 } while (idx-- != 0);
03311
03312 }
03313
03314 return npos;
03315 }
03316
03335 size_type find(const std::string& std_str, size_type idx = 0) const
03336 {
03337 std::string::size_type sze = std_str.size();
03338
03339 if ((sze == 0) && (idx < d_cplength))
03340 return idx;
03341
03342 if (idx < d_cplength)
03343 {
03344
03345 while (d_cplength - idx >= sze)
03346 {
03347 if (0 == compare(idx, (size_type)sze, std_str))
03348 return idx;
03349
03350 ++idx;
03351 }
03352
03353 }
03354
03355 return npos;
03356 }
03357
03376 size_type rfind(const std::string& std_str, size_type idx = npos) const
03377 {
03378 std::string::size_type sze = std_str.size();
03379
03380 if (sze == 0)
03381 return (idx < d_cplength) ? idx : d_cplength;
03382
03383 if (sze <= d_cplength)
03384 {
03385 if (idx > (d_cplength - sze))
03386 idx = d_cplength - sze;
03387
03388 do
03389 {
03390 if (0 == compare(idx, (size_type)sze, std_str))
03391 return idx;
03392
03393 } while (idx-- != 0);
03394
03395 }
03396
03397 return npos;
03398 }
03399
03422 size_type find(const utf8* utf8_str, size_type idx = 0) const
03423 {
03424 return find(utf8_str, idx, utf_length(utf8_str));
03425 }
03426
03449 size_type rfind(const utf8* utf8_str, size_type idx = npos) const
03450 {
03451 return rfind(utf8_str, idx, utf_length(utf8_str));
03452 }
03453
03479 size_type find(const utf8* utf8_str, size_type idx, size_type str_len) const
03480 {
03481 if (str_len == npos)
03482 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
03483
03484 size_type sze = encoded_size(utf8_str, str_len);
03485
03486 if ((sze == 0) && (idx < d_cplength))
03487 return idx;
03488
03489 if (idx < d_cplength)
03490 {
03491
03492 while (d_cplength - idx >= sze)
03493 {
03494 if (0 == compare(idx, sze, utf8_str, sze))
03495 return idx;
03496
03497 ++idx;
03498 }
03499
03500 }
03501
03502 return npos;
03503 }
03504
03530 size_type rfind(const utf8* utf8_str, size_type idx, size_type str_len) const
03531 {
03532 if (str_len == npos)
03533 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
03534
03535 size_type sze = encoded_size(utf8_str, str_len);
03536
03537 if (sze == 0)
03538 return (idx < d_cplength) ? idx : d_cplength;
03539
03540 if (sze <= d_cplength)
03541 {
03542 if (idx > (d_cplength - sze))
03543 idx = d_cplength - sze;
03544
03545 do
03546 {
03547 if (0 == compare(idx, sze, utf8_str, sze))
03548 return idx;
03549
03550 } while (idx-- != 0);
03551
03552 }
03553
03554 return npos;
03555 }
03556
03557
03574 size_type find(const char* cstr, size_type idx = 0) const
03575 {
03576 return find(cstr, idx, strlen(cstr));
03577 }
03578
03579
03596 size_type rfind(const char* cstr, size_type idx = npos) const
03597 {
03598 return rfind(cstr, idx, strlen(cstr));
03599 }
03600
03601
03621 size_type find(const char* chars, size_type idx, size_type chars_len) const
03622 {
03623 if (chars_len == npos)
03624 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
03625
03626 if ((chars_len == 0) && (idx < d_cplength))
03627 return idx;
03628
03629 if (idx < d_cplength)
03630 {
03631
03632 while (d_cplength - idx >= chars_len)
03633 {
03634 if (0 == compare(idx, chars_len, chars, chars_len))
03635 return idx;
03636
03637 ++idx;
03638 }
03639
03640 }
03641
03642 return npos;
03643 }
03644
03645
03665 size_type rfind(const char* chars, size_type idx, size_type chars_len) const
03666 {
03667 if (chars_len == npos)
03668 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
03669
03670 if (chars_len == 0)
03671 return (idx < d_cplength) ? idx : d_cplength;
03672
03673 if (chars_len <= d_cplength)
03674 {
03675 if (idx > (d_cplength - chars_len))
03676 idx = d_cplength - chars_len;
03677
03678 do
03679 {
03680 if (0 == compare(idx, chars_len, chars, chars_len))
03681 return idx;
03682
03683 } while (idx-- != 0);
03684
03685 }
03686
03687 return npos;
03688 }
03689
03690
03692
03694
03708 size_type find_first_of(const String& str, size_type idx = 0) const
03709 {
03710 if (idx < d_cplength)
03711 {
03712 const utf32* pt = &ptr()[idx];
03713
03714 do
03715 {
03716 if (npos != str.find(*pt++))
03717 return idx;
03718
03719 } while (++idx != d_cplength);
03720
03721 }
03722
03723 return npos;
03724 }
03725
03740 size_type find_first_not_of(const String& str, size_type idx = 0) const
03741 {
03742 if (idx < d_cplength)
03743 {
03744 const utf32* pt = &ptr()[idx];
03745
03746 do
03747 {
03748 if (npos == str.find(*pt++))
03749 return idx;
03750
03751 } while (++idx != d_cplength);
03752
03753 }
03754
03755 return npos;
03756 }
03757
03758
03777 size_type find_first_of(const std::string& std_str, size_type idx = 0) const
03778 {
03779 if (idx < d_cplength)
03780 {
03781 const utf32* pt = &ptr()[idx];
03782
03783 do
03784 {
03785 if (npos != find_codepoint(std_str, *pt++))
03786 return idx;
03787
03788 } while (++idx != d_cplength);
03789
03790 }
03791
03792 return npos;
03793 }
03794
03813 size_type find_first_not_of(const std::string& std_str, size_type idx = 0) const
03814 {
03815 if (idx < d_cplength)
03816 {
03817 const utf32* pt = &ptr()[idx];
03818
03819 do
03820 {
03821 if (npos == find_codepoint(std_str, *pt++))
03822 return idx;
03823
03824 } while (++idx != d_cplength);
03825
03826 }
03827
03828 return npos;
03829 }
03830
03831
03854 size_type find_first_of(const utf8* utf8_str, size_type idx = 0) const
03855 {
03856 return find_first_of(utf8_str, idx, utf_length(utf8_str));
03857 }
03858
03881 size_type find_first_not_of(const utf8* utf8_str, size_type idx = 0) const
03882 {
03883 return find_first_not_of(utf8_str, idx, utf_length(utf8_str));
03884 }
03885
03911 size_type find_first_of(const utf8* utf8_str, size_type idx, size_type str_len) const
03912 {
03913 if (str_len == npos)
03914 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
03915
03916 if (idx < d_cplength)
03917 {
03918 size_type encsze = encoded_size(utf8_str, str_len);
03919
03920 const utf32* pt = &ptr()[idx];
03921
03922 do
03923 {
03924 if (npos != find_codepoint(utf8_str, encsze, *pt++))
03925 return idx;
03926
03927 } while (++idx != d_cplength);
03928
03929 }
03930
03931 return npos;
03932 }
03933
03959 size_type find_first_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
03960 {
03961 if (str_len == npos)
03962 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
03963
03964 if (idx < d_cplength)
03965 {
03966 size_type encsze = encoded_size(utf8_str, str_len);
03967
03968 const utf32* pt = &ptr()[idx];
03969
03970 do
03971 {
03972 if (npos == find_codepoint(utf8_str, encsze, *pt++))
03973 return idx;
03974
03975 } while (++idx != d_cplength);
03976
03977 }
03978
03979 return npos;
03980 }
03981
03982
03997 size_type find_first_of(utf32 code_point, size_type idx = 0) const
03998 {
03999 return find(code_point, idx);
04000 }
04001
04018 size_type find_first_not_of(utf32 code_point, size_type idx = 0) const
04019 {
04020 if (idx < d_cplength)
04021 {
04022 do
04023 {
04024 if ((*this)[idx] != code_point)
04025 return idx;
04026
04027 } while(idx++ < d_cplength);
04028
04029 }
04030
04031 return npos;
04032 }
04033
04034
04051 size_type find_first_of(const char* cstr, size_type idx = 0) const
04052 {
04053 return find_first_of(cstr, idx, strlen(cstr));
04054 }
04055
04056
04073 size_type find_first_not_of(const char* cstr, size_type idx = 0) const
04074 {
04075 return find_first_not_of(cstr, idx, strlen(cstr));
04076 }
04077
04078
04098 size_type find_first_of(const char* chars, size_type idx, size_type chars_len) const
04099 {
04100 if (chars_len == npos)
04101 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
04102
04103 if (idx < d_cplength)
04104 {
04105 const utf32* pt = &ptr()[idx];
04106
04107 do
04108 {
04109 if (npos != find_codepoint(chars, chars_len, *pt++))
04110 return idx;
04111
04112 } while (++idx != d_cplength);
04113
04114 }
04115
04116 return npos;
04117 }
04118
04119
04139 size_type find_first_not_of(const char* chars, size_type idx, size_type chars_len) const
04140 {
04141 if (chars_len == npos)
04142 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
04143
04144 if (idx < d_cplength)
04145 {
04146 const utf32* pt = &ptr()[idx];
04147
04148 do
04149 {
04150 if (npos == find_codepoint(chars, chars_len, *pt++))
04151 return idx;
04152
04153 } while (++idx != d_cplength);
04154
04155 }
04156
04157 return npos;
04158 }
04159
04160
04162
04164
04178 size_type find_last_of(const String& str, size_type idx = npos) const
04179 {
04180 if (d_cplength > 0)
04181 {
04182 if (idx >= d_cplength)
04183 idx = d_cplength - 1;
04184
04185 const utf32* pt = &ptr()[idx];
04186
04187 do
04188 {
04189 if (npos != str.find(*pt--))
04190 return idx;
04191
04192 } while (idx-- != 0);
04193
04194 }
04195
04196 return npos;
04197 }
04198
04213 size_type find_last_not_of(const String& str, size_type idx = npos) const
04214 {
04215 if (d_cplength > 0)
04216 {
04217 if (idx >= d_cplength)
04218 idx = d_cplength - 1;
04219
04220 const utf32* pt = &ptr()[idx];
04221
04222 do
04223 {
04224 if (npos == str.find(*pt--))
04225 return idx;
04226
04227 } while (idx-- != 0);
04228
04229 }
04230
04231 return npos;
04232 }
04233
04234
04253 size_type find_last_of(const std::string& std_str, size_type idx = npos) const
04254 {
04255 if (d_cplength > 0)
04256 {
04257 if (idx >= d_cplength)
04258 idx = d_cplength - 1;
04259
04260 const utf32* pt = &ptr()[idx];
04261
04262 do
04263 {
04264 if (npos != find_codepoint(std_str, *pt--))
04265 return idx;
04266
04267 } while (idx-- != 0);
04268
04269 }
04270
04271 return npos;
04272 }
04273
04292 size_type find_last_not_of(const std::string& std_str, size_type idx = npos) const
04293 {
04294 if (d_cplength > 0)
04295 {
04296 if (idx >= d_cplength)
04297 idx = d_cplength - 1;
04298
04299 const utf32* pt = &ptr()[idx];
04300
04301 do
04302 {
04303 if (npos == find_codepoint(std_str, *pt--))
04304 return idx;
04305
04306 } while (idx-- != 0);
04307
04308 }
04309
04310 return npos;
04311 }
04312
04313
04336 size_type find_last_of(const utf8* utf8_str, size_type idx = npos) const
04337 {
04338 return find_last_of(utf8_str, idx, utf_length(utf8_str));
04339 }
04340
04363 size_type find_last_not_of(const utf8* utf8_str, size_type idx = npos) const
04364 {
04365 return find_last_not_of(utf8_str, idx, utf_length(utf8_str));
04366 }
04367
04393 size_type find_last_of(const utf8* utf8_str, size_type idx, size_type str_len) const
04394 {
04395 if (str_len == npos)
04396 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
04397
04398 if (d_cplength > 0)
04399 {
04400 if (idx >= d_cplength)
04401 idx = d_cplength - 1;
04402
04403 size_type encsze = encoded_size(utf8_str, str_len);
04404
04405 const utf32* pt = &ptr()[idx];
04406
04407 do
04408 {
04409 if (npos != find_codepoint(utf8_str, encsze, *pt--))
04410 return idx;
04411
04412 } while (idx-- != 0);
04413
04414 }
04415
04416 return npos;
04417 }
04418
04444 size_type find_last_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
04445 {
04446 if (str_len == npos)
04447 CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
04448
04449 if (d_cplength > 0)
04450 {
04451 if (idx >= d_cplength)
04452 idx = d_cplength - 1;
04453
04454 size_type encsze = encoded_size(utf8_str, str_len);
04455
04456 const utf32* pt = &ptr()[idx];
04457
04458 do
04459 {
04460 if (npos == find_codepoint(utf8_str, encsze, *pt--))
04461 return idx;
04462
04463 } while (idx-- != 0);
04464
04465 }
04466
04467 return npos;
04468 }
04469
04470
04485 size_type find_last_of(utf32 code_point, size_type idx = npos) const
04486 {
04487 return rfind(code_point, idx);
04488 }
04489
04504 size_type find_last_not_of(utf32 code_point, size_type idx = npos) const
04505 {
04506 if (d_cplength > 0)
04507 {
04508 if (idx >= d_cplength)
04509 idx = d_cplength - 1;
04510
04511 do
04512 {
04513 if ((*this)[idx] != code_point)
04514 return idx;
04515
04516 } while(idx-- != 0);
04517
04518 }
04519
04520 return npos;
04521 }
04522
04523
04540 size_type find_last_of(const char* cstr, size_type idx = npos) const
04541 {
04542 return find_last_of(cstr, idx, strlen(cstr));
04543 }
04544
04545
04562 size_type find_last_not_of(const char* cstr, size_type idx = npos) const
04563 {
04564 return find_last_not_of(cstr, idx, strlen(cstr));
04565 }
04566
04567
04587 size_type find_last_of(const char* chars, size_type idx, size_type chars_len) const
04588 {
04589 if (chars_len == npos)
04590 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
04591
04592 if (d_cplength > 0)
04593 {
04594 if (idx >= d_cplength)
04595 idx = d_cplength - 1;
04596
04597 const utf32* pt = &ptr()[idx];
04598
04599 do
04600 {
04601 if (npos != find_codepoint(chars, chars_len, *pt--))
04602 return idx;
04603
04604 } while (idx-- != 0);
04605
04606 }
04607
04608 return npos;
04609 }
04610
04611
04631 size_type find_last_not_of(const char* chars, size_type idx, size_type chars_len) const
04632 {
04633 if (chars_len == npos)
04634 CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
04635
04636 if (d_cplength > 0)
04637 {
04638 if (idx >= d_cplength)
04639 idx = d_cplength - 1;
04640
04641 const utf32* pt = &ptr()[idx];
04642
04643 do
04644 {
04645 if (npos == find_codepoint(chars, chars_len, *pt--))
04646 return idx;
04647
04648 } while (idx-- != 0);
04649
04650 }
04651
04652 return npos;
04653 }
04654
04655
04657
04659
04674 String substr(size_type idx = 0, size_type len = npos) const
04675 {
04676 if (d_cplength < idx)
04677 CEGUI_THROW(std::out_of_range("Index is out of range for this CEGUI::String"));
04678
04679 return String(*this, idx, len);
04680 }
04681
04683
04685
04692 iterator begin(void)
04693 {
04694 return iterator(ptr());
04695 }
04696
04704 const_iterator begin(void) const
04705 {
04706 return const_iterator(ptr());
04707 }
04708
04716 iterator end(void)
04717 {
04718 return iterator(&ptr()[d_cplength]);
04719 }
04720
04728 const_iterator end(void) const
04729 {
04730 return const_iterator(&ptr()[d_cplength]);
04731 }
04732
04740 reverse_iterator rbegin(void)
04741 {
04742 return reverse_iterator(end());
04743 }
04744
04752 const_reverse_iterator rbegin(void) const
04753 {
04754 return const_reverse_iterator(end());
04755 }
04756
04764 reverse_iterator rend(void)
04765 {
04766 return reverse_iterator(begin());
04767 }
04768
04776 const_reverse_iterator rend(void) const
04777 {
04778 return const_reverse_iterator(begin());
04779 }
04780
04781 private:
04782
04783
04784
04785
04786
04787
04788
04789
04790 bool grow(size_type new_size);
04791
04792
04793 void trim(void);
04794
04795
04796 void setlen(size_type len)
04797 {
04798 d_cplength = len;
04799 ptr()[len] = (utf32)(0);
04800 }
04801
04802
04803 void init(void)
04804 {
04805 d_reserve = STR_QUICKBUFF_SIZE;
04806 d_encodedbuff = 0;
04807 d_encodedbufflen = 0;
04808 d_encodeddatlen = 0;
04809 d_buffer = 0;
04810 setlen(0);
04811 }
04812
04813
04814 bool inside(utf32* inptr)
04815 {
04816 if (inptr < ptr() || ptr() + d_cplength <= inptr)
04817 return false;
04818 else
04819 return true;
04820 }
04821
04822
04823 size_type safe_iter_dif(const const_iterator& iter1, const const_iterator& iter2) const
04824 {
04825 return (iter1.d_ptr == 0) ? 0 : (iter1 - iter2);
04826 }
04827
04828
04829
04830
04831
04832
04833 size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
04834 {
04835
04836 if (src_len == 0)
04837 {
04838 src_len = utf_length(src);
04839 }
04840
04841 size_type destCapacity = dest_len;
04842
04843
04844 for (uint idx = 0; idx < src_len; ++idx)
04845 {
04846 utf32 cp = src[idx];
04847
04848
04849 if (destCapacity < encoded_size(cp))
04850 {
04851 break;
04852 }
04853
04854 if (cp < 0x80)
04855 {
04856 *dest++ = (utf8)cp;
04857 --destCapacity;
04858 }
04859 else if (cp < 0x0800)
04860 {
04861 *dest++ = (utf8)((cp >> 6) | 0xC0);
04862 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04863 destCapacity -= 2;
04864 }
04865 else if (cp < 0x10000)
04866 {
04867 *dest++ = (utf8)((cp >> 12) | 0xE0);
04868 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
04869 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04870 destCapacity -= 3;
04871 }
04872 else
04873 {
04874 *dest++ = (utf8)((cp >> 18) | 0xF0);
04875 *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
04876 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
04877 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04878 destCapacity -= 4;
04879 }
04880
04881 }
04882
04883 return dest_len - destCapacity;
04884 }
04885
04886 size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
04887 {
04888
04889 if (src_len == 0)
04890 {
04891 src_len = utf_length(src);
04892 }
04893
04894 size_type destCapacity = dest_len;
04895
04896
04897 for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
04898 {
04899 utf32 cp;
04900 utf8 cu = src[idx++];
04901
04902 if (cu < 0x80)
04903 {
04904 cp = (utf32)(cu);
04905 }
04906 else if (cu < 0xE0)
04907 {
04908 cp = ((cu & 0x1F) << 6);
04909 cp |= (src[idx++] & 0x3F);
04910 }
04911 else if (cu < 0xF0)
04912 {
04913 cp = ((cu & 0x0F) << 12);
04914 cp |= ((src[idx++] & 0x3F) << 6);
04915 cp |= (src[idx++] & 0x3F);
04916 }
04917 else
04918 {
04919 cp = ((cu & 0x07) << 18);
04920 cp |= ((src[idx++] & 0x3F) << 12);
04921 cp |= ((src[idx++] & 0x3F) << 6);
04922 cp |= (src[idx++] & 0x3F);
04923 }
04924
04925 *dest++ = cp;
04926 --destCapacity;
04927 }
04928
04929 return dest_len - destCapacity;
04930 }
04931
04932
04933 size_type encoded_size(utf32 code_point) const
04934 {
04935 if (code_point < 0x80)
04936 return 1;
04937 else if (code_point < 0x0800)
04938 return 2;
04939 else if (code_point < 0x10000)
04940 return 3;
04941 else
04942 return 4;
04943 }
04944
04945
04946 size_type encoded_size(const utf32* buf) const
04947 {
04948 return encoded_size(buf, utf_length(buf));
04949 }
04950
04951
04952 size_type encoded_size(const utf32* buf, size_type len) const
04953 {
04954 size_type count = 0;
04955
04956 while (len--)
04957 {
04958 count += encoded_size(*buf++);
04959 }
04960
04961 return count;
04962 }
04963
04964
04965 size_type encoded_size(const utf8* buf) const
04966 {
04967 return encoded_size(buf, utf_length(buf));
04968 }
04969
04970
04971 size_type encoded_size(const utf8* buf, size_type len) const
04972 {
04973 utf8 tcp;
04974 size_type count = 0;
04975
04976 while (len--)
04977 {
04978 tcp = *buf++;
04979 ++count;
04980 size_type size = 0;
04981
04982 if (tcp < 0x80)
04983 {
04984 }
04985 else if (tcp < 0xE0)
04986 {
04987 size = 1;
04988 ++buf;
04989 }
04990 else if (tcp < 0xF0)
04991 {
04992 size = 2;
04993 buf += 2;
04994 }
04995 else
04996 {
04997 size = 3;
04998 buf += 3;
04999 }
05000
05001 if (len >= size)
05002 len -= size;
05003 else
05004 break;
05005 }
05006
05007 return count;
05008 }
05009
05010
05011 size_type utf_length(const utf8* utf8_str) const
05012 {
05013 size_type cnt = 0;
05014 while (*utf8_str++)
05015 cnt++;
05016
05017 return cnt;
05018 }
05019
05020
05021 size_type utf_length(const utf32* utf32_str) const
05022 {
05023 size_type cnt = 0;
05024 while (*utf32_str++)
05025 cnt++;
05026
05027 return cnt;
05028 }
05029
05030
05031 utf8* build_utf8_buff(void) const;
05032
05033
05034 int utf32_comp_utf32(const utf32* buf1, const utf32* buf2, size_type cp_count) const
05035 {
05036 if (!cp_count)
05037 return 0;
05038
05039 while ((--cp_count) && (*buf1 == *buf2))
05040 buf1++, buf2++;
05041
05042 return *buf1 - *buf2;
05043 }
05044
05045
05046 int utf32_comp_char(const utf32* buf1, const char* buf2, size_type cp_count) const
05047 {
05048 if (!cp_count)
05049 return 0;
05050
05051 while ((--cp_count) && (*buf1 == static_cast<utf32>(static_cast<unsigned char>(*buf2))))
05052 buf1++, buf2++;
05053
05054 return *buf1 - static_cast<utf32>(static_cast<unsigned char>(*buf2));
05055 }
05056
05057
05058 int utf32_comp_utf8(const utf32* buf1, const utf8* buf2, size_type cp_count) const
05059 {
05060 if (!cp_count)
05061 return 0;
05062
05063 utf32 cp;
05064 utf8 cu;
05065
05066 do
05067 {
05068 cu = *buf2++;
05069
05070 if (cu < 0x80)
05071 {
05072 cp = (utf32)(cu);
05073 }
05074 else if (cu < 0xE0)
05075 {
05076 cp = ((cu & 0x1F) << 6);
05077 cp |= (*buf2++ & 0x3F);
05078 }
05079 else if (cu < 0xF0)
05080 {
05081 cp = ((cu & 0x0F) << 12);
05082 cp |= ((*buf2++ & 0x3F) << 6);
05083 cp |= (*buf2++ & 0x3F);
05084 }
05085 else
05086 {
05087 cp = ((cu & 0x07) << 18);
05088 cp |= ((*buf2++ & 0x3F) << 12);
05089 cp |= ((*buf2++ & 0x3F) << 6);
05090 cp |= (*buf2++ & 0x3F);
05091 }
05092
05093 } while ((*buf1++ == cp) && (--cp_count));
05094
05095 return (*--buf1) - cp;
05096 }
05097
05098
05099 size_type find_codepoint(const std::string& str, utf32 code_point) const
05100 {
05101 size_type idx = 0, sze = (size_type)str.size();
05102
05103 while (idx != sze)
05104 {
05105 if (code_point == static_cast<utf32>(static_cast<unsigned char>(str[idx])))
05106 return idx;
05107
05108 ++idx;
05109 }
05110
05111 return npos;
05112 }
05113
05114
05115 size_type find_codepoint(const utf8* str, size_type len, utf32 code_point) const
05116 {
05117 size_type idx = 0;
05118
05119 utf32 cp;
05120 utf8 cu;
05121
05122 while (idx != len) {
05123 cu = *str++;
05124
05125 if (cu < 0x80)
05126 {
05127 cp = (utf32)(cu);
05128 }
05129 else if (cu < 0xE0)
05130 {
05131 cp = ((cu & 0x1F) << 6);
05132 cp |= (*str++ & 0x3F);
05133 }
05134 else if (cu < 0xF0)
05135 {
05136 cp = ((cu & 0x0F) << 12);
05137 cp |= ((*str++ & 0x3F) << 6);
05138 cp |= (*str++ & 0x3F);
05139 }
05140 else
05141 {
05142 cp = ((cu & 0x07) << 18);
05143 cp |= ((*str++ & 0x3F) << 12);
05144 cp |= ((*str++ & 0x3F) << 6);
05145 cp |= (*str++ & 0x3F);
05146 }
05147
05148 if (code_point == cp)
05149 return idx;
05150
05151 ++idx;
05152 }
05153
05154 return npos;
05155 }
05156
05157
05158
05159 size_type find_codepoint(const char* chars, size_type chars_len, utf32 code_point) const
05160 {
05161 for (size_type idx = 0; idx != chars_len; ++idx)
05162 {
05163 if (code_point == static_cast<utf32>(static_cast<unsigned char>(chars[idx])))
05164 return idx;
05165 }
05166
05167 return npos;
05168 }
05169
05170 };
05171
05172
05174
05176
05180 bool CEGUIEXPORT operator==(const String& str1, const String& str2);
05181
05186 bool CEGUIEXPORT operator==(const String& str, const std::string& std_str);
05187
05192 bool CEGUIEXPORT operator==(const std::string& std_str, const String& str);
05193
05198 bool CEGUIEXPORT operator==(const String& str, const utf8* utf8_str);
05199
05204 bool CEGUIEXPORT operator==(const utf8* utf8_str, const String& str);
05205
05210 bool CEGUIEXPORT operator!=(const String& str1, const String& str2);
05211
05216 bool CEGUIEXPORT operator!=(const String& str, const std::string& std_str);
05217
05222 bool CEGUIEXPORT operator!=(const std::string& std_str, const String& str);
05223
05228 bool CEGUIEXPORT operator!=(const String& str, const utf8* utf8_str);
05229
05234 bool CEGUIEXPORT operator!=(const utf8* utf8_str, const String& str);
05235
05240 bool CEGUIEXPORT operator<(const String& str1, const String& str2);
05241
05246 bool CEGUIEXPORT operator<(const String& str, const std::string& std_str);
05247
05252 bool CEGUIEXPORT operator<(const std::string& std_str, const String& str);
05253
05258 bool CEGUIEXPORT operator<(const String& str, const utf8* utf8_str);
05259
05264 bool CEGUIEXPORT operator<(const utf8* utf8_str, const String& str);
05265
05270 bool CEGUIEXPORT operator>(const String& str1, const String& str2);
05271
05276 bool CEGUIEXPORT operator>(const String& str, const std::string& std_str);
05277
05282 bool CEGUIEXPORT operator>(const std::string& std_str, const String& str);
05283
05288 bool CEGUIEXPORT operator>(const String& str, const utf8* utf8_str);
05289
05294 bool CEGUIEXPORT operator>(const utf8* utf8_str, const String& str);
05295
05300 bool CEGUIEXPORT operator<=(const String& str1, const String& str2);
05301
05306 bool CEGUIEXPORT operator<=(const String& str, const std::string& std_str);
05307
05312 bool CEGUIEXPORT operator<=(const std::string& std_str, const String& str);
05313
05318 bool CEGUIEXPORT operator<=(const String& str, const utf8* utf8_str);
05319
05324 bool CEGUIEXPORT operator<=(const utf8* utf8_str, const String& str);
05325
05330 bool CEGUIEXPORT operator>=(const String& str1, const String& str2);
05331
05336 bool CEGUIEXPORT operator>=(const String& str, const std::string& std_str);
05337
05342 bool CEGUIEXPORT operator>=(const std::string& std_str, const String& str);
05343
05348 bool CEGUIEXPORT operator>=(const String& str, const utf8* utf8_str);
05349
05354 bool CEGUIEXPORT operator>=(const utf8* utf8_str, const String& str);
05355
05360 bool CEGUIEXPORT operator==(const String& str, const char* c_str);
05361
05366 bool CEGUIEXPORT operator==(const char* c_str, const String& str);
05367
05372 bool CEGUIEXPORT operator!=(const String& str, const char* c_str);
05373
05378 bool CEGUIEXPORT operator!=(const char* c_str, const String& str);
05379
05384 bool CEGUIEXPORT operator<(const String& str, const char* c_str);
05385
05390 bool CEGUIEXPORT operator<(const char* c_str, const String& str);
05391
05396 bool CEGUIEXPORT operator>(const String& str, const char* c_str);
05397
05402 bool CEGUIEXPORT operator>(const char* c_str, const String& str);
05403
05408 bool CEGUIEXPORT operator<=(const String& str, const char* c_str);
05409
05414 bool CEGUIEXPORT operator<=(const char* c_str, const String& str);
05415
05420 bool CEGUIEXPORT operator>=(const String& str, const char* c_str);
05421
05426 bool CEGUIEXPORT operator>=(const char* c_str, const String& str);
05427
05429
05431
05446 String CEGUIEXPORT operator+(const String& str1, const String& str2);
05447
05463 String CEGUIEXPORT operator+(const String& str, const std::string& std_str);
05464
05480 String CEGUIEXPORT operator+(const std::string& std_str, const String& str);
05481
05497 String CEGUIEXPORT operator+(const String& str, const utf8* utf8_str);
05498
05514 String CEGUIEXPORT operator+(const utf8* utf8_str, const String& str);
05515
05531 String CEGUIEXPORT operator+(const String& str, utf32 code_point);
05532
05548 String CEGUIEXPORT operator+(utf32 code_point, const String& str);
05549
05565 String CEGUIEXPORT operator+(const String& str, const char* c_str);
05566
05582 String CEGUIEXPORT operator+(const char* c_str, const String& str);
05583
05584
05586
05588 CEGUIEXPORT std::ostream& operator<<(std::ostream& s, const String& str);
05589
05590
05592
05594
05607 void CEGUIEXPORT swap(String& str1, String& str2);
05608
05609
05610 }
05611
05612
05613 #endif // end of guard _CEGUIString_h_