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 #ifndef _CEGUIString_h_
00027 #define _CEGUIString_h_
00028
00029 #include "CEGUIBase.h"
00030 #include <string>
00031 #include <string.h>
00032 #include <stdexcept>
00033
00034
00035 namespace CEGUI
00036 {
00037 #define STR_QUICKBUFF_SIZE 32
00038
00039
00040
00041 typedef uchar utf8;
00042
00043 typedef ulong utf32;
00044
00053 class CEGUIBASE_API String
00054 {
00055 public:
00056
00057
00058
00059 typedef utf32 value_type;
00060 typedef uint size_type;
00061 typedef ptrdiff_t difference_type;
00062 typedef utf32& reference;
00063 typedef const utf32& const_reference;
00064 typedef utf32* pointer;
00065 typedef const utf32* const_pointer;
00066
00067 static const size_type npos;
00068
00069 private:
00070
00071
00072
00073 size_type d_cplength;
00074 size_type d_reserve;
00075
00076 mutable utf8* d_encodedbuff;
00077 mutable size_type d_encodeddatlen;
00078 mutable size_type d_encodedbufflen;
00079
00080 utf32 d_quickbuff[STR_QUICKBUFF_SIZE];
00081 utf32* d_buffer;
00082
00083 public:
00084
00085
00086
00091 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00092 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32>
00093 #else
00094 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32, std::ptrdiff_t, const utf32*, const utf32&>
00095 #endif
00096 {
00097
00098 public:
00100
00102 const utf32* d_ptr;
00103
00104
00106
00108 const_iterator(void)
00109 {
00110 d_ptr = 0;
00111 }
00112 const_iterator(const_pointer ptr)
00113 {
00114 d_ptr = ptr;
00115 }
00116
00117 const_reference operator*() const
00118 {
00119 return *d_ptr;
00120 }
00121
00122 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00123 # pragma warning (push)
00124 # pragma warning (disable : 4284)
00125 #endif
00126 const_pointer operator->() const
00127 {
00128 return &**this;
00129 }
00130
00131 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00132 # pragma warning (pop)
00133 #endif
00134
00135 const_iterator& operator++()
00136 {
00137 ++d_ptr;
00138 return *this;
00139 }
00140
00141 const_iterator operator++(int)
00142 {
00143 const_iterator temp = *this;
00144 ++*this;
00145 return temp;
00146 }
00147
00148 const_iterator& operator--()
00149 {
00150 --d_ptr;
00151 return *this;
00152 }
00153
00154 const_iterator operator--(int)
00155 {
00156 const_iterator temp = *this;
00157 --*this;
00158 return temp;
00159 }
00160
00161 const_iterator& operator+=(difference_type offset)
00162 {
00163 d_ptr += offset;
00164 return *this;
00165 }
00166
00167 const_iterator operator+(difference_type offset) const
00168 {
00169 const_iterator temp = *this;
00170 return temp += offset;
00171 }
00172
00173 const_iterator& operator-=(difference_type offset)
00174 {
00175 return *this += -offset;
00176 }
00177
00178 const_iterator operator-(difference_type offset) const
00179 {
00180 const_iterator temp = *this;
00181 return temp -= offset;
00182 }
00183
00184 difference_type operator-(const const_iterator& iter) const
00185 {
00186 return d_ptr - iter.d_ptr;
00187 }
00188
00189 const_reference operator[](difference_type offset) const
00190 {
00191 return *(*this + offset);
00192 }
00193
00194 bool operator==(const const_iterator& iter) const
00195 {
00196 return d_ptr == iter.d_ptr;
00197 }
00198
00199 bool operator!=(const const_iterator& iter) const
00200 {
00201 return !(*this == iter);
00202 }
00203
00204 bool operator<(const const_iterator& iter) const
00205 {
00206 return d_ptr < iter.d_ptr;
00207 }
00208
00209 bool operator>(const const_iterator& iter) const
00210 {
00211 return (!(iter < *this));
00212 }
00213
00214 bool operator<=(const const_iterator& iter) const
00215 {
00216 return (!(iter < *this));
00217 }
00218
00219 bool operator>=(const const_iterator& iter) const
00220 {
00221 return (!(*this < iter));
00222 }
00223
00224 friend const_iterator operator+(difference_type offset, const const_iterator& iter)
00225 {
00226 return iter + offset;
00227 }
00228
00229 };
00230
00235 class iterator : public const_iterator
00236 {
00237 public:
00238 iterator(void) {}
00239 iterator(pointer ptr) : const_iterator(ptr) {}
00240
00241
00242 reference operator*() const
00243 {
00244 return ((reference)**(const_iterator *)this);
00245 }
00246
00247 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00248 # pragma warning (push)
00249 # pragma warning (disable : 4284)
00250 #endif
00251
00252 pointer operator->() const
00253 {
00254 return &**this;
00255 }
00256
00257 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00258 # pragma warning (pop)
00259 #endif
00260
00261 iterator& operator++()
00262 {
00263 ++this->d_ptr;
00264 return *this;
00265 }
00266
00267 iterator operator++(int)
00268 {
00269 iterator temp = *this;
00270 ++*this;
00271 return temp;
00272 }
00273
00274 iterator& operator--()
00275 {
00276 --this->d_ptr;
00277 return *this;
00278 }
00279
00280 iterator operator--(int)
00281 {
00282 iterator temp = *this;
00283 --*this;
00284 return temp;
00285 }
00286
00287 iterator& operator+=(difference_type offset)
00288 {
00289 this->d_ptr += offset;
00290 return *this;
00291 }
00292
00293 iterator operator+(difference_type offset) const
00294 {
00295 iterator temp = *this;
00296 return temp + offset;
00297 }
00298
00299 iterator& operator-=(difference_type offset)
00300 {
00301 return *this += -offset;
00302 }
00303
00304 iterator operator-(difference_type offset) const
00305 {
00306 iterator temp = *this;
00307 return temp -= offset;
00308 }
00309
00310 difference_type operator-(const const_iterator& iter) const
00311 {
00312 return ((const_iterator)*this - iter);
00313 }
00314
00315 reference operator[](difference_type offset) const
00316 {
00317 return *(*this + offset);
00318 }
00319
00320 friend iterator operator+(difference_type offset, const iterator& iter)
00321 {
00322 return iter + offset;
00323 }
00324
00325 };
00326
00331 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
00332 typedef std::reverse_iterator<const_iterator, const_pointer, const_reference, difference_type> const_reverse_iterator;
00333 #else
00334 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00335 #endif
00336
00341 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
00342 typedef std::reverse_iterator<iterator, pointer, reference, difference_type> reverse_iterator;
00343 #else
00344 typedef std::reverse_iterator<iterator> reverse_iterator;
00345 #endif
00346
00347 public:
00349
00351
00355 String(void)
00356 {
00357 init();
00358 }
00359
00364 ~String(void)
00365 {
00366 if (d_reserve > STR_QUICKBUFF_SIZE)
00367 {
00368 delete[] d_buffer;
00369 }
00370
00371 if (d_encodedbufflen > 0)
00372 {
00373 delete[] d_encodedbuff;
00374 }
00375
00376 }
00377
00379
00381
00391 String(const String& str)
00392 {
00393 init();
00394 assign(str);
00395 }
00396
00397
00414 String(const String& str, size_type str_idx, size_type str_num = npos)
00415 {
00416 init();
00417 assign(str, str_idx, str_num);
00418 }
00419
00421
00423
00439 String(const std::string& std_str)
00440 {
00441 init();
00442 assign(std_str);
00443 }
00444
00467 String(const std::string& std_str, size_type str_idx, size_type str_num = npos)
00468 {
00469 init();
00470 assign(std_str, str_idx, str_num);
00471 }
00472
00473
00475
00477
00495 String(const utf8* utf8_str)
00496 {
00497 init();
00498 assign(utf8_str);
00499 }
00500
00527 String(const utf8* utf8_str, size_type chars_len)
00528 {
00529 init();
00530 assign(utf8_str, chars_len);
00531 }
00532
00534
00536
00551 String(size_type num, utf32 code_point)
00552 {
00553 init();
00554 assign(num, code_point);
00555 }
00556
00558
00560
00574 String(const_iterator beg, const_iterator end)
00575 {
00576 init();
00577 append(beg, end);
00578 }
00579
00580
00582
00584
00596 String(const char* c_str)
00597 {
00598 init();
00599 assign(c_str);
00600 }
00601
00617 String(const char* chars, size_type chars_len)
00618 {
00619 init();
00620 assign(chars, chars_len);
00621 }
00622
00623
00625
00627
00634 size_type size(void) const
00635 {
00636 return d_cplength;
00637 }
00638
00646 size_type length(void) const
00647 {
00648 return d_cplength;
00649 }
00650
00658 bool empty(void) const
00659 {
00660 return (d_cplength == 0);
00661 }
00662
00672 static size_type max_size(void)
00673 {
00674 return (((size_type)-1) / sizeof(utf32));
00675 }
00676
00678
00680
00681
00690 size_type capacity(void) const
00691 {
00692 return d_reserve - 1;
00693 }
00694
00695
00710 void reserve(size_type num = 0)
00711 {
00712 if (num == 0)
00713 trim();
00714 else
00715 grow(num);
00716 }
00717
00719
00721
00736 int compare(const String& str) const
00737 {
00738 return compare(0, d_cplength, str);
00739 }
00740
00770 int compare(size_type idx, size_type len, const String& str, size_type str_idx = 0, size_type str_len = npos) const
00771 {
00772 if ((d_cplength < idx) || (str.d_cplength < str_idx))
00773 throw std::out_of_range("Index is out of range for CEGUI::String");
00774
00775 if ((len == npos) || (idx + len > d_cplength))
00776 len = d_cplength - idx;
00777
00778 if ((str_len == npos) || (str_idx + str_len > str.d_cplength))
00779 str_len = str.d_cplength - str_idx;
00780
00781 int val = (len == 0) ? 0 : utf32_comp_utf32(&ptr()[idx], &str.ptr()[str_idx], (len < str_len) ? len : str_len);
00782
00783 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
00784 }
00785
00786
00806 int compare(const std::string& std_str) const
00807 {
00808 return compare(0, d_cplength, std_str);
00809 }
00810
00811
00845 int compare(size_type idx, size_type len, const std::string& std_str, size_type str_idx = 0, size_type str_len = npos) const
00846 {
00847 if (d_cplength < idx)
00848 throw std::out_of_range("Index is out of range for CEGUI::String");
00849
00850 if (std_str.size() < str_idx)
00851 throw std::out_of_range("Index is out of range for std::string");
00852
00853 if ((len == npos) || (idx + len > d_cplength))
00854 len = d_cplength - idx;
00855
00856 if ((str_len == npos) || (str_idx + str_len > std_str.size()))
00857 str_len = (size_type)std_str.size() - str_idx;
00858
00859 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], &std_str.c_str()[str_idx], (len < str_len) ? len : str_len);
00860
00861 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
00862 }
00863
00864
00886 int compare(const utf8* utf8_str) const
00887 {
00888 return compare(0, d_cplength, utf8_str, encoded_size(utf8_str));
00889 }
00890
00891
00921 int compare(size_type idx, size_type len, const utf8* utf8_str) const
00922 {
00923 return compare(idx, len, utf8_str, encoded_size(utf8_str));
00924 }
00925
00959 int compare(size_type idx, size_type len, const utf8* utf8_str, size_type str_cplen) const
00960 {
00961 if (d_cplength < idx)
00962 throw std::out_of_range("Index is out of range for CEGUI::String");
00963
00964 if (str_cplen == npos)
00965 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
00966
00967 if ((len == npos) || (idx + len > d_cplength))
00968 len = d_cplength - idx;
00969
00970 int val = (len == 0) ? 0 : utf32_comp_utf8(&ptr()[idx], utf8_str, (len < str_cplen) ? len : str_cplen);
00971
00972 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_cplen) ? -1 : (len == str_cplen) ? 0 : 1;
00973 }
00974
00975
00991 int compare(const char* c_str) const
00992 {
00993 return compare(0, d_cplength, c_str, strlen(c_str));
00994 }
00995
00996
01020 int compare(size_type idx, size_type len, const char* c_str) const
01021 {
01022 return compare(idx, len, c_str, strlen(c_str));
01023 }
01024
01025
01053 int compare(size_type idx, size_type len, const char* chars, size_type chars_len) const
01054 {
01055 if (d_cplength < idx)
01056 throw std::out_of_range("Index is out of range for CEGUI::String");
01057
01058 if (chars_len == npos)
01059 throw std::length_error("Length for char array can not be 'npos'");
01060
01061 if ((len == npos) || (idx + len > d_cplength))
01062 len = d_cplength - idx;
01063
01064 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], chars, (len < chars_len) ? len : chars_len);
01065
01066 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < chars_len) ? -1 : (len == chars_len) ? 0 : 1;
01067 }
01068
01069
01071
01073
01087 reference operator[](size_type idx)
01088 {
01089 return (ptr()[idx]);
01090 }
01091
01106 value_type operator[](size_type idx) const
01107 {
01108 return ptr()[idx];
01109 }
01110
01123 reference at(size_type idx)
01124 {
01125 if (d_cplength <= idx)
01126 throw std::out_of_range("Index is out of range for CEGUI::String");
01127
01128 return ptr()[idx];
01129 }
01130
01143 const_reference at(size_type idx) const
01144 {
01145 if (d_cplength <= idx)
01146 throw std::out_of_range("Index is out of range for CEGUI::String");
01147
01148 return ptr()[idx];
01149 }
01150
01151
01153
01155
01168 const char* c_str(void) const
01169 {
01170 return (const char*)build_utf8_buff();
01171 }
01172
01186 const utf8* data(void) const
01187 {
01188 return build_utf8_buff();
01189 }
01190
01191
01192
01213 size_type copy(utf8* buf, size_type len = npos, size_type idx = 0) const
01214 {
01215 if (d_cplength < idx)
01216 throw std::out_of_range("Index is out of range for CEGUI::String");
01217
01218 if (len == npos)
01219 len = d_cplength;
01220
01221 return encode(&ptr()[idx], buf, npos, len);
01222 }
01223
01225
01227
01243 size_type utf8_stream_len(size_type num = npos, size_type idx = 0)
01244 {
01245 using namespace std;
01246
01247 if (d_cplength < idx)
01248 throw out_of_range("Index was out of range for CEGUI::String object");
01249
01250 size_type maxlen = d_cplength - idx;
01251
01252 return encoded_size(&ptr()[idx], ceguimin(num, maxlen));
01253 }
01254
01256
01258
01268 String& operator=(const String& str)
01269 {
01270 return assign(str);
01271 }
01272
01291 String& assign(const String& str, size_type str_idx = 0, size_type str_num = npos)
01292 {
01293 if (str.d_cplength < str_idx)
01294 throw std::out_of_range("Index was out of range for CEGUI::String object");
01295
01296 if (str_num == npos)
01297 str_num = str.d_cplength - str_idx;
01298
01299 grow(str_num);
01300 setlen(str_num);
01301 memcpy(ptr(), &str.ptr()[str_idx], str_num * sizeof(utf32));
01302 return *this;
01303 }
01304
01321 String& operator=(const std::string& std_str)
01322 {
01323 return assign(std_str);
01324 }
01325
01349 String& assign(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
01350 {
01351 if (std_str.size() < str_idx)
01352 throw std::out_of_range("Index was out of range for std::string object");
01353
01354 if (str_num == npos)
01355 str_num = (size_type)std_str.size() - str_idx;
01356
01357 grow(str_num);
01358 setlen(str_num);
01359
01360 while(str_num--)
01361 {
01362 ((*this)[str_num]) = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num + str_idx]));
01363 }
01364
01365 return *this;
01366 }
01367
01386 String& operator=(const utf8* utf8_str)
01387 {
01388 return assign(utf8_str, utf_length(utf8_str));
01389 }
01390
01409 String& assign(const utf8* utf8_str)
01410 {
01411 return assign(utf8_str, utf_length(utf8_str));
01412 }
01413
01435 String& assign(const utf8* utf8_str, size_type str_num)
01436 {
01437 if (str_num == npos)
01438 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
01439
01440 size_type enc_sze = encoded_size(utf8_str, str_num);
01441
01442 grow(enc_sze);
01443 encode(utf8_str, ptr(), d_reserve, str_num);
01444 setlen(enc_sze);
01445 return *this;
01446 }
01447
01458 String& operator=(utf32 code_point)
01459 {
01460 return assign(1, code_point);
01461 }
01462
01478 String& assign(size_type num, utf32 code_point)
01479 {
01480 if (num == npos)
01481 throw std::length_error("Code point count can not be 'npos'");
01482
01483 grow(num);
01484 setlen(num);
01485 utf32* p = ptr();
01486
01487 while(num--)
01488 *p = code_point;
01489
01490 return *this;
01491 }
01492
01493
01506 String& operator=(const char* c_str)
01507 {
01508 return assign(c_str, strlen(c_str));
01509 }
01510
01511
01524 String& assign(const char* c_str)
01525 {
01526 return assign(c_str, strlen(c_str));
01527 }
01528
01529
01545 String& assign(const char* chars, size_type chars_len)
01546 {
01547 grow(chars_len);
01548 utf32* pt = ptr();
01549
01550 for (size_type i = 0; i < chars_len; ++i)
01551 {
01552 *pt++ = static_cast<utf32>(static_cast<unsigned char>(*chars++));
01553 }
01554
01555 setlen(chars_len);
01556 return *this;
01557 }
01558
01559
01570 void swap(String& str)
01571 {
01572 size_type temp_len = d_cplength;
01573 d_cplength = str.d_cplength;
01574 str.d_cplength = temp_len;
01575
01576 size_type temp_res = d_reserve;
01577 d_reserve = str.d_reserve;
01578 str.d_reserve = temp_res;
01579
01580 utf32* temp_buf = d_buffer;
01581 d_buffer = str.d_buffer;
01582 str.d_buffer = temp_buf;
01583
01584
01585 if (temp_res <= STR_QUICKBUFF_SIZE)
01586 {
01587 utf32 temp_qbf[STR_QUICKBUFF_SIZE];
01588
01589 memcpy(temp_qbf, d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
01590 memcpy(d_quickbuff, str.d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
01591 memcpy(str.d_quickbuff, temp_qbf, STR_QUICKBUFF_SIZE * sizeof(utf32));
01592 }
01593
01594 }
01595
01597
01599
01611 String& operator+=(const String& str)
01612 {
01613 return append(str);
01614 }
01615
01635 String& append(const String& str, size_type str_idx = 0, size_type str_num = npos)
01636 {
01637 if (str.d_cplength < str_idx)
01638 throw std::out_of_range("Index is out of range for CEGUI::String");
01639
01640 if (str_num == npos)
01641 str_num = str.d_cplength - str_idx;
01642
01643 grow(d_cplength + str_num);
01644 memcpy(&ptr()[d_cplength], &str.ptr()[str_idx], str_num * sizeof(utf32));
01645 setlen(d_cplength + str_num);
01646 return *this;
01647 }
01648
01649
01666 String& operator+=(const std::string& std_str)
01667 {
01668 return append(std_str);
01669 }
01670
01694 String& append(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
01695 {
01696 if (std_str.size() < str_idx)
01697 throw std::out_of_range("Index is out of range for std::string");
01698
01699 if (str_num == npos)
01700 str_num = (size_type)std_str.size() - str_idx;
01701
01702 size_type newsze = d_cplength + str_num;
01703
01704 grow(newsze);
01705 utf32* pt = &ptr()[newsze-1];
01706
01707 while(str_num--)
01708 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num]));
01709
01710 setlen(newsze);
01711 return *this;
01712 }
01713
01714
01733 String& operator+=(const utf8* utf8_str)
01734 {
01735 return append(utf8_str, utf_length(utf8_str));
01736 }
01737
01756 String& append(const utf8* utf8_str)
01757 {
01758 return append(utf8_str, utf_length(utf8_str));
01759 }
01760
01761
01783 String& append(const utf8* utf8_str, size_type len)
01784 {
01785 if (len == npos)
01786 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
01787
01788 size_type encsz = encoded_size(utf8_str, len);
01789 size_type newsz = d_cplength + encsz;
01790
01791 grow(newsz);
01792 encode(utf8_str, &ptr()[d_cplength], encsz, len);
01793 setlen(newsz);
01794
01795 return *this;
01796 }
01797
01798
01811 String& operator+=(utf32 code_point)
01812 {
01813 return append(1, code_point);
01814 }
01815
01831 String& append(size_type num, utf32 code_point)
01832 {
01833 if (num == npos)
01834 throw std::length_error("Code point count can not be 'npos'");
01835
01836 size_type newsz = d_cplength + num;
01837 grow(newsz);
01838
01839 utf32* p = &ptr()[d_cplength];
01840
01841 while(num--)
01842 *p++ = code_point;
01843
01844 setlen(newsz);
01845
01846 return *this;
01847 }
01848
01861 void push_back(utf32 code_point)
01862 {
01863 append(1, code_point);
01864 }
01865
01881 String& append(const_iterator beg, const_iterator end)
01882 {
01883 return replace(this->end(), this->end(), beg, end);
01884 }
01885
01886
01899 String& operator+=(const char* c_str)
01900 {
01901 return append(c_str, strlen(c_str));
01902 }
01903
01904
01917 String& append(const char* c_str)
01918 {
01919 return append(c_str, strlen(c_str));
01920 }
01921
01922
01938 String& append(const char* chars, size_type chars_len)
01939 {
01940 if (chars_len == npos)
01941 throw std::length_error("Length for char array can not be 'npos'");
01942
01943 size_type newsz = d_cplength + chars_len;
01944
01945 grow(newsz);
01946
01947 utf32* pt = &ptr()[newsz-1];
01948
01949 while(chars_len--)
01950 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
01951
01952 setlen(newsz);
01953
01954 return *this;
01955 }
01956
01957
01959
01961
01977 String& insert(size_type idx, const String& str)
01978 {
01979 return insert(idx, str, 0, npos);
01980 }
01981
02004 String& insert(size_type idx, const String& str, size_type str_idx, size_type str_num)
02005 {
02006 if ((d_cplength < idx) || (str.d_cplength < str_idx))
02007 throw std::out_of_range("Index is out of range for CEGUI::String");
02008
02009 if (str_num == npos)
02010 str_num = str.d_cplength - str_idx;
02011
02012 size_type newsz = d_cplength + str_num;
02013 grow(newsz);
02014 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02015 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
02016 setlen(newsz);
02017
02018 return *this;
02019 }
02020
02041 String& insert(size_type idx, const std::string& std_str)
02042 {
02043 return insert(idx, std_str, 0, npos);
02044 }
02045
02072 String& insert(size_type idx, const std::string& std_str, size_type str_idx, size_type str_num)
02073 {
02074 if (d_cplength < idx)
02075 throw std::out_of_range("Index is out of range for CEGUI::String");
02076
02077 if (std_str.size() < str_idx)
02078 throw std::out_of_range("Index is out of range for std::string");
02079
02080 if (str_num == npos)
02081 str_num = (size_type)std_str.size() - str_idx;
02082
02083 size_type newsz = d_cplength + str_num;
02084 grow(newsz);
02085
02086 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02087
02088 utf32* pt = &ptr()[idx + str_num - 1];
02089
02090 while(str_num--)
02091 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
02092
02093 setlen(newsz);
02094
02095 return *this;
02096 }
02097
02120 String& insert(size_type idx, const utf8* utf8_str)
02121 {
02122 return insert(idx, utf8_str, utf_length(utf8_str));
02123 }
02124
02150 String& insert(size_type idx, const utf8* utf8_str, size_type len)
02151 {
02152 if (d_cplength < idx)
02153 throw std::out_of_range("Index is out of range for CEGUI::String");
02154
02155 if (len == npos)
02156 throw std::length_error("Length of utf8 encoded string can not be 'npos'");
02157
02158 size_type encsz = encoded_size(utf8_str, len);
02159 size_type newsz = d_cplength + encsz;
02160
02161 grow(newsz);
02162 memmove(&ptr()[idx + encsz], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02163 encode(utf8_str, &ptr()[idx], encsz, len);
02164 setlen(newsz);
02165
02166 return *this;
02167 }
02168
02188 String& insert(size_type idx, size_type num, utf32 code_point)
02189 {
02190 if (d_cplength < idx)
02191 throw std::out_of_range("Index is out of range for CEGUI::String");
02192
02193 if (num == npos)
02194 throw std::length_error("Code point count can not be 'npos'");
02195
02196 size_type newsz = d_cplength + num;
02197 grow(newsz);
02198
02199 memmove(&ptr()[idx + num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02200
02201 utf32* pt = &ptr()[idx + num - 1];
02202
02203 while(num--)
02204 *pt-- = code_point;
02205
02206 setlen(newsz);
02207
02208 return *this;
02209 }
02210
02229 void insert(iterator pos, size_type num, utf32 code_point)
02230 {
02231 insert(safe_iter_dif(pos, begin()), num, code_point);
02232 }
02233
02249 iterator insert(iterator pos, utf32 code_point)
02250 {
02251 insert(pos, 1, code_point);
02252 return pos;
02253 }
02254
02273 void insert(iterator pos, const_iterator beg, const_iterator end)
02274 {
02275 replace(pos, pos, beg, end);
02276 }
02277
02278
02295 String& insert(size_type idx, const char* c_str)
02296 {
02297 return insert(idx, c_str, strlen(c_str));
02298 }
02299
02300
02320 String& insert(size_type idx, const char* chars, size_type chars_len)
02321 {
02322 if (d_cplength < idx)
02323 throw std::out_of_range("Index is out of range for CEGUI::String");
02324
02325 if (chars_len == npos)
02326 throw std::length_error("Length of char array can not be 'npos'");
02327
02328 size_type newsz = d_cplength + chars_len;
02329
02330 grow(newsz);
02331 memmove(&ptr()[idx + chars_len], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
02332
02333 utf32* pt = &ptr()[idx + chars_len - 1];
02334
02335 while(chars_len--)
02336 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
02337
02338 setlen(newsz);
02339
02340 return *this;
02341 }
02342
02343
02345
02347
02354 void clear(void)
02355 {
02356 setlen(0);
02357 trim();
02358 }
02359
02367 String& erase(void)
02368 {
02369 clear();
02370 return *this;
02371 }
02372
02385 String& erase(size_type idx)
02386 {
02387 return erase(idx, 1);
02388 }
02389
02405 String& erase(size_type idx, size_type len = npos)
02406 {
02407 if (d_cplength < idx)
02408 throw std::out_of_range("Index is out of range foe CEGUI::String");
02409
02410 if (len == npos)
02411 len = d_cplength - idx;
02412
02413 size_type newsz = d_cplength - len;
02414
02415 memmove(&ptr()[idx], &ptr()[idx + len], (d_cplength - idx - len) * sizeof(utf32));
02416 setlen(newsz);
02417 return *this;
02418 }
02419
02430 String& erase(iterator pos)
02431 {
02432 return erase(safe_iter_dif(pos, begin()), 1);
02433 }
02434
02448 String& erase(iterator beg, iterator end)
02449 {
02450 return erase(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg));
02451 }
02452
02454
02456
02468 void resize(size_type num)
02469 {
02470 resize(num, utf32());
02471 }
02472
02488 void resize(size_type num, utf32 code_point)
02489 {
02490 if (num < d_cplength)
02491 {
02492 setlen(num);
02493 }
02494 else
02495 {
02496 append(num - d_cplength, code_point);
02497 }
02498
02499 }
02500
02502
02504
02523 String& replace(size_type idx, size_type len, const String& str)
02524 {
02525 return replace(idx, len, str, 0, npos);
02526 }
02527
02549 String& replace(iterator beg, iterator end, const String& str)
02550 {
02551 return replace(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg), str, 0, npos);
02552 }
02553
02579 String& replace(size_type idx, size_type len, const String& str, size_type str_idx, size_type str_num)
02580 {
02581 if ((d_cplength < idx) || (str.d_cplength < str_idx))
02582 throw std::out_of_range("Index is out of range for CEGUI::String");
02583
02584 if (((str_idx + str_num) > str.d_cplength) || (str_num == npos))
02585 str_num = str.d_cplength - str_idx;
02586
02587 if (((len + idx) > d_cplength) || (len == npos))
02588 len = d_cplength - idx;
02589
02590 size_type newsz = d_cplength + str_num - len;
02591
02592 grow(newsz);
02593
02594 if ((idx + len) < d_cplength)
02595 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02596
02597 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
02598 setlen(newsz);
02599
02600 return *this;
02601 }
02602
02603
02627 String& replace(size_type idx, size_type len, const std::string& std_str)
02628 {
02629 return replace(idx, len, std_str, 0, npos);
02630 }
02631
02657 String& replace(iterator beg, iterator end, const std::string& std_str)
02658 {
02659 return replace(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg), std_str, 0, npos);
02660 }
02661
02691 String& replace(size_type idx, size_type len, const std::string& std_str, size_type str_idx, size_type str_num)
02692 {
02693 if (d_cplength < idx)
02694 throw std::out_of_range("Index is out of range for CEGUI::String");
02695
02696 if (std_str.size() < str_idx)
02697 throw std::out_of_range("Index is out of range for std::string");
02698
02699 if (((str_idx + str_num) > std_str.size()) || (str_num == npos))
02700 str_num = (size_type)std_str.size() - str_idx;
02701
02702 if (((len + idx) > d_cplength) || (len == npos))
02703 len = d_cplength - idx;
02704
02705 size_type newsz = d_cplength + str_num - len;
02706
02707 grow(newsz);
02708
02709 if ((idx + len) < d_cplength)
02710 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02711
02712 utf32* pt = &ptr()[idx + str_num - 1];
02713
02714 while (str_num--)
02715 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
02716
02717 setlen(newsz);
02718
02719 return *this;
02720 }
02721
02722
02748 String& replace(size_type idx, size_type len, const utf8* utf8_str)
02749 {
02750 return replace(idx, len, utf8_str, utf_length(utf8_str));
02751 }
02752
02780 String& replace(iterator beg, iterator end, const utf8* utf8_str)
02781 {
02782 return replace(beg, end, utf8_str, utf_length(utf8_str));
02783 }
02784
02813 String& replace(size_type idx, size_type len, const utf8* utf8_str, size_type str_len)
02814 {
02815 if (d_cplength < idx)
02816 throw std::out_of_range("Index is out of range for CEGUI::String");
02817
02818 if (str_len == npos)
02819 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
02820
02821 if (((len + idx) > d_cplength) || (len == npos))
02822 len = d_cplength - idx;
02823
02824 size_type encsz = encoded_size(utf8_str, str_len);
02825 size_type newsz = d_cplength + encsz - len;
02826
02827 grow(newsz);
02828
02829 if ((idx + len) < d_cplength)
02830 memmove(&ptr()[idx + encsz], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02831
02832 encode(utf8_str, &ptr()[idx], encsz, str_len);
02833
02834 setlen(newsz);
02835 return *this;
02836 }
02837
02868 String& replace(iterator beg, iterator end, const utf8* utf8_str, size_type str_len)
02869 {
02870 return replace(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg), utf8_str, str_len);
02871 }
02872
02895 String& replace(size_type idx, size_type len, size_type num, utf32 code_point)
02896 {
02897 if (d_cplength < idx)
02898 throw std::out_of_range("Index is out of range for CEGUI::String");
02899
02900 if (num == npos)
02901 throw std::length_error("Code point count can not be 'npos'");
02902
02903 if (((len + idx) > d_cplength) || (len == npos))
02904 len = d_cplength - idx;
02905
02906 size_type newsz = d_cplength + num - len;
02907
02908 grow(newsz);
02909
02910 if ((idx + len) < d_cplength)
02911 memmove(&ptr()[idx + num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02912
02913 utf32* pt = &ptr()[idx + num - 1];
02914
02915 while (num--)
02916 *pt-- = code_point;
02917
02918 setlen(newsz);
02919
02920 return *this;
02921 }
02922
02947 String& replace(iterator beg, iterator end, size_type num, utf32 code_point)
02948 {
02949 return replace(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg), num, code_point);
02950 }
02951
02952
02977 String& replace(iterator beg, iterator end, const_iterator newBeg, const_iterator newEnd)
02978 {
02979 if (beg == end)
02980 {
02981 erase(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg));
02982 }
02983 else
02984 {
02985 size_type str_len = safe_iter_dif(newEnd, newBeg);
02986 size_type idx = safe_iter_dif(beg, begin());
02987 size_type len = safe_iter_dif(end, beg);
02988
02989 if ((len + idx) > d_cplength)
02990 len = d_cplength - idx;
02991
02992 size_type newsz = d_cplength + str_len - len;
02993
02994 grow(newsz);
02995
02996 if ((idx + len) < d_cplength)
02997 memmove(&ptr()[idx + str_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
02998
02999 memcpy(&ptr()[idx], newBeg.d_ptr, str_len * sizeof(utf32));
03000 setlen(newsz);
03001 }
03002
03003 return *this;
03004 }
03005
03006
03026 String& replace(size_type idx, size_type len, const char* c_str)
03027 {
03028 return replace(idx, len, c_str, strlen(c_str));
03029 }
03030
03031
03053 String& replace(iterator beg, iterator end, const char* c_str)
03054 {
03055 return replace(beg, end, c_str, strlen(c_str));
03056 }
03057
03058
03081 String& replace(size_type idx, size_type len, const char* chars, size_type chars_len)
03082 {
03083 if (d_cplength < idx)
03084 throw std::out_of_range("Index is out of range for CEGUI::String");
03085
03086 if (chars_len == npos)
03087 throw std::length_error("Length for the char array can not be 'npos'");
03088
03089 if (((len + idx) > d_cplength) || (len == npos))
03090 len = d_cplength - idx;
03091
03092 size_type newsz = d_cplength + chars_len - len;
03093
03094 grow(newsz);
03095
03096 if ((idx + len) < d_cplength)
03097 memmove(&ptr()[idx + chars_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
03098
03099 utf32* pt = &ptr()[idx + chars_len - 1];
03100
03101 while (chars_len--)
03102 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
03103
03104 setlen(newsz);
03105 return *this;
03106 }
03107
03108
03133 String& replace(iterator beg, iterator end, const char* chars, size_type chars_len)
03134 {
03135 return replace(safe_iter_dif(beg, begin()), safe_iter_dif(end, beg), chars, chars_len);
03136 }
03137
03138
03140
03142
03156 size_type find(utf32 code_point, size_type idx = 0) const
03157 {
03158 if (idx < d_cplength)
03159 {
03160 const utf32* pt = &ptr()[idx];
03161
03162 while (idx < d_cplength)
03163 {
03164 if (*pt++ == code_point)
03165 return idx;
03166
03167 ++idx;
03168 }
03169
03170 }
03171
03172 return npos;
03173 }
03174
03189 size_type rfind(utf32 code_point, size_type idx = npos) const
03190 {
03191 if (idx >= d_cplength)
03192 idx = d_cplength - 1;
03193
03194 if (d_cplength > 0)
03195 {
03196 const utf32* pt = &ptr()[idx];
03197
03198 do
03199 {
03200 if (*pt-- == code_point)
03201 return idx;
03202
03203 } while (idx-- != 0);
03204
03205 }
03206
03207 return npos;
03208 }
03209
03211
03213
03227 size_type find(const String& str, size_type idx = 0) const
03228 {
03229 if ((str.d_cplength == 0) && (idx < d_cplength))
03230 return idx;
03231
03232 if (idx < d_cplength)
03233 {
03234
03235 while (d_cplength - idx >= str.d_cplength)
03236 {
03237 if (0 == compare(idx, str.d_cplength, str))
03238 return idx;
03239
03240 ++idx;
03241 }
03242
03243 }
03244
03245 return npos;
03246 }
03247
03262 size_type rfind(const String& str, size_type idx = npos) const
03263 {
03264 if (str.d_cplength == 0)
03265 return (idx < d_cplength) ? idx : d_cplength;
03266
03267 if (str.d_cplength <= d_cplength)
03268 {
03269 if (idx > (d_cplength - str.d_cplength))
03270 idx = d_cplength - str.d_cplength;
03271
03272 do
03273 {
03274 if (0 == compare(idx, str.d_cplength, str))
03275 return idx;
03276
03277 } while (idx-- != 0);
03278
03279 }
03280
03281 return npos;
03282 }
03283
03302 size_type find(const std::string& std_str, size_type idx = 0) const
03303 {
03304 std::string::size_type sze = std_str.size();
03305
03306 if ((sze == 0) && (idx < d_cplength))
03307 return idx;
03308
03309 if (idx < d_cplength)
03310 {
03311
03312 while (d_cplength - idx >= sze)
03313 {
03314 if (0 == compare(idx, (size_type)sze, std_str))
03315 return idx;
03316
03317 ++idx;
03318 }
03319
03320 }
03321
03322 return npos;
03323 }
03324
03343 size_type rfind(const std::string& std_str, size_type idx = npos) const
03344 {
03345 std::string::size_type sze = std_str.size();
03346
03347 if (sze == 0)
03348 return (idx < d_cplength) ? idx : d_cplength;
03349
03350 if (sze <= d_cplength)
03351 {
03352 if (idx > (d_cplength - sze))
03353 idx = d_cplength - sze;
03354
03355 do
03356 {
03357 if (0 == compare(idx, (size_type)sze, std_str))
03358 return idx;
03359
03360 } while (idx-- != 0);
03361
03362 }
03363
03364 return npos;
03365 }
03366
03389 size_type find(const utf8* utf8_str, size_type idx = 0) const
03390 {
03391 return find(utf8_str, idx, utf_length(utf8_str));
03392 }
03393
03416 size_type rfind(const utf8* utf8_str, size_type idx = npos) const
03417 {
03418 return rfind(utf8_str, idx, utf_length(utf8_str));
03419 }
03420
03446 size_type find(const utf8* utf8_str, size_type idx, size_type str_len) const
03447 {
03448 if (str_len == npos)
03449 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
03450
03451 size_type sze = encoded_size(utf8_str, str_len);
03452
03453 if ((sze == 0) && (idx < d_cplength))
03454 return idx;
03455
03456 if (idx < d_cplength)
03457 {
03458
03459 while (d_cplength - idx >= sze)
03460 {
03461 if (0 == compare(idx, sze, utf8_str, sze))
03462 return idx;
03463
03464 ++idx;
03465 }
03466
03467 }
03468
03469 return npos;
03470 }
03471
03497 size_type rfind(const utf8* utf8_str, size_type idx, size_type str_len) const
03498 {
03499 if (str_len == npos)
03500 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
03501
03502 size_type sze = encoded_size(utf8_str, str_len);
03503
03504 if (sze == 0)
03505 return (idx < d_cplength) ? idx : d_cplength;
03506
03507 if (sze <= d_cplength)
03508 {
03509 if (idx > (d_cplength - sze))
03510 idx = d_cplength - sze;
03511
03512 do
03513 {
03514 if (0 == compare(idx, sze, utf8_str, sze))
03515 return idx;
03516
03517 } while (idx-- != 0);
03518
03519 }
03520
03521 return npos;
03522 }
03523
03524
03541 size_type find(const char* c_str, size_type idx = 0) const
03542 {
03543 return find(c_str, idx, strlen(c_str));
03544 }
03545
03546
03563 size_type rfind(const char* c_str, size_type idx = npos) const
03564 {
03565 return rfind(c_str, idx, strlen(c_str));
03566 }
03567
03568
03588 size_type find(const char* chars, size_type idx, size_type chars_len) const
03589 {
03590 if (chars_len == npos)
03591 throw std::length_error("Length for char array can not be 'npos'");
03592
03593 if ((chars_len == 0) && (idx < d_cplength))
03594 return idx;
03595
03596 if (idx < d_cplength)
03597 {
03598
03599 while (d_cplength - idx >= chars_len)
03600 {
03601 if (0 == compare(idx, chars_len, chars, chars_len))
03602 return idx;
03603
03604 ++idx;
03605 }
03606
03607 }
03608
03609 return npos;
03610 }
03611
03612
03632 size_type rfind(const char* chars, size_type idx, size_type chars_len) const
03633 {
03634 if (chars_len == npos)
03635 throw std::length_error("Length for char array can not be 'npos'");
03636
03637 if (chars_len == 0)
03638 return (idx < d_cplength) ? idx : d_cplength;
03639
03640 if (chars_len <= d_cplength)
03641 {
03642 if (idx > (d_cplength - chars_len))
03643 idx = d_cplength - chars_len;
03644
03645 do
03646 {
03647 if (0 == compare(idx, chars_len, chars, chars_len))
03648 return idx;
03649
03650 } while (idx-- != 0);
03651
03652 }
03653
03654 return npos;
03655 }
03656
03657
03659
03661
03675 size_type find_first_of(const String& str, size_type idx = 0) const
03676 {
03677 if (idx < d_cplength)
03678 {
03679 const utf32* pt = &ptr()[idx];
03680
03681 do
03682 {
03683 if (npos != str.find(*pt++))
03684 return idx;
03685
03686 } while (++idx != d_cplength);
03687
03688 }
03689
03690 return npos;
03691 }
03692
03707 size_type find_first_not_of(const String& str, size_type idx = 0) const
03708 {
03709 if (idx < d_cplength)
03710 {
03711 const utf32* pt = &ptr()[idx];
03712
03713 do
03714 {
03715 if (npos == str.find(*pt++))
03716 return idx;
03717
03718 } while (++idx != d_cplength);
03719
03720 }
03721
03722 return npos;
03723 }
03724
03725
03744 size_type find_first_of(const std::string& std_str, size_type idx = 0) const
03745 {
03746 if (idx < d_cplength)
03747 {
03748 const utf32* pt = &ptr()[idx];
03749
03750 do
03751 {
03752 if (npos != find_codepoint(std_str, *pt++))
03753 return idx;
03754
03755 } while (++idx != d_cplength);
03756
03757 }
03758
03759 return npos;
03760 }
03761
03780 size_type find_first_not_of(const std::string& std_str, size_type idx = 0) const
03781 {
03782 if (idx < d_cplength)
03783 {
03784 const utf32* pt = &ptr()[idx];
03785
03786 do
03787 {
03788 if (npos == find_codepoint(std_str, *pt++))
03789 return idx;
03790
03791 } while (++idx != d_cplength);
03792
03793 }
03794
03795 return npos;
03796 }
03797
03798
03821 size_type find_first_of(const utf8* utf8_str, size_type idx = 0) const
03822 {
03823 return find_first_of(utf8_str, idx, utf_length(utf8_str));
03824 }
03825
03848 size_type find_first_not_of(const utf8* utf8_str, size_type idx = 0) const
03849 {
03850 return find_first_not_of(utf8_str, idx, utf_length(utf8_str));
03851 }
03852
03878 size_type find_first_of(const utf8* utf8_str, size_type idx, size_type str_len) const
03879 {
03880 if (str_len == npos)
03881 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
03882
03883 if (idx < d_cplength)
03884 {
03885 size_type encsze = encoded_size(utf8_str, str_len);
03886
03887 const utf32* pt = &ptr()[idx];
03888
03889 do
03890 {
03891 if (npos != find_codepoint(utf8_str, encsze, *pt++))
03892 return idx;
03893
03894 } while (++idx != d_cplength);
03895
03896 }
03897
03898 return npos;
03899 }
03900
03926 size_type find_first_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
03927 {
03928 if (str_len == npos)
03929 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
03930
03931 if (idx < d_cplength)
03932 {
03933 size_type encsze = encoded_size(utf8_str, str_len);
03934
03935 const utf32* pt = &ptr()[idx];
03936
03937 do
03938 {
03939 if (npos == find_codepoint(utf8_str, encsze, *pt++))
03940 return idx;
03941
03942 } while (++idx != d_cplength);
03943
03944 }
03945
03946 return npos;
03947 }
03948
03949
03964 size_type find_first_of(utf32 code_point, size_type idx = 0) const
03965 {
03966 return find(code_point, idx);
03967 }
03968
03985 size_type find_first_not_of(utf32 code_point, size_type idx = 0) const
03986 {
03987 if (idx < d_cplength)
03988 {
03989 do
03990 {
03991 if ((*this)[idx] != code_point)
03992 return idx;
03993
03994 } while(idx++ < d_cplength);
03995
03996 }
03997
03998 return npos;
03999 }
04000
04001
04018 size_type find_first_of(const char* c_str, size_type idx = 0) const
04019 {
04020 return find_first_of(c_str, idx, strlen(c_str));
04021 }
04022
04023
04040 size_type find_first_not_of(const char* c_str, size_type idx = 0) const
04041 {
04042 return find_first_not_of(c_str, idx, strlen(c_str));
04043 }
04044
04045
04065 size_type find_first_of(const char* chars, size_type idx, size_type chars_len) const
04066 {
04067 if (chars_len == npos)
04068 throw std::length_error("Length for char array can not be 'npos'");
04069
04070 if (idx < d_cplength)
04071 {
04072 const utf32* pt = &ptr()[idx];
04073
04074 do
04075 {
04076 if (npos != find_codepoint(chars, chars_len, *pt++))
04077 return idx;
04078
04079 } while (++idx != d_cplength);
04080
04081 }
04082
04083 return npos;
04084 }
04085
04086
04106 size_type find_first_not_of(const char* chars, size_type idx, size_type chars_len) const
04107 {
04108 if (chars_len == npos)
04109 throw std::length_error("Length for char array can not be 'npos'");
04110
04111 if (idx < d_cplength)
04112 {
04113 const utf32* pt = &ptr()[idx];
04114
04115 do
04116 {
04117 if (npos == find_codepoint(chars, chars_len, *pt++))
04118 return idx;
04119
04120 } while (++idx != d_cplength);
04121
04122 }
04123
04124 return npos;
04125 }
04126
04127
04129
04131
04145 size_type find_last_of(const String& str, size_type idx = npos) const
04146 {
04147 if (d_cplength > 0)
04148 {
04149 if (idx >= d_cplength)
04150 idx = d_cplength - 1;
04151
04152 const utf32* pt = &ptr()[idx];
04153
04154 do
04155 {
04156 if (npos != str.find(*pt--))
04157 return idx;
04158
04159 } while (idx-- != 0);
04160
04161 }
04162
04163 return npos;
04164 }
04165
04180 size_type find_last_not_of(const String& str, size_type idx = npos) const
04181 {
04182 if (d_cplength > 0)
04183 {
04184 if (idx >= d_cplength)
04185 idx = d_cplength - 1;
04186
04187 const utf32* pt = &ptr()[idx];
04188
04189 do
04190 {
04191 if (npos == str.find(*pt--))
04192 return idx;
04193
04194 } while (idx-- != 0);
04195
04196 }
04197
04198 return npos;
04199 }
04200
04201
04220 size_type find_last_of(const std::string& std_str, size_type idx = npos) const
04221 {
04222 if (d_cplength > 0)
04223 {
04224 if (idx >= d_cplength)
04225 idx = d_cplength - 1;
04226
04227 const utf32* pt = &ptr()[idx];
04228
04229 do
04230 {
04231 if (npos != find_codepoint(std_str, *pt--))
04232 return idx;
04233
04234 } while (idx-- != 0);
04235
04236 }
04237
04238 return npos;
04239 }
04240
04259 size_type find_last_not_of(const std::string& std_str, size_type idx = npos) const
04260 {
04261 if (d_cplength > 0)
04262 {
04263 if (idx >= d_cplength)
04264 idx = d_cplength - 1;
04265
04266 const utf32* pt = &ptr()[idx];
04267
04268 do
04269 {
04270 if (npos == find_codepoint(std_str, *pt--))
04271 return idx;
04272
04273 } while (idx-- != 0);
04274
04275 }
04276
04277 return npos;
04278 }
04279
04280
04303 size_type find_last_of(const utf8* utf8_str, size_type idx = npos) const
04304 {
04305 return find_last_of(utf8_str, idx, utf_length(utf8_str));
04306 }
04307
04330 size_type find_last_not_of(const utf8* utf8_str, size_type idx = npos) const
04331 {
04332 return find_last_not_of(utf8_str, idx, utf_length(utf8_str));
04333 }
04334
04360 size_type find_last_of(const utf8* utf8_str, size_type idx, size_type str_len) const
04361 {
04362 if (str_len == npos)
04363 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
04364
04365 if (d_cplength > 0)
04366 {
04367 if (idx >= d_cplength)
04368 idx = d_cplength - 1;
04369
04370 size_type encsze = encoded_size(utf8_str, str_len);
04371
04372 const utf32* pt = &ptr()[idx];
04373
04374 do
04375 {
04376 if (npos != find_codepoint(utf8_str, encsze, *pt--))
04377 return idx;
04378
04379 } while (idx-- != 0);
04380
04381 }
04382
04383 return npos;
04384 }
04385
04411 size_type find_last_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
04412 {
04413 if (str_len == npos)
04414 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
04415
04416 if (d_cplength > 0)
04417 {
04418 if (idx >= d_cplength)
04419 idx = d_cplength - 1;
04420
04421 size_type encsze = encoded_size(utf8_str, str_len);
04422
04423 const utf32* pt = &ptr()[idx];
04424
04425 do
04426 {
04427 if (npos == find_codepoint(utf8_str, encsze, *pt--))
04428 return idx;
04429
04430 } while (idx-- != 0);
04431
04432 }
04433
04434 return npos;
04435 }
04436
04437
04452 size_type find_last_of(utf32 code_point, size_type idx = npos) const
04453 {
04454 return rfind(code_point, idx);
04455 }
04456
04471 size_type find_last_not_of(utf32 code_point, size_type idx = npos) const
04472 {
04473 if (d_cplength > 0)
04474 {
04475 if (idx >= d_cplength)
04476 idx = d_cplength - 1;
04477
04478 do
04479 {
04480 if ((*this)[idx] != code_point)
04481 return idx;
04482
04483 } while(idx-- != 0);
04484
04485 }
04486
04487 return npos;
04488 }
04489
04490
04507 size_type find_last_of(const char* c_str, size_type idx = npos) const
04508 {
04509 return find_last_of(c_str, idx, strlen(c_str));
04510 }
04511
04512
04529 size_type find_last_not_of(const char* c_str, size_type idx = npos) const
04530 {
04531 return find_last_not_of(c_str, idx, strlen(c_str));
04532 }
04533
04534
04554 size_type find_last_of(const char* chars, size_type idx, size_type chars_len) const
04555 {
04556 if (chars_len == npos)
04557 throw std::length_error("Length for char array can not be 'npos'");
04558
04559 if (d_cplength > 0)
04560 {
04561 if (idx >= d_cplength)
04562 idx = d_cplength - 1;
04563
04564 const utf32* pt = &ptr()[idx];
04565
04566 do
04567 {
04568 if (npos != find_codepoint(chars, chars_len, *pt--))
04569 return idx;
04570
04571 } while (idx-- != 0);
04572
04573 }
04574
04575 return npos;
04576 }
04577
04578
04598 size_type find_last_not_of(const char* chars, size_type idx, size_type chars_len) const
04599 {
04600 if (chars_len == npos)
04601 throw std::length_error("Length for char array can not be 'npos'");
04602
04603 if (d_cplength > 0)
04604 {
04605 if (idx >= d_cplength)
04606 idx = d_cplength - 1;
04607
04608 const utf32* pt = &ptr()[idx];
04609
04610 do
04611 {
04612 if (npos == find_codepoint(chars, chars_len, *pt--))
04613 return idx;
04614
04615 } while (idx-- != 0);
04616
04617 }
04618
04619 return npos;
04620 }
04621
04622
04624
04626
04641 String substr(size_type idx = 0, size_type len = npos) const
04642 {
04643 if (d_cplength < idx)
04644 throw std::out_of_range("Index is out of range for this CEGUI::String");
04645
04646 return String(*this, idx, len);
04647 }
04648
04650
04652
04659 iterator begin(void)
04660 {
04661 return iterator(ptr());
04662 }
04663
04671 const_iterator begin(void) const
04672 {
04673 return const_iterator(ptr());
04674 }
04675
04683 iterator end(void)
04684 {
04685 return iterator(&ptr()[d_cplength]);
04686 }
04687
04695 const_iterator end(void) const
04696 {
04697 return const_iterator(&ptr()[d_cplength]);
04698 }
04699
04707 reverse_iterator rbegin(void)
04708 {
04709 return reverse_iterator(end());
04710 }
04711
04719 const_reverse_iterator rbegin(void) const
04720 {
04721 return const_reverse_iterator(end());
04722 }
04723
04731 reverse_iterator rend(void)
04732 {
04733 return reverse_iterator(begin());
04734 }
04735
04743 const_reverse_iterator rend(void) const
04744 {
04745 return const_reverse_iterator(begin());
04746 }
04747
04748 private:
04749
04750
04751
04752
04753
04754
04755
04756
04757 bool grow(size_type new_size)
04758 {
04759
04760 if (max_size() <= new_size)
04761 std::length_error("Resulting CEGUI::String would be too big");
04762
04763
04764 ++new_size;
04765
04766 if (new_size > d_reserve)
04767 {
04768 utf32* temp = new utf32[new_size];
04769
04770 if (d_reserve > STR_QUICKBUFF_SIZE)
04771 {
04772 memcpy(temp, d_buffer, (d_cplength + 1) * sizeof(utf32));
04773 delete[] d_buffer;
04774 }
04775 else
04776 {
04777 memcpy(temp, d_quickbuff, (d_cplength + 1) * sizeof(utf32));
04778 }
04779
04780 d_buffer = temp;
04781 d_reserve = new_size;
04782
04783 return true;
04784 }
04785
04786 return false;
04787 }
04788
04789
04790 void trim(void)
04791 {
04792 size_type min_size = d_cplength + 1;
04793
04794
04795 if ((d_reserve > STR_QUICKBUFF_SIZE) && (d_reserve > min_size))
04796 {
04797
04798 if (min_size <= STR_QUICKBUFF_SIZE)
04799 {
04800 memcpy(d_quickbuff, d_buffer, min_size * sizeof(utf32));
04801 delete d_buffer;
04802 d_reserve = STR_QUICKBUFF_SIZE;
04803 }
04804
04805 else
04806 {
04807 utf32* temp = new utf32[min_size];
04808 memcpy(temp, d_buffer, min_size * sizeof(utf32));
04809 delete d_buffer;
04810 d_buffer = temp;
04811 d_reserve = min_size;
04812 }
04813
04814 }
04815
04816 }
04817
04818
04819 void setlen(size_type len)
04820 {
04821 d_cplength = len;
04822 ptr()[len] = (utf32)(0);
04823 }
04824
04825
04826 utf32* ptr(void)
04827 {
04828 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
04829 }
04830
04831
04832 const utf32* ptr(void) const
04833 {
04834 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
04835 }
04836
04837
04838 void init(void)
04839 {
04840 d_reserve = STR_QUICKBUFF_SIZE;
04841 d_encodedbuff = NULL;
04842 d_encodedbufflen = 0;
04843 d_encodeddatlen = 0;
04844 setlen(0);
04845 }
04846
04847
04848 bool inside(utf32* inptr)
04849 {
04850 if (inptr < ptr() || ptr() + d_cplength <= inptr)
04851 return false;
04852 else
04853 return true;
04854 }
04855
04856
04857 size_type safe_iter_dif(const const_iterator& iter1, const const_iterator& iter2) const
04858 {
04859 return (iter1.d_ptr == 0) ? 0 : (iter1 - iter2);
04860 }
04861
04862
04863
04864
04865
04866
04867 size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
04868 {
04869
04870 if (src_len == 0)
04871 {
04872 src_len = utf_length(src);
04873 }
04874
04875 size_type destCapacity = dest_len;
04876
04877
04878 for (uint idx = 0; idx < src_len; ++idx)
04879 {
04880 utf32 cp = src[idx];
04881
04882
04883 if (destCapacity < encoded_size(cp))
04884 {
04885 break;
04886 }
04887
04888 if (cp < 0x80)
04889 {
04890 *dest++ = (utf8)cp;
04891 --destCapacity;
04892 }
04893 else if (cp < 0x0800)
04894 {
04895 *dest++ = (utf8)((cp >> 6) | 0xC0);
04896 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04897 destCapacity -= 2;
04898 }
04899 else if (cp < 0x10000)
04900 {
04901 *dest++ = (utf8)((cp >> 12) | 0xE0);
04902 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
04903 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04904 destCapacity -= 3;
04905 }
04906 else
04907 {
04908 *dest++ = (utf8)((cp >> 18) | 0xF0);
04909 *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
04910 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
04911 *dest++ = (utf8)((cp & 0x3F) | 0x80);
04912 destCapacity -= 4;
04913 }
04914
04915 }
04916
04917 return dest_len - destCapacity;
04918 }
04919
04920 size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
04921 {
04922
04923 if (src_len == 0)
04924 {
04925 src_len = utf_length(src);
04926 }
04927
04928 size_type destCapacity = dest_len;
04929
04930
04931 for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
04932 {
04933 utf32 cp;
04934 utf8 cu = src[idx++];
04935
04936 if (cu < 0x80)
04937 {
04938 cp = (utf32)(cu);
04939 }
04940 else if (cu < 0xE0)
04941 {
04942 cp = ((cu & 0x1F) << 6);
04943 cp |= (src[idx++] & 0x3F);
04944 }
04945 else if (cu < 0xF0)
04946 {
04947 cp = ((cu & 0x0F) << 12);
04948 cp |= ((src[idx++] & 0x3F) << 6);
04949 cp |= (src[idx++] & 0x3F);
04950 }
04951 else
04952 {
04953 cp = ((cu & 0x07) << 18);
04954 cp |= ((src[idx++] & 0x3F) << 12);
04955 cp |= ((src[idx++] & 0x3F) << 6);
04956 cp |= (src[idx++] & 0x3F);
04957 }
04958
04959 *dest++ = cp;
04960 --destCapacity;
04961 }
04962
04963 return dest_len - destCapacity;
04964 }
04965
04966
04967 size_type encoded_size(utf32 code_point) const
04968 {
04969 if (code_point < 0x80)
04970 return 1;
04971 else if (code_point < 0x0800)
04972 return 2;
04973 else if (code_point < 0x10000)
04974 return 3;
04975 else
04976 return 4;
04977 }
04978
04979
04980 size_type encoded_size(const utf32* buf) const
04981 {
04982 return encoded_size(buf, utf_length(buf));
04983 }
04984
04985
04986 size_type encoded_size(const utf32* buf, size_type len) const
04987 {
04988 size_type count = 0;
04989
04990 while (len--)
04991 {
04992 count += encoded_size(*buf++);
04993 }
04994
04995 return count;
04996 }
04997
04998
04999 size_type encoded_size(const utf8* buf) const
05000 {
05001 return encoded_size(buf, utf_length(buf));
05002 }
05003
05004
05005 size_type encoded_size(const utf8* buf, size_type len) const
05006 {
05007 utf8 tcp;
05008 size_type count = 0;
05009
05010 while (len--)
05011 {
05012 tcp = *buf++;
05013 ++count;
05014
05015 if (tcp < 0x80)
05016 {
05017 }
05018 else if (tcp < 0xE0)
05019 {
05020 --len;
05021 ++buf;
05022 }
05023 else if (tcp < 0xF0)
05024 {
05025 len -= 2;
05026 buf += 2;
05027 }
05028 else
05029 {
05030 len -= 2;
05031 buf += 3;
05032 }
05033
05034 }
05035
05036 return count;
05037 }
05038
05039
05040 size_type utf_length(const utf8* utf8_str) const
05041 {
05042 size_type cnt = 0;
05043 while (*utf8_str++)
05044 cnt++;
05045
05046 return cnt;
05047 }
05048
05049
05050 size_type utf_length(const utf32* utf32_str) const
05051 {
05052 size_type cnt = 0;
05053 while (*utf32_str++)
05054 cnt++;
05055
05056 return cnt;
05057 }
05058
05059
05060 utf8* build_utf8_buff(void) const
05061 {
05062 size_type buffsize = encoded_size(ptr(), d_cplength) + 1;
05063
05064 if (buffsize > d_encodedbufflen) {
05065
05066 if (d_encodedbufflen > 0)
05067 {
05068 delete[] d_encodedbuff;
05069 }
05070
05071 d_encodedbuff = new utf8[buffsize];
05072 d_encodedbufflen = buffsize;
05073 }
05074
05075 encode(ptr(), d_encodedbuff, buffsize, d_cplength);
05076
05077
05078 d_encodedbuff[buffsize-1] = ((utf8)0);
05079
05080 d_encodeddatlen = buffsize;
05081
05082 return d_encodedbuff;
05083 }
05084
05085
05086 int utf32_comp_utf32(const utf32* buf1, const utf32* buf2, size_type cp_count) const
05087 {
05088 if (!cp_count)
05089 return 0;
05090
05091 while ((--cp_count) && (*buf1 == *buf2))
05092 buf1++, buf2++;
05093
05094 return *buf1 - *buf2;
05095 }
05096
05097
05098 int utf32_comp_char(const utf32* buf1, const char* buf2, size_type cp_count) const
05099 {
05100 if (!cp_count)
05101 return 0;
05102
05103 while ((--cp_count) && (*buf1 == static_cast<utf32>(static_cast<unsigned char>(*buf2))))
05104 buf1++, buf2++;
05105
05106 return *buf1 - static_cast<utf32>(static_cast<unsigned char>(*buf2));
05107 }
05108
05109
05110 int utf32_comp_utf8(const utf32* buf1, const utf8* buf2, size_type cp_count) const
05111 {
05112 if (!cp_count)
05113 return 0;
05114
05115 utf32 cp;
05116 utf8 cu;
05117
05118 do
05119 {
05120 cu = *buf2++;
05121
05122 if (cu < 0x80)
05123 {
05124 cp = (utf32)(cu);
05125 }
05126 else if (cu < 0xE0)
05127 {
05128 cp = ((cu & 0x1F) << 6);
05129 cp |= (*buf2++ & 0x3F);
05130 }
05131 else if (cu < 0xF0)
05132 {
05133 cp = ((cu & 0x0F) << 12);
05134 cp |= ((*buf2++ & 0x3F) << 6);
05135 cp |= (*buf2++ & 0x3F);
05136 }
05137 else
05138 {
05139 cp = ((cu & 0x07) << 18);
05140 cp |= ((*buf2++ & 0x3F) << 12);
05141 cp |= ((*buf2++ & 0x3F) << 6);
05142 cp |= (*buf2++ & 0x3F);
05143 }
05144
05145 } while ((*buf1++ == cp) && (--cp_count));
05146
05147 return (*--buf1) - cp;
05148 }
05149
05150
05151 size_type find_codepoint(const std::string& str, utf32 code_point) const
05152 {
05153 size_type idx = 0, sze = (size_type)str.size();
05154
05155 while (idx != sze)
05156 {
05157 if (code_point == static_cast<utf32>(static_cast<unsigned char>(str[idx])))
05158 return idx;
05159
05160 ++idx;
05161 }
05162
05163 return npos;
05164 }
05165
05166
05167 size_type find_codepoint(const utf8* str, size_type len, utf32 code_point) const
05168 {
05169 size_type idx = 0;
05170
05171 utf32 cp;
05172 utf8 cu;
05173
05174 while (idx != len) {
05175 cu = *str++;
05176
05177 if (cu < 0x80)
05178 {
05179 cp = (utf32)(cu);
05180 }
05181 else if (cu < 0xE0)
05182 {
05183 cp = ((cu & 0x1F) << 6);
05184 cp |= (*str++ & 0x3F);
05185 }
05186 else if (cu < 0xF0)
05187 {
05188 cp = ((cu & 0x0F) << 12);
05189 cp |= ((*str++ & 0x3F) << 6);
05190 cp |= (*str++ & 0x3F);
05191 }
05192 else
05193 {
05194 cp = ((cu & 0x07) << 18);
05195 cp |= ((*str++ & 0x3F) << 12);
05196 cp |= ((*str++ & 0x3F) << 6);
05197 cp |= (*str++ & 0x3F);
05198 }
05199
05200 if (code_point == cp)
05201 return idx;
05202
05203 ++idx;
05204 }
05205
05206 return npos;
05207 }
05208
05209
05210
05211 size_type find_codepoint(const char* chars, size_type chars_len, utf32 code_point) const
05212 {
05213 for (size_type idx = 0; idx != chars_len; ++idx)
05214 {
05215 if (code_point == static_cast<utf32>(static_cast<unsigned char>(chars[idx])))
05216 return idx;
05217 }
05218
05219 return npos;
05220 }
05221
05222 };
05223
05224
05226
05228
05232 bool CEGUIBASE_API operator==(const String& str1, const String& str2);
05233
05238 bool CEGUIBASE_API operator==(const String& str, const std::string& std_str);
05239
05244 bool CEGUIBASE_API operator==(const std::string& std_str, const String& str);
05245
05250 bool CEGUIBASE_API operator==(const String& str, const utf8* utf8_str);
05251
05256 bool CEGUIBASE_API operator==(const utf8* utf8_str, const String& str);
05257
05262 bool CEGUIBASE_API operator!=(const String& str1, const String& str2);
05263
05268 bool CEGUIBASE_API operator!=(const String& str, const std::string& std_str);
05269
05274 bool CEGUIBASE_API operator!=(const std::string& std_str, const String& str);
05275
05280 bool CEGUIBASE_API operator!=(const String& str, const utf8* utf8_str);
05281
05286 bool CEGUIBASE_API operator!=(const utf8* utf8_str, const String& str);
05287
05292 bool CEGUIBASE_API operator<(const String& str1, const String& str2);
05293
05298 bool CEGUIBASE_API operator<(const String& str, const std::string& std_str);
05299
05304 bool CEGUIBASE_API operator<(const std::string& std_str, const String& str);
05305
05310 bool CEGUIBASE_API operator<(const String& str, const utf8* utf8_str);
05311
05316 bool CEGUIBASE_API operator<(const utf8* utf8_str, const String& str);
05317
05322 bool CEGUIBASE_API operator>(const String& str1, const String& str2);
05323
05328 bool CEGUIBASE_API operator>(const String& str, const std::string& std_str);
05329
05334 bool CEGUIBASE_API operator>(const std::string& std_str, const String& str);
05335
05340 bool CEGUIBASE_API operator>(const String& str, const utf8* utf8_str);
05341
05346 bool CEGUIBASE_API operator>(const utf8* utf8_str, const String& str);
05347
05352 bool CEGUIBASE_API operator<=(const String& str1, const String& str2);
05353
05358 bool CEGUIBASE_API operator<=(const String& str, const std::string& std_str);
05359
05364 bool CEGUIBASE_API operator<=(const std::string& std_str, const String& str);
05365
05370 bool CEGUIBASE_API operator<=(const String& str, const utf8* utf8_str);
05371
05376 bool CEGUIBASE_API operator<=(const utf8* utf8_str, const String& str);
05377
05382 bool CEGUIBASE_API operator>=(const String& str1, const String& str2);
05383
05388 bool CEGUIBASE_API operator>=(const String& str, const std::string& std_str);
05389
05394 bool CEGUIBASE_API operator>=(const std::string& std_str, const String& str);
05395
05400 bool CEGUIBASE_API operator>=(const String& str, const utf8* utf8_str);
05401
05406 bool CEGUIBASE_API operator>=(const utf8* utf8_str, const String& str);
05407
05412 bool CEGUIBASE_API operator==(const String& str, const char* c_str);
05413
05418 bool CEGUIBASE_API operator==(const char* c_str, const String& str);
05419
05424 bool CEGUIBASE_API operator!=(const String& str, const char* c_str);
05425
05430 bool CEGUIBASE_API operator!=(const char* c_str, const String& str);
05431
05436 bool CEGUIBASE_API operator<(const String& str, const char* c_str);
05437
05442 bool CEGUIBASE_API operator<(const char* c_str, const String& str);
05443
05448 bool CEGUIBASE_API operator>(const String& str, const char* c_str);
05449
05454 bool CEGUIBASE_API operator>(const char* c_str, const String& str);
05455
05460 bool CEGUIBASE_API operator<=(const String& str, const char* c_str);
05461
05466 bool CEGUIBASE_API operator<=(const char* c_str, const String& str);
05467
05472 bool CEGUIBASE_API operator>=(const String& str, const char* c_str);
05473
05478 bool CEGUIBASE_API operator>=(const char* c_str, const String& str);
05479
05481
05483
05498 String CEGUIBASE_API operator+(const String str1, const String& str2);
05499
05515 String CEGUIBASE_API operator+(const String str, const std::string& std_str);
05516
05532 String CEGUIBASE_API operator+(const std::string& std_str, const String& str);
05533
05549 String CEGUIBASE_API operator+(const String str, const utf8* utf8_str);
05550
05566 String CEGUIBASE_API operator+(const utf8* utf8_str, const String& str);
05567
05583 String CEGUIBASE_API operator+(const String str, utf32 code_point);
05584
05600 String CEGUIBASE_API operator+(utf32 code_point, const String& str);
05601
05617 String CEGUIBASE_API operator+(const String str, const char* c_str);
05618
05634 String CEGUIBASE_API operator+(const char* c_str, const String& str);
05635
05636
05638
05640 std::ostream& operator<<(std::ostream& s, const String& str);
05641
05642
05644
05646
05659 void CEGUIBASE_API swap(String& str1, String& str2);
05660
05661
05662 }
05663
05664
05665 #endif // end of guard _CEGUIString_h_