Crazy Eddies GUI System  0.6.0
CEGUIString.h
1 /***********************************************************************
2  filename: CEGUIString.h
3  created: 26/2/2004
4  author: Paul D Turner
5 
6  purpose: Defines string class used within the GUI system.
7 *************************************************************************/
8 /***************************************************************************
9  * Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining
12  * a copy of this software and associated documentation files (the
13  * "Software"), to deal in the Software without restriction, including
14  * without limitation the rights to use, copy, modify, merge, publish,
15  * distribute, sublicense, and/or sell copies of the Software, and to
16  * permit persons to whom the Software is furnished to do so, subject to
17  * the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be
20  * included in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  ***************************************************************************/
30 #ifndef _CEGUIString_h_
31 #define _CEGUIString_h_
32 
33 #include "CEGUIBase.h"
34 #include <string>
35 #include <string.h>
36 #include <stdexcept>
37 
38 // Start of CEGUI namespace section
39 namespace CEGUI
40 {
41 #define STR_QUICKBUFF_SIZE 32
42  /*************************************************************************
43  Basic Types
44  *************************************************************************/
45  typedef uint8 utf8;
46  //typedef uint16 utf16; // removed typedef to prevent usage, as utf16 is not supported (yet)
47  typedef uint32 utf32;
48 
57 class CEGUIEXPORT String
58 {
59 public:
60  /*************************************************************************
61  Integral Types
62  *************************************************************************/
63  typedef utf32 value_type;
64  typedef size_t size_type;
65  typedef ptrdiff_t difference_type;
66  typedef utf32& reference;
67  typedef const utf32& const_reference;
68  typedef utf32* pointer;
69  typedef const utf32* const_pointer;
70 
71  static const size_type npos;
72 
73 private:
74  /*************************************************************************
75  Implementation data
76  *************************************************************************/
77  size_type d_cplength;
78  size_type d_reserve;
79 
80  mutable utf8* d_encodedbuff;
81  mutable size_type d_encodeddatlen;
82  mutable size_type d_encodedbufflen;
83 
84  utf32 d_quickbuff[STR_QUICKBUFF_SIZE];
85  utf32* d_buffer;
86 
87 public:
88  /*************************************************************************
89  Iterator Classes
90  *************************************************************************/
95 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
96  class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32>
97 #else
98  class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32, std::ptrdiff_t, const utf32*, const utf32&>
99 #endif
100  {
101 
102  public:
104  // data
106  const utf32* d_ptr;
107 
108 
110  // Methods
112  const_iterator(void)
113  {
114  d_ptr = 0;
115  }
117  {
118  d_ptr = ptr;
119  }
120 
121  const_reference operator*() const
122  {
123  return *d_ptr;
124  }
125 
126 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
127 # pragma warning (push)
128 # pragma warning (disable : 4284)
129 #endif
130  const_pointer operator->() const
131  {
132  return &**this;
133  }
134 
135 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
136 # pragma warning (pop)
137 #endif
138 
139  const_iterator& operator++()
140  {
141  ++d_ptr;
142  return *this;
143  }
144 
145  const_iterator operator++(int)
146  {
147  const_iterator temp = *this;
148  ++*this;
149  return temp;
150  }
151 
152  const_iterator& operator--()
153  {
154  --d_ptr;
155  return *this;
156  }
157 
158  const_iterator operator--(int)
159  {
160  const_iterator temp = *this;
161  --*this;
162  return temp;
163  }
164 
165  const_iterator& operator+=(difference_type offset)
166  {
167  d_ptr += offset;
168  return *this;
169  }
170 
172  {
173  const_iterator temp = *this;
174  return temp += offset;
175  }
176 
177  const_iterator& operator-=(difference_type offset)
178  {
179  return *this += -offset;
180  }
181 
182  const_iterator operator-(difference_type offset) const
183  {
184  const_iterator temp = *this;
185  return temp -= offset;
186  }
187 
188  difference_type operator-(const const_iterator& iter) const
189  {
190  return d_ptr - iter.d_ptr;
191  }
192 
193  const_reference operator[](difference_type offset) const
194  {
195  return *(*this + offset);
196  }
197 
198  bool operator==(const const_iterator& iter) const
199  {
200  return d_ptr == iter.d_ptr;
201  }
202 
203  bool operator!=(const const_iterator& iter) const
204  {
205  return !(*this == iter);
206  }
207 
208  bool operator<(const const_iterator& iter) const
209  {
210  return d_ptr < iter.d_ptr;
211  }
212 
213  bool operator>(const const_iterator& iter) const
214  {
215  return (!(iter < *this));
216  }
217 
218  bool operator<=(const const_iterator& iter) const
219  {
220  return (!(iter < *this));
221  }
222 
223  bool operator>=(const const_iterator& iter) const
224  {
225  return (!(*this < iter));
226  }
227 
228  friend const_iterator operator+(difference_type offset, const const_iterator& iter)
229  {
230  return iter + offset;
231  }
232 
233  };
234 
239  class iterator : public const_iterator
240  {
241  public:
242  iterator(void) {}
243  iterator(pointer ptr) : const_iterator(ptr) {}
244 
245 
246  reference operator*() const
247  {
248  return ((reference)**(const_iterator *)this);
249  }
250 
251 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
252 # pragma warning (push)
253 # pragma warning (disable : 4284)
254 #endif
255 
256  pointer operator->() const
257  {
258  return &**this;
259  }
260 
261 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
262 # pragma warning (pop)
263 #endif
264 
265  iterator& operator++()
266  {
267  ++this->d_ptr;
268  return *this;
269  }
270 
271  iterator operator++(int)
272  {
273  iterator temp = *this;
274  ++*this;
275  return temp;
276  }
277 
278  iterator& operator--()
279  {
280  --this->d_ptr;
281  return *this;
282  }
283 
284  iterator operator--(int)
285  {
286  iterator temp = *this;
287  --*this;
288  return temp;
289  }
290 
291  iterator& operator+=(difference_type offset)
292  {
293  this->d_ptr += offset;
294  return *this;
295  }
296 
297  iterator operator+(difference_type offset) const
298  {
299  iterator temp = *this;
300  return temp + offset;
301  }
302 
303  iterator& operator-=(difference_type offset)
304  {
305  return *this += -offset;
306  }
307 
308  iterator operator-(difference_type offset) const
309  {
310  iterator temp = *this;
311  return temp -= offset;
312  }
313 
314  difference_type operator-(const const_iterator& iter) const
315  {
316  return ((const_iterator)*this - iter);
317  }
318 
319  reference operator[](difference_type offset) const
320  {
321  return *(*this + offset);
322  }
323 
324  friend iterator operator+(difference_type offset, const iterator& iter)
325  {
326  return iter + offset;
327  }
328 
329  };
330 
335 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
336  typedef std::reverse_iterator<const_iterator, const_pointer, const_reference, difference_type> const_reverse_iterator;
337 #else
338  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
339 #endif
340 
345 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
346  typedef std::reverse_iterator<iterator, pointer, reference, difference_type> reverse_iterator;
347 #else
348  typedef std::reverse_iterator<iterator> reverse_iterator;
349 #endif
350 
351 public:
358  {
359  bool operator() (const String& a, const String& b) const
360  {
361  const size_t la = a.length();
362  const size_t lb = b.length();
363  if (la == lb)
364  return (memcmp(a.ptr(), b.ptr(), la*sizeof(utf32)) < 0);
365  return (la < lb);
366  }
367  };
368 
369 public:
371  // Default Construction and Destructor
373 
377  String(void)
378  {
379  init();
380  }
381 
386  ~String(void);
387 
389  // Construction via CEGUI::String
391 
401  String(const String& str)
402  {
403  init();
404  assign(str);
405  }
406 
407 
424  String(const String& str, size_type str_idx, size_type str_num = npos)
425  {
426  init();
427  assign(str, str_idx, str_num);
428  }
429 
431  // Construction via std::string
433 
449  String(const std::string& std_str)
450  {
451  init();
452  assign(std_str);
453  }
454 
477  String(const std::string& std_str, size_type str_idx, size_type str_num = npos)
478  {
479  init();
480  assign(std_str, str_idx, str_num);
481  }
482 
483 
485  // Construction via UTF-8 stream (for straight ASCII use, only codes 0x00 - 0x7f are valid)
487 
505  String(const utf8* utf8_str)
506  {
507  init();
508  assign(utf8_str);
509  }
510 
537  String(const utf8* utf8_str, size_type chars_len)
538  {
539  init();
540  assign(utf8_str, chars_len);
541  }
542 
544  // Construction via code-point (using a UTF-32 code unit)
546 
561  String(size_type num, utf32 code_point)
562  {
563  init();
564  assign(num, code_point);
565  }
566 
568  // Construction via iterator
570  // Create string with characters in the range [beg, end)
585  {
586  init();
587  append(iter_beg, iter_end);
588  }
589 
590 
592  // Construction via c-string
594 
606  String(const char* cstr)
607  {
608  init();
609  assign(cstr);
610  }
611 
627  String(const char* chars, size_type chars_len)
628  {
629  init();
630  assign(chars, chars_len);
631  }
632 
633 
635  // Size operations
637 
644  size_type size(void) const
645  {
646  return d_cplength;
647  }
648 
656  size_type length(void) const
657  {
658  return d_cplength;
659  }
660 
668  bool empty(void) const
669  {
670  return (d_cplength == 0);
671  }
672 
682  static size_type max_size(void)
683  {
684  return (((size_type)-1) / sizeof(utf32));
685  }
686 
688  // Capacity Operations
690  // return the number of code points the string could hold without re-allocation
691  // (due to internal encoding this will always report the figure for worst-case encoding, and could even be < size()!)
700  size_type capacity(void) const
701  {
702  return d_reserve - 1;
703  }
704 
705  // reserve internal memory for at-least 'num' code-points (characters). if num is 0, request is shrink-to-fit.
720  void reserve(size_type num = 0)
721  {
722  if (num == 0)
723  trim();
724  else
725  grow(num);
726  }
727 
729  // Comparisons
731 
746  int compare(const String& str) const
747  {
748  return compare(0, d_cplength, str);
749  }
750 
780  int compare(size_type idx, size_type len, const String& str, size_type str_idx = 0, size_type str_len = npos) const
781  {
782  if ((d_cplength < idx) || (str.d_cplength < str_idx))
783  throw std::out_of_range("Index is out of range for CEGUI::String");
784 
785  if ((len == npos) || (idx + len > d_cplength))
786  len = d_cplength - idx;
787 
788  if ((str_len == npos) || (str_idx + str_len > str.d_cplength))
789  str_len = str.d_cplength - str_idx;
790 
791  int val = (len == 0) ? 0 : utf32_comp_utf32(&ptr()[idx], &str.ptr()[str_idx], (len < str_len) ? len : str_len);
792 
793  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
794  }
795 
796 
816  int compare(const std::string& std_str) const
817  {
818  return compare(0, d_cplength, std_str);
819  }
820 
821 
855  int compare(size_type idx, size_type len, const std::string& std_str, size_type str_idx = 0, size_type str_len = npos) const
856  {
857  if (d_cplength < idx)
858  throw std::out_of_range("Index is out of range for CEGUI::String");
859 
860  if (std_str.size() < str_idx)
861  throw std::out_of_range("Index is out of range for std::string");
862 
863  if ((len == npos) || (idx + len > d_cplength))
864  len = d_cplength - idx;
865 
866  if ((str_len == npos) || (str_idx + str_len > std_str.size()))
867  str_len = (size_type)std_str.size() - str_idx;
868 
869  int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], &std_str.c_str()[str_idx], (len < str_len) ? len : str_len);
870 
871  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
872  }
873 
874 
896  int compare(const utf8* utf8_str) const
897  {
898  return compare(0, d_cplength, utf8_str, encoded_size(utf8_str));
899  }
900 
901 
931  int compare(size_type idx, size_type len, const utf8* utf8_str) const
932  {
933  return compare(idx, len, utf8_str, encoded_size(utf8_str));
934  }
935 
969  int compare(size_type idx, size_type len, const utf8* utf8_str, size_type str_cplen) const
970  {
971  if (d_cplength < idx)
972  throw std::out_of_range("Index is out of range for CEGUI::String");
973 
974  if (str_cplen == npos)
975  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
976 
977  if ((len == npos) || (idx + len > d_cplength))
978  len = d_cplength - idx;
979 
980  int val = (len == 0) ? 0 : utf32_comp_utf8(&ptr()[idx], utf8_str, (len < str_cplen) ? len : str_cplen);
981 
982  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_cplen) ? -1 : (len == str_cplen) ? 0 : 1;
983  }
984 
985 
1001  int compare(const char* cstr) const
1002  {
1003  return compare(0, d_cplength, cstr, strlen(cstr));
1004  }
1005 
1006 
1030  int compare(size_type idx, size_type len, const char* cstr) const
1031  {
1032  return compare(idx, len, cstr, strlen(cstr));
1033  }
1034 
1035 
1063  int compare(size_type idx, size_type len, const char* chars, size_type chars_len) const
1064  {
1065  if (d_cplength < idx)
1066  throw std::out_of_range("Index is out of range for CEGUI::String");
1067 
1068  if (chars_len == npos)
1069  throw std::length_error("Length for char array can not be 'npos'");
1070 
1071  if ((len == npos) || (idx + len > d_cplength))
1072  len = d_cplength - idx;
1073 
1074  int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], chars, (len < chars_len) ? len : chars_len);
1075 
1076  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < chars_len) ? -1 : (len == chars_len) ? 0 : 1;
1077  }
1078 
1079 
1081  // Character access
1083 
1097  reference operator[](size_type idx)
1098  {
1099  return (ptr()[idx]);
1100  }
1101 
1116  value_type operator[](size_type idx) const
1117  {
1118  return ptr()[idx];
1119  }
1120 
1134  {
1135  if (d_cplength <= idx)
1136  throw std::out_of_range("Index is out of range for CEGUI::String");
1137 
1138  return ptr()[idx];
1139  }
1140 
1154  {
1155  if (d_cplength <= idx)
1156  throw std::out_of_range("Index is out of range for CEGUI::String");
1157 
1158  return ptr()[idx];
1159  }
1160 
1161 
1163  // C-Strings and arrays
1165 
1178  const char* c_str(void) const
1179  {
1180  return (const char*)build_utf8_buff();
1181  }
1182 
1196  const utf8* data(void) const
1197  {
1198  return build_utf8_buff();
1199  }
1200 
1205  utf32* ptr(void)
1206  {
1207  return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1208  }
1209 
1214  const utf32* ptr(void) const
1215  {
1216  return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1217  }
1218 
1219  // copy, at most, 'len' code-points of the string, begining with code-point 'idx', into the array 'buf' as valid utf8 encoded data
1220  // return number of utf8 code units placed into the buffer
1241  size_type copy(utf8* buf, size_type len = npos, size_type idx = 0) const
1242  {
1243  if (d_cplength < idx)
1244  throw std::out_of_range("Index is out of range for CEGUI::String");
1245 
1246  if (len == npos)
1247  len = d_cplength;
1248 
1249  return encode(&ptr()[idx], buf, npos, len);
1250  }
1251 
1253  // UTF8 Encoding length information
1255  // return the number of bytes required to hold 'num' code-points, starting at code-point 'idx', of the the string when encoded as utf8 data.
1271  size_type utf8_stream_len(size_type num = npos, size_type idx = 0) const
1272  {
1273  using namespace std;
1274 
1275  if (d_cplength < idx)
1276  throw out_of_range("Index was out of range for CEGUI::String object");
1277 
1278  size_type maxlen = d_cplength - idx;
1279 
1280  return encoded_size(&ptr()[idx], ceguimin(num, maxlen));
1281  }
1282 
1284  // Assignment Functions
1286 
1296  String& operator=(const String& str)
1297  {
1298  return assign(str);
1299  }
1300 
1319  String& assign(const String& str, size_type str_idx = 0, size_type str_num = npos)
1320  {
1321  if (str.d_cplength < str_idx)
1322  throw std::out_of_range("Index was out of range for CEGUI::String object");
1323 
1324  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
1325  str_num = str.d_cplength - str_idx;
1326 
1327  grow(str_num);
1328  setlen(str_num);
1329  memcpy(ptr(), &str.ptr()[str_idx], str_num * sizeof(utf32));
1330 
1331  return *this;
1332  }
1333 
1350  String& operator=(const std::string& std_str)
1351  {
1352  return assign(std_str);
1353  }
1354 
1378  String& assign(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1379  {
1380  if (std_str.size() < str_idx)
1381  throw std::out_of_range("Index was out of range for std::string object");
1382 
1383  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
1384  str_num = (size_type)std_str.size() - str_idx;
1385 
1386  grow(str_num);
1387  setlen(str_num);
1388 
1389  while(str_num--)
1390  {
1391  ((*this)[str_num]) = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num + str_idx]));
1392  }
1393 
1394  return *this;
1395  }
1396 
1415  String& operator=(const utf8* utf8_str)
1416  {
1417  return assign(utf8_str, utf_length(utf8_str));
1418  }
1419 
1438  String& assign(const utf8* utf8_str)
1439  {
1440  return assign(utf8_str, utf_length(utf8_str));
1441  }
1442 
1464  String& assign(const utf8* utf8_str, size_type str_num)
1465  {
1466  if (str_num == npos)
1467  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
1468 
1469  size_type enc_sze = encoded_size(utf8_str, str_num);
1470 
1471  grow(enc_sze);
1472  encode(utf8_str, ptr(), d_reserve, str_num);
1473  setlen(enc_sze);
1474  return *this;
1475  }
1476 
1487  String& operator=(utf32 code_point)
1488  {
1489  return assign(1, code_point);
1490  }
1491 
1507  String& assign(size_type num, utf32 code_point)
1508  {
1509  if (num == npos)
1510  throw std::length_error("Code point count can not be 'npos'");
1511 
1512  grow(num);
1513  setlen(num);
1514  utf32* p = ptr();
1515 
1516  while(num--)
1517  *p++ = code_point;
1518 
1519  return *this;
1520  }
1521 
1522 
1535  String& operator=(const char* cstr)
1536  {
1537  return assign(cstr, strlen(cstr));
1538  }
1539 
1540 
1553  String& assign(const char* cstr)
1554  {
1555  return assign(cstr, strlen(cstr));
1556  }
1557 
1558 
1574  String& assign(const char* chars, size_type chars_len)
1575  {
1576  grow(chars_len);
1577  utf32* pt = ptr();
1578 
1579  for (size_type i = 0; i < chars_len; ++i)
1580  {
1581  *pt++ = static_cast<utf32>(static_cast<unsigned char>(*chars++));
1582  }
1583 
1584  setlen(chars_len);
1585  return *this;
1586  }
1587 
1588 
1599  void swap(String& str)
1600  {
1601  size_type temp_len = d_cplength;
1602  d_cplength = str.d_cplength;
1603  str.d_cplength = temp_len;
1604 
1605  size_type temp_res = d_reserve;
1606  d_reserve = str.d_reserve;
1607  str.d_reserve = temp_res;
1608 
1609  utf32* temp_buf = d_buffer;
1610  d_buffer = str.d_buffer;
1611  str.d_buffer = temp_buf;
1612 
1613  // see if we need to swap 'quick buffer' data
1614  if (temp_res <= STR_QUICKBUFF_SIZE)
1615  {
1616  utf32 temp_qbf[STR_QUICKBUFF_SIZE];
1617 
1618  memcpy(temp_qbf, d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
1619  memcpy(d_quickbuff, str.d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
1620  memcpy(str.d_quickbuff, temp_qbf, STR_QUICKBUFF_SIZE * sizeof(utf32));
1621  }
1622 
1623  }
1624 
1626  // Appending Functions
1628 
1640  String& operator+=(const String& str)
1641  {
1642  return append(str);
1643  }
1644 
1664  String& append(const String& str, size_type str_idx = 0, size_type str_num = npos)
1665  {
1666  if (str.d_cplength < str_idx)
1667  throw std::out_of_range("Index is out of range for CEGUI::String");
1668 
1669  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
1670  str_num = str.d_cplength - str_idx;
1671 
1672  grow(d_cplength + str_num);
1673  memcpy(&ptr()[d_cplength], &str.ptr()[str_idx], str_num * sizeof(utf32));
1674  setlen(d_cplength + str_num);
1675  return *this;
1676  }
1677 
1678 
1695  String& operator+=(const std::string& std_str)
1696  {
1697  return append(std_str);
1698  }
1699 
1723  String& append(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1724  {
1725  if (std_str.size() < str_idx)
1726  throw std::out_of_range("Index is out of range for std::string");
1727 
1728  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
1729  str_num = (size_type)std_str.size() - str_idx;
1730 
1731  size_type newsze = d_cplength + str_num;
1732 
1733  grow(newsze);
1734  utf32* pt = &ptr()[newsze-1];
1735 
1736  while(str_num--)
1737  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num]));
1738 
1739  setlen(newsze);
1740  return *this;
1741  }
1742 
1743 
1762  String& operator+=(const utf8* utf8_str)
1763  {
1764  return append(utf8_str, utf_length(utf8_str));
1765  }
1766 
1785  String& append(const utf8* utf8_str)
1786  {
1787  return append(utf8_str, utf_length(utf8_str));
1788  }
1789 
1790 
1812  String& append(const utf8* utf8_str, size_type len)
1813  {
1814  if (len == npos)
1815  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
1816 
1817  size_type encsz = encoded_size(utf8_str, len);
1818  size_type newsz = d_cplength + encsz;
1819 
1820  grow(newsz);
1821  encode(utf8_str, &ptr()[d_cplength], encsz, len);
1822  setlen(newsz);
1823 
1824  return *this;
1825  }
1826 
1827 
1840  String& operator+=(utf32 code_point)
1841  {
1842  return append(1, code_point);
1843  }
1844 
1860  String& append(size_type num, utf32 code_point)
1861  {
1862  if (num == npos)
1863  throw std::length_error("Code point count can not be 'npos'");
1864 
1865  size_type newsz = d_cplength + num;
1866  grow(newsz);
1867 
1868  utf32* p = &ptr()[d_cplength];
1869 
1870  while(num--)
1871  *p++ = code_point;
1872 
1873  setlen(newsz);
1874 
1875  return *this;
1876  }
1877 
1890  void push_back(utf32 code_point)
1891  {
1892  append(1, code_point);
1893  }
1894 
1910  String& append(const_iterator iter_beg, const_iterator iter_end)
1911  {
1912  return replace(end(), end(), iter_beg, iter_end);
1913  }
1914 
1915 
1928  String& operator+=(const char* cstr)
1929  {
1930  return append(cstr, strlen(cstr));
1931  }
1932 
1933 
1946  String& append(const char* cstr)
1947  {
1948  return append(cstr, strlen(cstr));
1949  }
1950 
1951 
1967  String& append(const char* chars, size_type chars_len)
1968  {
1969  if (chars_len == npos)
1970  throw std::length_error("Length for char array can not be 'npos'");
1971 
1972  size_type newsz = d_cplength + chars_len;
1973 
1974  grow(newsz);
1975 
1976  utf32* pt = &ptr()[newsz-1];
1977 
1978  while(chars_len--)
1979  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
1980 
1981  setlen(newsz);
1982 
1983  return *this;
1984  }
1985 
1986 
1988  // Insertion Functions
1990 
2006  String& insert(size_type idx, const String& str)
2007  {
2008  return insert(idx, str, 0, npos);
2009  }
2010 
2033  String& insert(size_type idx, const String& str, size_type str_idx, size_type str_num)
2034  {
2035  if ((d_cplength < idx) || (str.d_cplength < str_idx))
2036  throw std::out_of_range("Index is out of range for CEGUI::String");
2037 
2038  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
2039  str_num = str.d_cplength - str_idx;
2040 
2041  size_type newsz = d_cplength + str_num;
2042  grow(newsz);
2043  memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2044  memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2045  setlen(newsz);
2046 
2047  return *this;
2048  }
2049 
2070  String& insert(size_type idx, const std::string& std_str)
2071  {
2072  return insert(idx, std_str, 0, npos);
2073  }
2074 
2101  String& insert(size_type idx, const std::string& std_str, size_type str_idx, size_type str_num)
2102  {
2103  if (d_cplength < idx)
2104  throw std::out_of_range("Index is out of range for CEGUI::String");
2105 
2106  if (std_str.size() < str_idx)
2107  throw std::out_of_range("Index is out of range for std::string");
2108 
2109  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
2110  str_num = (size_type)std_str.size() - str_idx;
2111 
2112  size_type newsz = d_cplength + str_num;
2113  grow(newsz);
2114 
2115  memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2116 
2117  utf32* pt = &ptr()[idx + str_num - 1];
2118 
2119  while(str_num--)
2120  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2121 
2122  setlen(newsz);
2123 
2124  return *this;
2125  }
2126 
2149  String& insert(size_type idx, const utf8* utf8_str)
2150  {
2151  return insert(idx, utf8_str, utf_length(utf8_str));
2152  }
2153 
2179  String& insert(size_type idx, const utf8* utf8_str, size_type len)
2180  {
2181  if (d_cplength < idx)
2182  throw std::out_of_range("Index is out of range for CEGUI::String");
2183 
2184  if (len == npos)
2185  throw std::length_error("Length of utf8 encoded string can not be 'npos'");
2186 
2187  size_type encsz = encoded_size(utf8_str, len);
2188  size_type newsz = d_cplength + encsz;
2189 
2190  grow(newsz);
2191  memmove(&ptr()[idx + encsz], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2192  encode(utf8_str, &ptr()[idx], encsz, len);
2193  setlen(newsz);
2194 
2195  return *this;
2196  }
2197 
2217  String& insert(size_type idx, size_type num, utf32 code_point)
2218  {
2219  if (d_cplength < idx)
2220  throw std::out_of_range("Index is out of range for CEGUI::String");
2221 
2222  if (num == npos)
2223  throw std::length_error("Code point count can not be 'npos'");
2224 
2225  size_type newsz = d_cplength + num;
2226  grow(newsz);
2227 
2228  memmove(&ptr()[idx + num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2229 
2230  utf32* pt = &ptr()[idx + num - 1];
2231 
2232  while(num--)
2233  *pt-- = code_point;
2234 
2235  setlen(newsz);
2236 
2237  return *this;
2238  }
2239 
2258  void insert(iterator pos, size_type num, utf32 code_point)
2259  {
2260  insert(safe_iter_dif(pos, begin()), num, code_point);
2261  }
2262 
2278  iterator insert(iterator pos, utf32 code_point)
2279  {
2280  insert(pos, 1, code_point);
2281  return pos;
2282  }
2283 
2302  void insert(iterator iter_pos, const_iterator iter_beg, const_iterator iter_end)
2303  {
2304  replace(iter_pos, iter_pos, iter_beg, iter_end);
2305  }
2306 
2307 
2324  String& insert(size_type idx, const char* cstr)
2325  {
2326  return insert(idx, cstr, strlen(cstr));
2327  }
2328 
2329 
2349  String& insert(size_type idx, const char* chars, size_type chars_len)
2350  {
2351  if (d_cplength < idx)
2352  throw std::out_of_range("Index is out of range for CEGUI::String");
2353 
2354  if (chars_len == npos)
2355  throw std::length_error("Length of char array can not be 'npos'");
2356 
2357  size_type newsz = d_cplength + chars_len;
2358 
2359  grow(newsz);
2360  memmove(&ptr()[idx + chars_len], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2361 
2362  utf32* pt = &ptr()[idx + chars_len - 1];
2363 
2364  while(chars_len--)
2365  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
2366 
2367  setlen(newsz);
2368 
2369  return *this;
2370  }
2371 
2372 
2374  // Erasing characters
2376 
2383  void clear(void)
2384  {
2385  setlen(0);
2386  trim();
2387  }
2388 
2396  String& erase(void)
2397  {
2398  clear();
2399  return *this;
2400  }
2401 
2414  String& erase(size_type idx)
2415  {
2416  return erase(idx, 1);
2417  }
2418 
2434  String& erase(size_type idx, size_type len = npos)
2435  {
2436  if (d_cplength < idx)
2437  throw std::out_of_range("Index is out of range foe CEGUI::String");
2438 
2439  if (len == npos)
2440  len = d_cplength - idx;
2441 
2442  size_type newsz = d_cplength - len;
2443 
2444  memmove(&ptr()[idx], &ptr()[idx + len], (d_cplength - idx - len) * sizeof(utf32));
2445  setlen(newsz);
2446  return *this;
2447  }
2448 
2459  String& erase(iterator pos)
2460  {
2461  return erase(safe_iter_dif(pos, begin()), 1);
2462  }
2463 
2477  String& erase(iterator iter_beg, iterator iter_end)
2478  {
2479  return erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
2480  }
2481 
2483  // Resizing
2485 
2497  void resize(size_type num)
2498  {
2499  resize(num, utf32());
2500  }
2501 
2517  void resize(size_type num, utf32 code_point)
2518  {
2519  if (num < d_cplength)
2520  {
2521  setlen(num);
2522  }
2523  else
2524  {
2525  append(num - d_cplength, code_point);
2526  }
2527 
2528  }
2529 
2531  // Replacing Characters
2533 
2552  String& replace(size_type idx, size_type len, const String& str)
2553  {
2554  return replace(idx, len, str, 0, npos);
2555  }
2556 
2578  String& replace(iterator iter_beg, iterator iter_end, const String& str)
2579  {
2580  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), str, 0, npos);
2581  }
2582 
2608  String& replace(size_type idx, size_type len, const String& str, size_type str_idx, size_type str_num)
2609  {
2610  if ((d_cplength < idx) || (str.d_cplength < str_idx))
2611  throw std::out_of_range("Index is out of range for CEGUI::String");
2612 
2613  if (((str_idx + str_num) > str.d_cplength) || (str_num == npos))
2614  str_num = str.d_cplength - str_idx;
2615 
2616  if (((len + idx) > d_cplength) || (len == npos))
2617  len = d_cplength - idx;
2618 
2619  size_type newsz = d_cplength + str_num - len;
2620 
2621  grow(newsz);
2622 
2623  if ((idx + len) < d_cplength)
2624  memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2625 
2626  memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2627  setlen(newsz);
2628 
2629  return *this;
2630  }
2631 
2632 
2656  String& replace(size_type idx, size_type len, const std::string& std_str)
2657  {
2658  return replace(idx, len, std_str, 0, npos);
2659  }
2660 
2686  String& replace(iterator iter_beg, iterator iter_end, const std::string& std_str)
2687  {
2688  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), std_str, 0, npos);
2689  }
2690 
2720  String& replace(size_type idx, size_type len, const std::string& std_str, size_type str_idx, size_type str_num)
2721  {
2722  if (d_cplength < idx)
2723  throw std::out_of_range("Index is out of range for CEGUI::String");
2724 
2725  if (std_str.size() < str_idx)
2726  throw std::out_of_range("Index is out of range for std::string");
2727 
2728  if (((str_idx + str_num) > std_str.size()) || (str_num == npos))
2729  str_num = (size_type)std_str.size() - str_idx;
2730 
2731  if (((len + idx) > d_cplength) || (len == npos))
2732  len = d_cplength - idx;
2733 
2734  size_type newsz = d_cplength + str_num - len;
2735 
2736  grow(newsz);
2737 
2738  if ((idx + len) < d_cplength)
2739  memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2740 
2741  utf32* pt = &ptr()[idx + str_num - 1];
2742 
2743  while (str_num--)
2744  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2745 
2746  setlen(newsz);
2747 
2748  return *this;
2749  }
2750 
2751 
2777  String& replace(size_type idx, size_type len, const utf8* utf8_str)
2778  {
2779  return replace(idx, len, utf8_str, utf_length(utf8_str));
2780  }
2781 
2809  String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str)
2810  {
2811  return replace(iter_beg, iter_end, utf8_str, utf_length(utf8_str));
2812  }
2813 
2842  String& replace(size_type idx, size_type len, const utf8* utf8_str, size_type str_len)
2843  {
2844  if (d_cplength < idx)
2845  throw std::out_of_range("Index is out of range for CEGUI::String");
2846 
2847  if (str_len == npos)
2848  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
2849 
2850  if (((len + idx) > d_cplength) || (len == npos))
2851  len = d_cplength - idx;
2852 
2853  size_type encsz = encoded_size(utf8_str, str_len);
2854  size_type newsz = d_cplength + encsz - len;
2855 
2856  grow(newsz);
2857 
2858  if ((idx + len) < d_cplength)
2859  memmove(&ptr()[idx + encsz], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2860 
2861  encode(utf8_str, &ptr()[idx], encsz, str_len);
2862 
2863  setlen(newsz);
2864  return *this;
2865  }
2866 
2897  String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str, size_type str_len)
2898  {
2899  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), utf8_str, str_len);
2900  }
2901 
2924  String& replace(size_type idx, size_type len, size_type num, utf32 code_point)
2925  {
2926  if (d_cplength < idx)
2927  throw std::out_of_range("Index is out of range for CEGUI::String");
2928 
2929  if (num == npos)
2930  throw std::length_error("Code point count can not be 'npos'");
2931 
2932  if (((len + idx) > d_cplength) || (len == npos))
2933  len = d_cplength - idx;
2934 
2935  size_type newsz = d_cplength + num - len;
2936 
2937  grow(newsz);
2938 
2939  if ((idx + len) < d_cplength)
2940  memmove(&ptr()[idx + num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2941 
2942  utf32* pt = &ptr()[idx + num - 1];
2943 
2944  while (num--)
2945  *pt-- = code_point;
2946 
2947  setlen(newsz);
2948 
2949  return *this;
2950  }
2951 
2976  String& replace(iterator iter_beg, iterator iter_end, size_type num, utf32 code_point)
2977  {
2978  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), num, code_point);
2979  }
2980 
2981 
3006  String& replace(iterator iter_beg, iterator iter_end, const_iterator iter_newBeg, const_iterator iter_newEnd)
3007  {
3008  if (iter_beg == iter_end)
3009  {
3010  erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
3011  }
3012  else
3013  {
3014  size_type str_len = safe_iter_dif(iter_newEnd, iter_newBeg);
3015  size_type idx = safe_iter_dif(iter_beg, begin());
3016  size_type len = safe_iter_dif(iter_end, iter_beg);
3017 
3018  if ((len + idx) > d_cplength)
3019  len = d_cplength - idx;
3020 
3021  size_type newsz = d_cplength + str_len - len;
3022 
3023  grow(newsz);
3024 
3025  if ((idx + len) < d_cplength)
3026  memmove(&ptr()[idx + str_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
3027 
3028  memcpy(&ptr()[idx], iter_newBeg.d_ptr, str_len * sizeof(utf32));
3029  setlen(newsz);
3030  }
3031 
3032  return *this;
3033  }
3034 
3035 
3055  String& replace(size_type idx, size_type len, const char* cstr)
3056  {
3057  return replace(idx, len, cstr, strlen(cstr));
3058  }
3059 
3060 
3082  String& replace(iterator iter_beg, iterator iter_end, const char* cstr)
3083  {
3084  return replace(iter_beg, iter_end, cstr, strlen(cstr));
3085  }
3086 
3087 
3110  String& replace(size_type idx, size_type len, const char* chars, size_type chars_len)
3111  {
3112  if (d_cplength < idx)
3113  throw std::out_of_range("Index is out of range for CEGUI::String");
3114 
3115  if (chars_len == npos)
3116  throw std::length_error("Length for the char array can not be 'npos'");
3117 
3118  if (((len + idx) > d_cplength) || (len == npos))
3119  len = d_cplength - idx;
3120 
3121  size_type newsz = d_cplength + chars_len - len;
3122 
3123  grow(newsz);
3124 
3125  if ((idx + len) < d_cplength)
3126  memmove(&ptr()[idx + chars_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
3127 
3128  utf32* pt = &ptr()[idx + chars_len - 1];
3129 
3130  while (chars_len--)
3131  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
3132 
3133  setlen(newsz);
3134  return *this;
3135  }
3136 
3137 
3162  String& replace(iterator iter_beg, iterator iter_end, const char* chars, size_type chars_len)
3163  {
3164  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), chars, chars_len);
3165  }
3166 
3167 
3169  // Find a code point
3171 
3185  size_type find(utf32 code_point, size_type idx = 0) const
3186  {
3187  if (idx < d_cplength)
3188  {
3189  const utf32* pt = &ptr()[idx];
3190 
3191  while (idx < d_cplength)
3192  {
3193  if (*pt++ == code_point)
3194  return idx;
3195 
3196  ++idx;
3197  }
3198 
3199  }
3200 
3201  return npos;
3202  }
3203 
3218  size_type rfind(utf32 code_point, size_type idx = npos) const
3219  {
3220  if (idx >= d_cplength)
3221  idx = d_cplength - 1;
3222 
3223  if (d_cplength > 0)
3224  {
3225  const utf32* pt = &ptr()[idx];
3226 
3227  do
3228  {
3229  if (*pt-- == code_point)
3230  return idx;
3231 
3232  } while (idx-- != 0);
3233 
3234  }
3235 
3236  return npos;
3237  }
3238 
3240  // Find a substring
3242 
3256  size_type find(const String& str, size_type idx = 0) const
3257  {
3258  if ((str.d_cplength == 0) && (idx < d_cplength))
3259  return idx;
3260 
3261  if (idx < d_cplength)
3262  {
3263  // loop while search string could fit in to search area
3264  while (d_cplength - idx >= str.d_cplength)
3265  {
3266  if (0 == compare(idx, str.d_cplength, str))
3267  return idx;
3268 
3269  ++idx;
3270  }
3271 
3272  }
3273 
3274  return npos;
3275  }
3276 
3291  size_type rfind(const String& str, size_type idx = npos) const
3292  {
3293  if (str.d_cplength == 0)
3294  return (idx < d_cplength) ? idx : d_cplength;
3295 
3296  if (str.d_cplength <= d_cplength)
3297  {
3298  if (idx > (d_cplength - str.d_cplength))
3299  idx = d_cplength - str.d_cplength;
3300 
3301  do
3302  {
3303  if (0 == compare(idx, str.d_cplength, str))
3304  return idx;
3305 
3306  } while (idx-- != 0);
3307 
3308  }
3309 
3310  return npos;
3311  }
3312 
3331  size_type find(const std::string& std_str, size_type idx = 0) const
3332  {
3333  std::string::size_type sze = std_str.size();
3334 
3335  if ((sze == 0) && (idx < d_cplength))
3336  return idx;
3337 
3338  if (idx < d_cplength)
3339  {
3340  // loop while search string could fit in to search area
3341  while (d_cplength - idx >= sze)
3342  {
3343  if (0 == compare(idx, (size_type)sze, std_str))
3344  return idx;
3345 
3346  ++idx;
3347  }
3348 
3349  }
3350 
3351  return npos;
3352  }
3353 
3372  size_type rfind(const std::string& std_str, size_type idx = npos) const
3373  {
3374  std::string::size_type sze = std_str.size();
3375 
3376  if (sze == 0)
3377  return (idx < d_cplength) ? idx : d_cplength;
3378 
3379  if (sze <= d_cplength)
3380  {
3381  if (idx > (d_cplength - sze))
3382  idx = d_cplength - sze;
3383 
3384  do
3385  {
3386  if (0 == compare(idx, (size_type)sze, std_str))
3387  return idx;
3388 
3389  } while (idx-- != 0);
3390 
3391  }
3392 
3393  return npos;
3394  }
3395 
3418  size_type find(const utf8* utf8_str, size_type idx = 0) const
3419  {
3420  return find(utf8_str, idx, utf_length(utf8_str));
3421  }
3422 
3445  size_type rfind(const utf8* utf8_str, size_type idx = npos) const
3446  {
3447  return rfind(utf8_str, idx, utf_length(utf8_str));
3448  }
3449 
3475  size_type find(const utf8* utf8_str, size_type idx, size_type str_len) const
3476  {
3477  if (str_len == npos)
3478  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3479 
3480  size_type sze = encoded_size(utf8_str, str_len);
3481 
3482  if ((sze == 0) && (idx < d_cplength))
3483  return idx;
3484 
3485  if (idx < d_cplength)
3486  {
3487  // loop while search string could fit in to search area
3488  while (d_cplength - idx >= sze)
3489  {
3490  if (0 == compare(idx, sze, utf8_str, sze))
3491  return idx;
3492 
3493  ++idx;
3494  }
3495 
3496  }
3497 
3498  return npos;
3499  }
3500 
3526  size_type rfind(const utf8* utf8_str, size_type idx, size_type str_len) const
3527  {
3528  if (str_len == npos)
3529  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3530 
3531  size_type sze = encoded_size(utf8_str, str_len);
3532 
3533  if (sze == 0)
3534  return (idx < d_cplength) ? idx : d_cplength;
3535 
3536  if (sze <= d_cplength)
3537  {
3538  if (idx > (d_cplength - sze))
3539  idx = d_cplength - sze;
3540 
3541  do
3542  {
3543  if (0 == compare(idx, sze, utf8_str, sze))
3544  return idx;
3545 
3546  } while (idx-- != 0);
3547 
3548  }
3549 
3550  return npos;
3551  }
3552 
3553 
3570  size_type find(const char* cstr, size_type idx = 0) const
3571  {
3572  return find(cstr, idx, strlen(cstr));
3573  }
3574 
3575 
3592  size_type rfind(const char* cstr, size_type idx = npos) const
3593  {
3594  return rfind(cstr, idx, strlen(cstr));
3595  }
3596 
3597 
3617  size_type find(const char* chars, size_type idx, size_type chars_len) const
3618  {
3619  if (chars_len == npos)
3620  throw std::length_error("Length for char array can not be 'npos'");
3621 
3622  if ((chars_len == 0) && (idx < d_cplength))
3623  return idx;
3624 
3625  if (idx < d_cplength)
3626  {
3627  // loop while search string could fit in to search area
3628  while (d_cplength - idx >= chars_len)
3629  {
3630  if (0 == compare(idx, chars_len, chars, chars_len))
3631  return idx;
3632 
3633  ++idx;
3634  }
3635 
3636  }
3637 
3638  return npos;
3639  }
3640 
3641 
3661  size_type rfind(const char* chars, size_type idx, size_type chars_len) const
3662  {
3663  if (chars_len == npos)
3664  throw std::length_error("Length for char array can not be 'npos'");
3665 
3666  if (chars_len == 0)
3667  return (idx < d_cplength) ? idx : d_cplength;
3668 
3669  if (chars_len <= d_cplength)
3670  {
3671  if (idx > (d_cplength - chars_len))
3672  idx = d_cplength - chars_len;
3673 
3674  do
3675  {
3676  if (0 == compare(idx, chars_len, chars, chars_len))
3677  return idx;
3678 
3679  } while (idx-- != 0);
3680 
3681  }
3682 
3683  return npos;
3684  }
3685 
3686 
3688  // Find first of different code-points
3690 
3704  size_type find_first_of(const String& str, size_type idx = 0) const
3705  {
3706  if (idx < d_cplength)
3707  {
3708  const utf32* pt = &ptr()[idx];
3709 
3710  do
3711  {
3712  if (npos != str.find(*pt++))
3713  return idx;
3714 
3715  } while (++idx != d_cplength);
3716 
3717  }
3718 
3719  return npos;
3720  }
3721 
3736  size_type find_first_not_of(const String& str, size_type idx = 0) const
3737  {
3738  if (idx < d_cplength)
3739  {
3740  const utf32* pt = &ptr()[idx];
3741 
3742  do
3743  {
3744  if (npos == str.find(*pt++))
3745  return idx;
3746 
3747  } while (++idx != d_cplength);
3748 
3749  }
3750 
3751  return npos;
3752  }
3753 
3754 
3773  size_type find_first_of(const std::string& std_str, size_type idx = 0) const
3774  {
3775  if (idx < d_cplength)
3776  {
3777  const utf32* pt = &ptr()[idx];
3778 
3779  do
3780  {
3781  if (npos != find_codepoint(std_str, *pt++))
3782  return idx;
3783 
3784  } while (++idx != d_cplength);
3785 
3786  }
3787 
3788  return npos;
3789  }
3790 
3809  size_type find_first_not_of(const std::string& std_str, size_type idx = 0) const
3810  {
3811  if (idx < d_cplength)
3812  {
3813  const utf32* pt = &ptr()[idx];
3814 
3815  do
3816  {
3817  if (npos == find_codepoint(std_str, *pt++))
3818  return idx;
3819 
3820  } while (++idx != d_cplength);
3821 
3822  }
3823 
3824  return npos;
3825  }
3826 
3827 
3850  size_type find_first_of(const utf8* utf8_str, size_type idx = 0) const
3851  {
3852  return find_first_of(utf8_str, idx, utf_length(utf8_str));
3853  }
3854 
3877  size_type find_first_not_of(const utf8* utf8_str, size_type idx = 0) const
3878  {
3879  return find_first_not_of(utf8_str, idx, utf_length(utf8_str));
3880  }
3881 
3907  size_type find_first_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3908  {
3909  if (str_len == npos)
3910  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3911 
3912  if (idx < d_cplength)
3913  {
3914  size_type encsze = encoded_size(utf8_str, str_len);
3915 
3916  const utf32* pt = &ptr()[idx];
3917 
3918  do
3919  {
3920  if (npos != find_codepoint(utf8_str, encsze, *pt++))
3921  return idx;
3922 
3923  } while (++idx != d_cplength);
3924 
3925  }
3926 
3927  return npos;
3928  }
3929 
3955  size_type find_first_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3956  {
3957  if (str_len == npos)
3958  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3959 
3960  if (idx < d_cplength)
3961  {
3962  size_type encsze = encoded_size(utf8_str, str_len);
3963 
3964  const utf32* pt = &ptr()[idx];
3965 
3966  do
3967  {
3968  if (npos == find_codepoint(utf8_str, encsze, *pt++))
3969  return idx;
3970 
3971  } while (++idx != d_cplength);
3972 
3973  }
3974 
3975  return npos;
3976  }
3977 
3978 
3993  size_type find_first_of(utf32 code_point, size_type idx = 0) const
3994  {
3995  return find(code_point, idx);
3996  }
3997 
4014  size_type find_first_not_of(utf32 code_point, size_type idx = 0) const
4015  {
4016  if (idx < d_cplength)
4017  {
4018  do
4019  {
4020  if ((*this)[idx] != code_point)
4021  return idx;
4022 
4023  } while(idx++ < d_cplength);
4024 
4025  }
4026 
4027  return npos;
4028  }
4029 
4030 
4047  size_type find_first_of(const char* cstr, size_type idx = 0) const
4048  {
4049  return find_first_of(cstr, idx, strlen(cstr));
4050  }
4051 
4052 
4069  size_type find_first_not_of(const char* cstr, size_type idx = 0) const
4070  {
4071  return find_first_not_of(cstr, idx, strlen(cstr));
4072  }
4073 
4074 
4094  size_type find_first_of(const char* chars, size_type idx, size_type chars_len) const
4095  {
4096  if (chars_len == npos)
4097  throw std::length_error("Length for char array can not be 'npos'");
4098 
4099  if (idx < d_cplength)
4100  {
4101  const utf32* pt = &ptr()[idx];
4102 
4103  do
4104  {
4105  if (npos != find_codepoint(chars, chars_len, *pt++))
4106  return idx;
4107 
4108  } while (++idx != d_cplength);
4109 
4110  }
4111 
4112  return npos;
4113  }
4114 
4115 
4135  size_type find_first_not_of(const char* chars, size_type idx, size_type chars_len) const
4136  {
4137  if (chars_len == npos)
4138  throw std::length_error("Length for char array can not be 'npos'");
4139 
4140  if (idx < d_cplength)
4141  {
4142  const utf32* pt = &ptr()[idx];
4143 
4144  do
4145  {
4146  if (npos == find_codepoint(chars, chars_len, *pt++))
4147  return idx;
4148 
4149  } while (++idx != d_cplength);
4150 
4151  }
4152 
4153  return npos;
4154  }
4155 
4156 
4158  // Find last of different code-points
4160 
4174  size_type find_last_of(const String& str, size_type idx = npos) const
4175  {
4176  if (d_cplength > 0)
4177  {
4178  if (idx >= d_cplength)
4179  idx = d_cplength - 1;
4180 
4181  const utf32* pt = &ptr()[idx];
4182 
4183  do
4184  {
4185  if (npos != str.find(*pt--))
4186  return idx;
4187 
4188  } while (idx-- != 0);
4189 
4190  }
4191 
4192  return npos;
4193  }
4194 
4209  size_type find_last_not_of(const String& str, size_type idx = npos) const
4210  {
4211  if (d_cplength > 0)
4212  {
4213  if (idx >= d_cplength)
4214  idx = d_cplength - 1;
4215 
4216  const utf32* pt = &ptr()[idx];
4217 
4218  do
4219  {
4220  if (npos == str.find(*pt--))
4221  return idx;
4222 
4223  } while (idx-- != 0);
4224 
4225  }
4226 
4227  return npos;
4228  }
4229 
4230 
4249  size_type find_last_of(const std::string& std_str, size_type idx = npos) const
4250  {
4251  if (d_cplength > 0)
4252  {
4253  if (idx >= d_cplength)
4254  idx = d_cplength - 1;
4255 
4256  const utf32* pt = &ptr()[idx];
4257 
4258  do
4259  {
4260  if (npos != find_codepoint(std_str, *pt--))
4261  return idx;
4262 
4263  } while (idx-- != 0);
4264 
4265  }
4266 
4267  return npos;
4268  }
4269 
4288  size_type find_last_not_of(const std::string& std_str, size_type idx = npos) const
4289  {
4290  if (d_cplength > 0)
4291  {
4292  if (idx >= d_cplength)
4293  idx = d_cplength - 1;
4294 
4295  const utf32* pt = &ptr()[idx];
4296 
4297  do
4298  {
4299  if (npos == find_codepoint(std_str, *pt--))
4300  return idx;
4301 
4302  } while (idx-- != 0);
4303 
4304  }
4305 
4306  return npos;
4307  }
4308 
4309 
4332  size_type find_last_of(const utf8* utf8_str, size_type idx = npos) const
4333  {
4334  return find_last_of(utf8_str, idx, utf_length(utf8_str));
4335  }
4336 
4359  size_type find_last_not_of(const utf8* utf8_str, size_type idx = npos) const
4360  {
4361  return find_last_not_of(utf8_str, idx, utf_length(utf8_str));
4362  }
4363 
4389  size_type find_last_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4390  {
4391  if (str_len == npos)
4392  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
4393 
4394  if (d_cplength > 0)
4395  {
4396  if (idx >= d_cplength)
4397  idx = d_cplength - 1;
4398 
4399  size_type encsze = encoded_size(utf8_str, str_len);
4400 
4401  const utf32* pt = &ptr()[idx];
4402 
4403  do
4404  {
4405  if (npos != find_codepoint(utf8_str, encsze, *pt--))
4406  return idx;
4407 
4408  } while (idx-- != 0);
4409 
4410  }
4411 
4412  return npos;
4413  }
4414 
4440  size_type find_last_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4441  {
4442  if (str_len == npos)
4443  throw std::length_error("Length for utf8 encoded string can not be 'npos'");
4444 
4445  if (d_cplength > 0)
4446  {
4447  if (idx >= d_cplength)
4448  idx = d_cplength - 1;
4449 
4450  size_type encsze = encoded_size(utf8_str, str_len);
4451 
4452  const utf32* pt = &ptr()[idx];
4453 
4454  do
4455  {
4456  if (npos == find_codepoint(utf8_str, encsze, *pt--))
4457  return idx;
4458 
4459  } while (idx-- != 0);
4460 
4461  }
4462 
4463  return npos;
4464  }
4465 
4466 
4481  size_type find_last_of(utf32 code_point, size_type idx = npos) const
4482  {
4483  return rfind(code_point, idx);
4484  }
4485 
4500  size_type find_last_not_of(utf32 code_point, size_type idx = npos) const
4501  {
4502  if (d_cplength > 0)
4503  {
4504  if (idx >= d_cplength)
4505  idx = d_cplength - 1;
4506 
4507  do
4508  {
4509  if ((*this)[idx] != code_point)
4510  return idx;
4511 
4512  } while(idx-- != 0);
4513 
4514  }
4515 
4516  return npos;
4517  }
4518 
4519 
4536  size_type find_last_of(const char* cstr, size_type idx = npos) const
4537  {
4538  return find_last_of(cstr, idx, strlen(cstr));
4539  }
4540 
4541 
4558  size_type find_last_not_of(const char* cstr, size_type idx = npos) const
4559  {
4560  return find_last_not_of(cstr, idx, strlen(cstr));
4561  }
4562 
4563 
4583  size_type find_last_of(const char* chars, size_type idx, size_type chars_len) const
4584  {
4585  if (chars_len == npos)
4586  throw std::length_error("Length for char array can not be 'npos'");
4587 
4588  if (d_cplength > 0)
4589  {
4590  if (idx >= d_cplength)
4591  idx = d_cplength - 1;
4592 
4593  const utf32* pt = &ptr()[idx];
4594 
4595  do
4596  {
4597  if (npos != find_codepoint(chars, chars_len, *pt--))
4598  return idx;
4599 
4600  } while (idx-- != 0);
4601 
4602  }
4603 
4604  return npos;
4605  }
4606 
4607 
4627  size_type find_last_not_of(const char* chars, size_type idx, size_type chars_len) const
4628  {
4629  if (chars_len == npos)
4630  throw std::length_error("Length for char array can not be 'npos'");
4631 
4632  if (d_cplength > 0)
4633  {
4634  if (idx >= d_cplength)
4635  idx = d_cplength - 1;
4636 
4637  const utf32* pt = &ptr()[idx];
4638 
4639  do
4640  {
4641  if (npos == find_codepoint(chars, chars_len, *pt--))
4642  return idx;
4643 
4644  } while (idx-- != 0);
4645 
4646  }
4647 
4648  return npos;
4649  }
4650 
4651 
4653  // Substring
4655 
4670  String substr(size_type idx = 0, size_type len = npos) const
4671  {
4672  if (d_cplength < idx)
4673  throw std::out_of_range("Index is out of range for this CEGUI::String");
4674 
4675  return String(*this, idx, len);
4676  }
4677 
4679  // Iterator creation
4681 
4688  iterator begin(void)
4689  {
4690  return iterator(ptr());
4691  }
4692 
4700  const_iterator begin(void) const
4701  {
4702  return const_iterator(ptr());
4703  }
4704 
4712  iterator end(void)
4713  {
4714  return iterator(&ptr()[d_cplength]);
4715  }
4716 
4724  const_iterator end(void) const
4725  {
4726  return const_iterator(&ptr()[d_cplength]);
4727  }
4728 
4736  reverse_iterator rbegin(void)
4737  {
4738  return reverse_iterator(end());
4739  }
4740 
4748  const_reverse_iterator rbegin(void) const
4749  {
4750  return const_reverse_iterator(end());
4751  }
4752 
4760  reverse_iterator rend(void)
4761  {
4762  return reverse_iterator(begin());
4763  }
4764 
4772  const_reverse_iterator rend(void) const
4773  {
4774  return const_reverse_iterator(begin());
4775  }
4776 
4777 private:
4778  /*************************************************************************
4779  Implementation Functions
4780  *************************************************************************/
4781  // string management
4782 
4783  // change size of allocated buffer so it is at least 'new_size'.
4784  // May or may not cause re-allocation and copy of buffer if size is larger
4785  // will never re-allocate to make size smaller. (see trim())
4786  bool grow(size_type new_size);
4787 
4788  // perform re-allocation to remove wasted space.
4789  void trim(void);
4790 
4791  // set the length of the string, and terminate it, according to the given value (will not re-allocate, use grow() first).
4792  void setlen(size_type len)
4793  {
4794  d_cplength = len;
4795  ptr()[len] = (utf32)(0);
4796  }
4797 
4798  // initialise string object
4799  void init(void)
4800  {
4801  d_reserve = STR_QUICKBUFF_SIZE;
4802  d_encodedbuff = 0;
4803  d_encodedbufflen = 0;
4804  d_encodeddatlen = 0;
4805  d_buffer = 0;
4806  setlen(0);
4807  }
4808 
4809  // return true if the given pointer is inside the string data
4810  bool inside(utf32* inptr)
4811  {
4812  if (inptr < ptr() || ptr() + d_cplength <= inptr)
4813  return false;
4814  else
4815  return true;
4816  }
4817 
4818  // compute distance between two iterators, returning a 'safe' value
4819  size_type safe_iter_dif(const const_iterator& iter1, const const_iterator& iter2) const
4820  {
4821  return (iter1.d_ptr == 0) ? 0 : (iter1 - iter2);
4822  }
4823 
4824  // encoding functions
4825  // for all:
4826  // src_len is in code units, or 0 for null terminated string.
4827  // dest_len is in code units.
4828  // returns number of code units put into dest buffer.
4829  size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
4830  {
4831  // count length for null terminated source...
4832  if (src_len == 0)
4833  {
4834  src_len = utf_length(src);
4835  }
4836 
4837  size_type destCapacity = dest_len;
4838 
4839  // while there is data in the source buffer,
4840  for (uint idx = 0; idx < src_len; ++idx)
4841  {
4842  utf32 cp = src[idx];
4843 
4844  // check there is enough destination buffer to receive this encoded unit (exit loop & return if not)
4845  if (destCapacity < encoded_size(cp))
4846  {
4847  break;
4848  }
4849 
4850  if (cp < 0x80)
4851  {
4852  *dest++ = (utf8)cp;
4853  --destCapacity;
4854  }
4855  else if (cp < 0x0800)
4856  {
4857  *dest++ = (utf8)((cp >> 6) | 0xC0);
4858  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4859  destCapacity -= 2;
4860  }
4861  else if (cp < 0x10000)
4862  {
4863  *dest++ = (utf8)((cp >> 12) | 0xE0);
4864  *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4865  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4866  destCapacity -= 3;
4867  }
4868  else
4869  {
4870  *dest++ = (utf8)((cp >> 18) | 0xF0);
4871  *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
4872  *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4873  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4874  destCapacity -= 4;
4875  }
4876 
4877  }
4878 
4879  return dest_len - destCapacity;
4880  }
4881 
4882  size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
4883  {
4884  // count length for null terminated source...
4885  if (src_len == 0)
4886  {
4887  src_len = utf_length(src);
4888  }
4889 
4890  size_type destCapacity = dest_len;
4891 
4892  // while there is data in the source buffer, and space in the dest buffer
4893  for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
4894  {
4895  utf32 cp;
4896  utf8 cu = src[idx++];
4897 
4898  if (cu < 0x80)
4899  {
4900  cp = (utf32)(cu);
4901  }
4902  else if (cu < 0xE0)
4903  {
4904  cp = ((cu & 0x1F) << 6);
4905  cp |= (src[idx++] & 0x3F);
4906  }
4907  else if (cu < 0xF0)
4908  {
4909  cp = ((cu & 0x0F) << 12);
4910  cp |= ((src[idx++] & 0x3F) << 6);
4911  cp |= (src[idx++] & 0x3F);
4912  }
4913  else
4914  {
4915  cp = ((cu & 0x07) << 18);
4916  cp |= ((src[idx++] & 0x3F) << 12);
4917  cp |= ((src[idx++] & 0x3F) << 6);
4918  cp |= (src[idx++] & 0x3F);
4919  }
4920 
4921  *dest++ = cp;
4922  --destCapacity;
4923  }
4924 
4925  return dest_len - destCapacity;
4926  }
4927 
4928  // return the number of utf8 code units required to encode the given utf32 code point
4929  size_type encoded_size(utf32 code_point) const
4930  {
4931  if (code_point < 0x80)
4932  return 1;
4933  else if (code_point < 0x0800)
4934  return 2;
4935  else if (code_point < 0x10000)
4936  return 3;
4937  else
4938  return 4;
4939  }
4940 
4941  // return number of code units required to re-encode given null-terminated utf32 data as utf8. return does not include terminating null.
4942  size_type encoded_size(const utf32* buf) const
4943  {
4944  return encoded_size(buf, utf_length(buf));
4945  }
4946 
4947  // return number of code units required to re-encode given utf32 data as utf8. len is number of code units in 'buf'.
4948  size_type encoded_size(const utf32* buf, size_type len) const
4949  {
4950  size_type count = 0;
4951 
4952  while (len--)
4953  {
4954  count += encoded_size(*buf++);
4955  }
4956 
4957  return count;
4958  }
4959 
4960  // return number of utf32 code units required to re-encode given utf8 data as utf32. return does not include terminating null.
4961  size_type encoded_size(const utf8* buf) const
4962  {
4963  return encoded_size(buf, utf_length(buf));
4964  }
4965 
4966  // return number of utf32 code units required to re-encode given utf8 data as utf32. len is number of code units in 'buf'.
4967  size_type encoded_size(const utf8* buf, size_type len) const
4968  {
4969  utf8 tcp;
4970  size_type count = 0;
4971 
4972  while (len--)
4973  {
4974  tcp = *buf++;
4975  ++count;
4976 
4977  if (tcp < 0x80)
4978  {
4979  }
4980  else if (tcp < 0xE0)
4981  {
4982  --len;
4983  ++buf;
4984  }
4985  else if (tcp < 0xF0)
4986  {
4987  len -= 2;
4988  buf += 2;
4989  }
4990  else
4991  {
4992  len -= 2;
4993  buf += 3;
4994  }
4995 
4996  }
4997 
4998  return count;
4999  }
5000 
5001  // return number of code units in a null terminated string
5002  size_type utf_length(const utf8* utf8_str) const
5003  {
5004  size_type cnt = 0;
5005  while (*utf8_str++)
5006  cnt++;
5007 
5008  return cnt;
5009  }
5010 
5011  // return number of code units in a null terminated string
5012  size_type utf_length(const utf32* utf32_str) const
5013  {
5014  size_type cnt = 0;
5015  while (*utf32_str++)
5016  cnt++;
5017 
5018  return cnt;
5019  }
5020 
5021  // build an internal buffer with the string encoded as utf8 (remains valid until string is modified).
5022  utf8* build_utf8_buff(void) const;
5023 
5024  // compare two utf32 buffers
5025  int utf32_comp_utf32(const utf32* buf1, const utf32* buf2, size_type cp_count) const
5026  {
5027  if (!cp_count)
5028  return 0;
5029 
5030  while ((--cp_count) && (*buf1 == *buf2))
5031  buf1++, buf2++;
5032 
5033  return *buf1 - *buf2;
5034  }
5035 
5036  // compare utf32 buffer with char buffer (chars are taken to be code-points in the range 0x00-0xFF)
5037  int utf32_comp_char(const utf32* buf1, const char* buf2, size_type cp_count) const
5038  {
5039  if (!cp_count)
5040  return 0;
5041 
5042  while ((--cp_count) && (*buf1 == static_cast<utf32>(static_cast<unsigned char>(*buf2))))
5043  buf1++, buf2++;
5044 
5045  return *buf1 - static_cast<utf32>(static_cast<unsigned char>(*buf2));
5046  }
5047 
5048  // compare utf32 buffer with encoded utf8 data
5049  int utf32_comp_utf8(const utf32* buf1, const utf8* buf2, size_type cp_count) const
5050  {
5051  if (!cp_count)
5052  return 0;
5053 
5054  utf32 cp;
5055  utf8 cu;
5056 
5057  do
5058  {
5059  cu = *buf2++;
5060 
5061  if (cu < 0x80)
5062  {
5063  cp = (utf32)(cu);
5064  }
5065  else if (cu < 0xE0)
5066  {
5067  cp = ((cu & 0x1F) << 6);
5068  cp |= (*buf2++ & 0x3F);
5069  }
5070  else if (cu < 0xF0)
5071  {
5072  cp = ((cu & 0x0F) << 12);
5073  cp |= ((*buf2++ & 0x3F) << 6);
5074  cp |= (*buf2++ & 0x3F);
5075  }
5076  else
5077  {
5078  cp = ((cu & 0x07) << 18);
5079  cp |= ((*buf2++ & 0x3F) << 12);
5080  cp |= ((*buf2++ & 0x3F) << 6);
5081  cp |= (*buf2++ & 0x3F);
5082  }
5083 
5084  } while ((*buf1++ == cp) && (--cp_count));
5085 
5086  return (*--buf1) - cp;
5087  }
5088 
5089  // return index of first occurrence of 'code_point' in std::string 'str', or npos if none
5090  size_type find_codepoint(const std::string& str, utf32 code_point) const
5091  {
5092  size_type idx = 0, sze = (size_type)str.size();
5093 
5094  while (idx != sze)
5095  {
5096  if (code_point == static_cast<utf32>(static_cast<unsigned char>(str[idx])))
5097  return idx;
5098 
5099  ++idx;
5100  }
5101 
5102  return npos;
5103  }
5104 
5105  // return index of first occurrence of 'code_point' in utf8 encoded string 'str', or npos if none. len is in code points.
5106  size_type find_codepoint(const utf8* str, size_type len, utf32 code_point) const
5107  {
5108  size_type idx = 0;
5109 
5110  utf32 cp;
5111  utf8 cu;
5112 
5113  while (idx != len) {
5114  cu = *str++;
5115 
5116  if (cu < 0x80)
5117  {
5118  cp = (utf32)(cu);
5119  }
5120  else if (cu < 0xE0)
5121  {
5122  cp = ((cu & 0x1F) << 6);
5123  cp |= (*str++ & 0x3F);
5124  }
5125  else if (cu < 0xF0)
5126  {
5127  cp = ((cu & 0x0F) << 12);
5128  cp |= ((*str++ & 0x3F) << 6);
5129  cp |= (*str++ & 0x3F);
5130  }
5131  else
5132  {
5133  cp = ((cu & 0x07) << 18);
5134  cp |= ((*str++ & 0x3F) << 12);
5135  cp |= ((*str++ & 0x3F) << 6);
5136  cp |= (*str++ & 0x3F);
5137  }
5138 
5139  if (code_point == cp)
5140  return idx;
5141 
5142  ++idx;
5143  }
5144 
5145  return npos;
5146  }
5147 
5148 
5149  // return index of first occurrence of 'code_point' in char array 'chars', or npos if none
5150  size_type find_codepoint(const char* chars, size_type chars_len, utf32 code_point) const
5151  {
5152  for (size_type idx = 0; idx != chars_len; ++idx)
5153  {
5154  if (code_point == static_cast<utf32>(static_cast<unsigned char>(chars[idx])))
5155  return idx;
5156  }
5157 
5158  return npos;
5159  }
5160 
5161 };
5162 
5163 
5165 // Comparison operators
5167 
5171 bool CEGUIEXPORT operator==(const String& str1, const String& str2);
5172 
5177 bool CEGUIEXPORT operator==(const String& str, const std::string& std_str);
5178 
5183 bool CEGUIEXPORT operator==(const std::string& std_str, const String& str);
5184 
5189 bool CEGUIEXPORT operator==(const String& str, const utf8* utf8_str);
5190 
5195 bool CEGUIEXPORT operator==(const utf8* utf8_str, const String& str);
5196 
5201 bool CEGUIEXPORT operator!=(const String& str1, const String& str2);
5202 
5207 bool CEGUIEXPORT operator!=(const String& str, const std::string& std_str);
5208 
5213 bool CEGUIEXPORT operator!=(const std::string& std_str, const String& str);
5214 
5219 bool CEGUIEXPORT operator!=(const String& str, const utf8* utf8_str);
5220 
5225 bool CEGUIEXPORT operator!=(const utf8* utf8_str, const String& str);
5226 
5231 bool CEGUIEXPORT operator<(const String& str1, const String& str2);
5232 
5237 bool CEGUIEXPORT operator<(const String& str, const std::string& std_str);
5238 
5243 bool CEGUIEXPORT operator<(const std::string& std_str, const String& str);
5244 
5249 bool CEGUIEXPORT operator<(const String& str, const utf8* utf8_str);
5250 
5255 bool CEGUIEXPORT operator<(const utf8* utf8_str, const String& str);
5256 
5261 bool CEGUIEXPORT operator>(const String& str1, const String& str2);
5262 
5267 bool CEGUIEXPORT operator>(const String& str, const std::string& std_str);
5268 
5273 bool CEGUIEXPORT operator>(const std::string& std_str, const String& str);
5274 
5279 bool CEGUIEXPORT operator>(const String& str, const utf8* utf8_str);
5280 
5285 bool CEGUIEXPORT operator>(const utf8* utf8_str, const String& str);
5286 
5291 bool CEGUIEXPORT operator<=(const String& str1, const String& str2);
5292 
5297 bool CEGUIEXPORT operator<=(const String& str, const std::string& std_str);
5298 
5303 bool CEGUIEXPORT operator<=(const std::string& std_str, const String& str);
5304 
5309 bool CEGUIEXPORT operator<=(const String& str, const utf8* utf8_str);
5310 
5315 bool CEGUIEXPORT operator<=(const utf8* utf8_str, const String& str);
5316 
5321 bool CEGUIEXPORT operator>=(const String& str1, const String& str2);
5322 
5327 bool CEGUIEXPORT operator>=(const String& str, const std::string& std_str);
5328 
5333 bool CEGUIEXPORT operator>=(const std::string& std_str, const String& str);
5334 
5339 bool CEGUIEXPORT operator>=(const String& str, const utf8* utf8_str);
5340 
5345 bool CEGUIEXPORT operator>=(const utf8* utf8_str, const String& str);
5346 
5351 bool CEGUIEXPORT operator==(const String& str, const char* c_str);
5352 
5357 bool CEGUIEXPORT operator==(const char* c_str, const String& str);
5358 
5363 bool CEGUIEXPORT operator!=(const String& str, const char* c_str);
5364 
5369 bool CEGUIEXPORT operator!=(const char* c_str, const String& str);
5370 
5375 bool CEGUIEXPORT operator<(const String& str, const char* c_str);
5376 
5381 bool CEGUIEXPORT operator<(const char* c_str, const String& str);
5382 
5387 bool CEGUIEXPORT operator>(const String& str, const char* c_str);
5388 
5393 bool CEGUIEXPORT operator>(const char* c_str, const String& str);
5394 
5399 bool CEGUIEXPORT operator<=(const String& str, const char* c_str);
5400 
5405 bool CEGUIEXPORT operator<=(const char* c_str, const String& str);
5406 
5411 bool CEGUIEXPORT operator>=(const String& str, const char* c_str);
5412 
5417 bool CEGUIEXPORT operator>=(const char* c_str, const String& str);
5418 
5420 // Concatenation operator functions
5422 
5437 String CEGUIEXPORT operator+(const String& str1, const String& str2);
5438 
5454 String CEGUIEXPORT operator+(const String& str, const std::string& std_str);
5455 
5471 String CEGUIEXPORT operator+(const std::string& std_str, const String& str);
5472 
5488 String CEGUIEXPORT operator+(const String& str, const utf8* utf8_str);
5489 
5505 String CEGUIEXPORT operator+(const utf8* utf8_str, const String& str);
5506 
5522 String CEGUIEXPORT operator+(const String& str, utf32 code_point);
5523 
5539 String CEGUIEXPORT operator+(utf32 code_point, const String& str);
5540 
5556 String CEGUIEXPORT operator+(const String& str, const char* c_str);
5557 
5573 String CEGUIEXPORT operator+(const char* c_str, const String& str);
5574 
5575 
5577 // Output (stream) functions
5579 CEGUIEXPORT std::ostream& operator<<(std::ostream& s, const String& str);
5580 
5581 
5583 // Modifying operations
5585 
5598 void CEGUIEXPORT swap(String& str1, String& str2);
5599 
5600 
5601 } // End of CEGUI namespace section
5602 
5603 
5604 #endif // end of guard _CEGUIString_h_