Crazy Eddie's GUI System  0.8.5
String.h
1 /***********************************************************************
2  created: 26/2/2004
3  author: Paul D Turner
4 
5  purpose: Defines string class used within the GUI system.
6 *************************************************************************/
7 /***************************************************************************
8  * Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining
11  * a copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sublicense, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifndef _String_h_
30 #define _String_h_
31 
32 #include "CEGUI/Base.h"
33 #include <cstring>
34 #include <stdexcept>
35 #include <cstddef>
36 
37 // Start of CEGUI namespace section
38 namespace CEGUI
39 {
40 /*************************************************************************
41 Basic Types
42 *************************************************************************/
43 typedef uint8 utf8;
44 //typedef uint16 utf16; // removed typedef to prevent usage, as utf16 is not supported (yet)
45 typedef uint32 utf32;
46 
47 #if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_UNICODE
48 
50 typedef utf8 encoded_char;
51 
52 #define CEGUI_STR_QUICKBUFF_SIZE 32
53 
62 class CEGUIEXPORT String :
63  public AllocatedObject<String>
64 {
65 public:
66  /*************************************************************************
67  Integral Types
68  *************************************************************************/
69  typedef utf32 value_type;
70  typedef size_t size_type;
71  typedef std::ptrdiff_t difference_type;
72  typedef utf32& reference;
73  typedef const utf32& const_reference;
74  typedef utf32* pointer;
75  typedef const utf32* const_pointer;
76 
77  static const size_type npos;
78 
79 private:
80  /*************************************************************************
81  Implementation data
82  *************************************************************************/
83  size_type d_cplength;
84  size_type d_reserve;
85 
86  mutable utf8* d_encodedbuff;
87  mutable size_type d_encodeddatlen;
88  mutable size_type d_encodedbufflen;
89 
90  utf32 d_quickbuff[CEGUI_STR_QUICKBUFF_SIZE];
91  utf32* d_buffer;
92 
93 public:
94  /*************************************************************************
95  Iterator Classes
96  *************************************************************************/
98  class iterator : public std::iterator<std::random_access_iterator_tag, utf32>
99  {
100  public:
101  iterator() : d_ptr(0) {}
102  explicit iterator(utf32* const ptr) : d_ptr(ptr) {}
103 
104  utf32& operator*() const
105  {
106  return *d_ptr;
107  }
108 
109  utf32* operator->() const
110  {
111  return &**this;
112  }
113 
114  String::iterator& operator++()
115  {
116  ++d_ptr;
117  return *this;
118  }
119 
120  String::iterator operator++(int)
121  {
122  String::iterator temp = *this;
123  ++*this;
124  return temp;
125  }
126 
127  String::iterator& operator--()
128  {
129  --d_ptr;
130  return *this;
131  }
132 
133  String::iterator operator--(int)
134  {
135  String::iterator temp = *this;
136  --*this;
137  return temp;
138  }
139 
140  String::iterator& operator+=(difference_type offset)
141  {
142  d_ptr += offset;
143  return *this;
144  }
145 
146  String::iterator operator+(difference_type offset) const
147  {
148  String::iterator temp = *this;
149  return temp += offset;
150  }
151 
152  String::iterator& operator-=(difference_type offset)
153  {
154  return *this += -offset;
155  }
156 
157  String::iterator operator-(difference_type offset) const
158  {
159  String::iterator temp = *this;
160  return temp -= offset;
161  }
162 
163  utf32& operator[](difference_type offset) const
164  {
165  return *(*this + offset);
166  }
167 
168  friend difference_type operator-(const String::iterator& lhs,
169  const String::iterator& rhs)
170  { return lhs.d_ptr - rhs.d_ptr; }
171 
172  friend String::iterator operator+(difference_type offset, const String::iterator& iter)
173  { return iter + offset; }
174 
175  friend bool operator==(const String::iterator& lhs,
176  const String::iterator& rhs)
177  { return lhs.d_ptr == rhs.d_ptr; }
178 
179  friend bool operator!=(const String::iterator& lhs,
180  const String::iterator& rhs)
181  { return lhs.d_ptr != rhs.d_ptr; }
182 
183  friend bool operator<(const String::iterator& lhs,
184  const String::iterator& rhs)
185  { return lhs.d_ptr < rhs.d_ptr; }
186 
187  friend bool operator>(const String::iterator& lhs,
188  const String::iterator& rhs)
189  { return lhs.d_ptr > rhs.d_ptr; }
190 
191  friend bool operator<=(const String::iterator& lhs,
192  const String::iterator& rhs)
193  { return lhs.d_ptr <= rhs.d_ptr; }
194 
195  friend bool operator>=(const String::iterator& lhs,
196  const String::iterator& rhs)
197  { return lhs.d_ptr >= rhs.d_ptr; }
198 
199  utf32* d_ptr;
200  };
201 
203  class const_iterator : public std::iterator<std::random_access_iterator_tag, const utf32>
204  {
205  public:
206  const_iterator() : d_ptr(0) {}
207  explicit const_iterator(const utf32* const ptr) : d_ptr(ptr) {}
208  const_iterator(const String::iterator& iter) : d_ptr(iter.d_ptr) {}
209 
210  const utf32& operator*() const
211  {
212  return *d_ptr;
213  }
214 
215  const utf32* operator->() const
216  {
217  return &**this;
218  }
219 
220  String::const_iterator& operator++()
221  {
222  ++d_ptr;
223  return *this;
224  }
225 
226  String::const_iterator operator++(int)
227  {
228  String::const_iterator temp = *this;
229  ++*this;
230  return temp;
231  }
232 
233  String::const_iterator& operator--()
234  {
235  --d_ptr;
236  return *this;
237  }
238 
239  String::const_iterator operator--(int)
240  {
241  String::const_iterator temp = *this;
242  --*this;
243  return temp;
244  }
245 
246  String::const_iterator& operator+=(difference_type offset)
247  {
248  d_ptr += offset;
249  return *this;
250  }
251 
252  String::const_iterator operator+(difference_type offset) const
253  {
254  String::const_iterator temp = *this;
255  return temp += offset;
256  }
257 
258  String::const_iterator& operator-=(difference_type offset)
259  {
260  return *this += -offset;
261  }
262 
263  String::const_iterator operator-(difference_type offset) const
264  {
265  String::const_iterator temp = *this;
266  return temp -= offset;
267  }
268 
269  const utf32& operator[](difference_type offset) const
270  {
271  return *(*this + offset);
272  }
273 
274  String::const_iterator& operator=(const String::iterator& iter)
275  {
276  d_ptr = iter.d_ptr;
277  return *this;
278  }
279 
280  friend String::const_iterator operator+(difference_type offset, const String::const_iterator& iter)
281  { return iter + offset; }
282 
283  friend difference_type operator-(const String::const_iterator& lhs,
284  const String::const_iterator& rhs)
285  { return lhs.d_ptr - rhs.d_ptr; }
286 
287  friend bool operator==(const String::const_iterator& lhs,
288  const String::const_iterator& rhs)
289  { return lhs.d_ptr == rhs.d_ptr; }
290 
291  friend bool operator!=(const String::const_iterator& lhs,
292  const String::const_iterator& rhs)
293  { return lhs.d_ptr != rhs.d_ptr; }
294 
295  friend bool operator<(const String::const_iterator& lhs,
296  const String::const_iterator& rhs)
297  { return lhs.d_ptr < rhs.d_ptr; }
298 
299  friend bool operator>(const String::const_iterator& lhs,
300  const String::const_iterator& rhs)
301  { return lhs.d_ptr > rhs.d_ptr; }
302 
303  friend bool operator<=(const String::const_iterator& lhs,
304  const String::const_iterator& rhs)
305  { return lhs.d_ptr <= rhs.d_ptr; }
306 
307  friend bool operator>=(const String::const_iterator& lhs,
308  const String::const_iterator& rhs)
309  { return lhs.d_ptr >= rhs.d_ptr; }
310 
311  const utf32* d_ptr;
312  };
313 
318 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
319  typedef std::reverse_iterator<const_iterator, const_pointer, const_reference, difference_type> const_reverse_iterator;
320 #else
321  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
322 #endif
323 
328 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
329  typedef std::reverse_iterator<iterator, pointer, reference, difference_type> reverse_iterator;
330 #else
331  typedef std::reverse_iterator<iterator> reverse_iterator;
332 #endif
333 
334 public:
336  // Default Construction and Destructor
338 
342  String(void)
343  {
344  init();
345  }
346 
351  ~String(void);
352 
354  // Construction via CEGUI::String
356 
366  String(const String& str)
367  {
368  init();
369  assign(str);
370  }
371 
372 
389  String(const String& str, size_type str_idx, size_type str_num = npos)
390  {
391  init();
392  assign(str, str_idx, str_num);
393  }
394 
396  // Construction via std::string
398 
414  String(const std::string& std_str)
415  {
416  init();
417  assign(std_str);
418  }
419 
442  String(const std::string& std_str, size_type str_idx, size_type str_num = npos)
443  {
444  init();
445  assign(std_str, str_idx, str_num);
446  }
447 
448 
450  // Construction via UTF-8 stream (for straight ASCII use, only codes 0x00 - 0x7f are valid)
452 
470  String(const utf8* utf8_str)
471  {
472  init();
473  assign(utf8_str);
474  }
475 
502  String(const utf8* utf8_str, size_type chars_len)
503  {
504  init();
505  assign(utf8_str, chars_len);
506  }
507 
509  // Construction via code-point (using a UTF-32 code unit)
511 
526  String(size_type num, utf32 code_point)
527  {
528  init();
529  assign(num, code_point);
530  }
531 
533  // Construction via iterator
535  // Create string with characters in the range [beg, end)
550  {
551  init();
552  append(iter_beg, iter_end);
553  }
554 
555 
557  // Construction via c-string
559 
571  String(const char* cstr)
572  {
573  init();
574  assign(cstr);
575  }
576 
592  String(const char* chars, size_type chars_len)
593  {
594  init();
595  assign(chars, chars_len);
596  }
597 
598 
600  // Size operations
602 
609  size_type size(void) const
610  {
611  return d_cplength;
612  }
613 
621  size_type length(void) const
622  {
623  return d_cplength;
624  }
625 
633  bool empty(void) const
634  {
635  return (d_cplength == 0);
636  }
637 
647  size_type max_size(void) const
648  {
649  return (((size_type)-1) / sizeof(utf32));
650  }
651 
653  // Capacity Operations
655  // return the number of code points the string could hold without re-allocation
656  // (due to internal encoding this will always report the figure for worst-case encoding, and could even be < size()!)
665  size_type capacity(void) const
666  {
667  return d_reserve - 1;
668  }
669 
670  // reserve internal memory for at-least 'num' code-points (characters). if num is 0, request is shrink-to-fit.
685  void reserve(size_type num = 0)
686  {
687  if (num == 0)
688  trim();
689  else
690  grow(num);
691  }
692 
694  // Comparisons
696 
711  int compare(const String& str) const
712  {
713  return compare(0, d_cplength, str);
714  }
715 
745  int compare(size_type idx, size_type len, const String& str, size_type str_idx = 0, size_type str_len = npos) const
746  {
747  if ((d_cplength < idx) || (str.d_cplength < str_idx))
748  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
749 
750  if ((len == npos) || (idx + len > d_cplength))
751  len = d_cplength - idx;
752 
753  if ((str_len == npos) || (str_idx + str_len > str.d_cplength))
754  str_len = str.d_cplength - str_idx;
755 
756  int val = (len == 0) ? 0 : utf32_comp_utf32(&ptr()[idx], &str.ptr()[str_idx], (len < str_len) ? len : str_len);
757 
758  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
759  }
760 
761 
781  int compare(const std::string& std_str) const
782  {
783  return compare(0, d_cplength, std_str);
784  }
785 
786 
820  int compare(size_type idx, size_type len, const std::string& std_str, size_type str_idx = 0, size_type str_len = npos) const
821  {
822  if (d_cplength < idx)
823  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
824 
825  if (std_str.size() < str_idx)
826  CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
827 
828  if ((len == npos) || (idx + len > d_cplength))
829  len = d_cplength - idx;
830 
831  if ((str_len == npos) || (str_idx + str_len > std_str.size()))
832  str_len = (size_type)std_str.size() - str_idx;
833 
834  int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], &std_str.c_str()[str_idx], (len < str_len) ? len : str_len);
835 
836  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
837  }
838 
839 
861  int compare(const utf8* utf8_str) const
862  {
863  return compare(0, d_cplength, utf8_str, encoded_size(utf8_str));
864  }
865 
866 
896  int compare(size_type idx, size_type len, const utf8* utf8_str) const
897  {
898  return compare(idx, len, utf8_str, encoded_size(utf8_str));
899  }
900 
934  int compare(size_type idx, size_type len, const utf8* utf8_str, size_type str_cplen) const
935  {
936  if (d_cplength < idx)
937  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
938 
939  if (str_cplen == npos)
940  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
941 
942  if ((len == npos) || (idx + len > d_cplength))
943  len = d_cplength - idx;
944 
945  int val = (len == 0) ? 0 : utf32_comp_utf8(&ptr()[idx], utf8_str, (len < str_cplen) ? len : str_cplen);
946 
947  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_cplen) ? -1 : (len == str_cplen) ? 0 : 1;
948  }
949 
950 
966  int compare(const char* cstr) const
967  {
968  return compare(0, d_cplength, cstr, strlen(cstr));
969  }
970 
971 
995  int compare(size_type idx, size_type len, const char* cstr) const
996  {
997  return compare(idx, len, cstr, strlen(cstr));
998  }
999 
1000 
1028  int compare(size_type idx, size_type len, const char* chars, size_type chars_len) const
1029  {
1030  if (d_cplength < idx)
1031  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
1032 
1033  if (chars_len == npos)
1034  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
1035 
1036  if ((len == npos) || (idx + len > d_cplength))
1037  len = d_cplength - idx;
1038 
1039  int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], chars, (len < chars_len) ? len : chars_len);
1040 
1041  return (val != 0) ? ((val < 0) ? -1 : 1) : (len < chars_len) ? -1 : (len == chars_len) ? 0 : 1;
1042  }
1043 
1044 
1046  // Character access
1048 
1062  reference operator[](size_type idx)
1063  {
1064  return (ptr()[idx]);
1065  }
1066 
1081  value_type operator[](size_type idx) const
1082  {
1083  return ptr()[idx];
1084  }
1085 
1098  reference at(size_type idx)
1099  {
1100  if (d_cplength <= idx)
1101  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
1102 
1103  return ptr()[idx];
1104  }
1105 
1118  const_reference at(size_type idx) const
1119  {
1120  if (d_cplength <= idx)
1121  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
1122 
1123  return ptr()[idx];
1124  }
1125 
1126 
1128  // C-Strings and arrays
1130 
1143  const char* c_str(void) const
1144  {
1145  return (const char*)build_utf8_buff();
1146  }
1147 
1161  const utf8* data(void) const
1162  {
1163  return build_utf8_buff();
1164  }
1165 
1170  utf32* ptr(void)
1171  {
1172  return (d_reserve > CEGUI_STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1173  }
1174 
1179  const utf32* ptr(void) const
1180  {
1181  return (d_reserve > CEGUI_STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1182  }
1183 
1184  // copy, at most, 'len' code-points of the string, begining with code-point 'idx', into the array 'buf' as valid utf8 encoded data
1185  // return number of utf8 code units placed into the buffer
1206  size_type copy(utf8* buf, size_type len = npos, size_type idx = 0) const
1207  {
1208  if (d_cplength < idx)
1209  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
1210 
1211  if (len == npos)
1212  len = d_cplength;
1213 
1214  return encode(&ptr()[idx], buf, npos, len);
1215  }
1216 
1218  // UTF8 Encoding length information
1220  // 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.
1236  size_type utf8_stream_len(size_type num = npos, size_type idx = 0) const
1237  {
1238  using namespace std;
1239 
1240  if (d_cplength < idx)
1241  CEGUI_THROW(out_of_range("Index was out of range for CEGUI::String object"));
1242 
1243  size_type maxlen = d_cplength - idx;
1244 
1245  return encoded_size(&ptr()[idx], ceguimin(num, maxlen));
1246  }
1247 
1249  // Assignment Functions
1251 
1261  String& operator=(const String& str)
1262  {
1263  return assign(str);
1264  }
1265 
1284  String& assign(const String& str, size_type str_idx = 0, size_type str_num = npos)
1285  {
1286  if (str.d_cplength < str_idx)
1287  CEGUI_THROW(std::out_of_range("Index was out of range for CEGUI::String object"));
1288 
1289  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
1290  str_num = str.d_cplength - str_idx;
1291 
1292  grow(str_num);
1293  setlen(str_num);
1294  memcpy(ptr(), &str.ptr()[str_idx], str_num * sizeof(utf32));
1295 
1296  return *this;
1297  }
1298 
1315  String& operator=(const std::string& std_str)
1316  {
1317  return assign(std_str);
1318  }
1319 
1343  String& assign(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1344  {
1345  if (std_str.size() < str_idx)
1346  CEGUI_THROW(std::out_of_range("Index was out of range for std::string object"));
1347 
1348  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
1349  str_num = (size_type)std_str.size() - str_idx;
1350 
1351  grow(str_num);
1352  setlen(str_num);
1353 
1354  while(str_num--)
1355  {
1356  ((*this)[str_num]) = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num + str_idx]));
1357  }
1358 
1359  return *this;
1360  }
1361 
1380  String& operator=(const utf8* utf8_str)
1381  {
1382  return assign(utf8_str, utf_length(utf8_str));
1383  }
1384 
1403  String& assign(const utf8* utf8_str)
1404  {
1405  return assign(utf8_str, utf_length(utf8_str));
1406  }
1407 
1429  String& assign(const utf8* utf8_str, size_type str_num)
1430  {
1431  if (str_num == npos)
1432  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
1433 
1434  size_type enc_sze = encoded_size(utf8_str, str_num);
1435 
1436  grow(enc_sze);
1437  encode(utf8_str, ptr(), d_reserve, str_num);
1438  setlen(enc_sze);
1439  return *this;
1440  }
1441 
1452  String& operator=(utf32 code_point)
1453  {
1454  return assign(1, code_point);
1455  }
1456 
1472  String& assign(size_type num, utf32 code_point)
1473  {
1474  if (num == npos)
1475  CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
1476 
1477  grow(num);
1478  setlen(num);
1479  utf32* p = ptr();
1480 
1481  while(num--)
1482  *p++ = code_point;
1483 
1484  return *this;
1485  }
1486 
1487 
1500  String& operator=(const char* cstr)
1501  {
1502  return assign(cstr, strlen(cstr));
1503  }
1504 
1505 
1518  String& assign(const char* cstr)
1519  {
1520  return assign(cstr, strlen(cstr));
1521  }
1522 
1523 
1539  String& assign(const char* chars, size_type chars_len)
1540  {
1541  grow(chars_len);
1542  utf32* pt = ptr();
1543 
1544  for (size_type i = 0; i < chars_len; ++i)
1545  {
1546  *pt++ = static_cast<utf32>(static_cast<unsigned char>(*chars++));
1547  }
1548 
1549  setlen(chars_len);
1550  return *this;
1551  }
1552 
1553 
1564  void swap(String& str)
1565  {
1566  size_type temp_len = d_cplength;
1567  d_cplength = str.d_cplength;
1568  str.d_cplength = temp_len;
1569 
1570  size_type temp_res = d_reserve;
1571  d_reserve = str.d_reserve;
1572  str.d_reserve = temp_res;
1573 
1574  utf32* temp_buf = d_buffer;
1575  d_buffer = str.d_buffer;
1576  str.d_buffer = temp_buf;
1577 
1578  // see if we need to swap 'quick buffer' data
1579  if (temp_res <= CEGUI_STR_QUICKBUFF_SIZE)
1580  {
1581  utf32 temp_qbf[CEGUI_STR_QUICKBUFF_SIZE];
1582 
1583  memcpy(temp_qbf, d_quickbuff, CEGUI_STR_QUICKBUFF_SIZE * sizeof(utf32));
1584  memcpy(d_quickbuff, str.d_quickbuff, CEGUI_STR_QUICKBUFF_SIZE * sizeof(utf32));
1585  memcpy(str.d_quickbuff, temp_qbf, CEGUI_STR_QUICKBUFF_SIZE * sizeof(utf32));
1586  }
1587 
1588  }
1589 
1591  // Appending Functions
1593 
1605  String& operator+=(const String& str)
1606  {
1607  return append(str);
1608  }
1609 
1629  String& append(const String& str, size_type str_idx = 0, size_type str_num = npos)
1630  {
1631  if (str.d_cplength < str_idx)
1632  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
1633 
1634  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
1635  str_num = str.d_cplength - str_idx;
1636 
1637  grow(d_cplength + str_num);
1638  memcpy(&ptr()[d_cplength], &str.ptr()[str_idx], str_num * sizeof(utf32));
1639  setlen(d_cplength + str_num);
1640  return *this;
1641  }
1642 
1643 
1660  String& operator+=(const std::string& std_str)
1661  {
1662  return append(std_str);
1663  }
1664 
1688  String& append(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1689  {
1690  if (std_str.size() < str_idx)
1691  CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
1692 
1693  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
1694  str_num = (size_type)std_str.size() - str_idx;
1695 
1696  size_type newsze = d_cplength + str_num;
1697 
1698  grow(newsze);
1699  utf32* pt = &ptr()[newsze-1];
1700 
1701  while(str_num--)
1702  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num]));
1703 
1704  setlen(newsze);
1705  return *this;
1706  }
1707 
1708 
1727  String& operator+=(const utf8* utf8_str)
1728  {
1729  return append(utf8_str, utf_length(utf8_str));
1730  }
1731 
1750  String& append(const utf8* utf8_str)
1751  {
1752  return append(utf8_str, utf_length(utf8_str));
1753  }
1754 
1755 
1777  String& append(const utf8* utf8_str, size_type len)
1778  {
1779  if (len == npos)
1780  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
1781 
1782  size_type encsz = encoded_size(utf8_str, len);
1783  size_type newsz = d_cplength + encsz;
1784 
1785  grow(newsz);
1786  encode(utf8_str, &ptr()[d_cplength], encsz, len);
1787  setlen(newsz);
1788 
1789  return *this;
1790  }
1791 
1792 
1805  String& operator+=(utf32 code_point)
1806  {
1807  return append(1, code_point);
1808  }
1809 
1825  String& append(size_type num, utf32 code_point)
1826  {
1827  if (num == npos)
1828  CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
1829 
1830  size_type newsz = d_cplength + num;
1831  grow(newsz);
1832 
1833  utf32* p = &ptr()[d_cplength];
1834 
1835  while(num--)
1836  *p++ = code_point;
1837 
1838  setlen(newsz);
1839 
1840  return *this;
1841  }
1842 
1855  void push_back(utf32 code_point)
1856  {
1857  append(1, code_point);
1858  }
1859 
1876  {
1877  return replace(end(), end(), iter_beg, iter_end);
1878  }
1879 
1880 
1893  String& operator+=(const char* cstr)
1894  {
1895  return append(cstr, strlen(cstr));
1896  }
1897 
1898 
1911  String& append(const char* cstr)
1912  {
1913  return append(cstr, strlen(cstr));
1914  }
1915 
1916 
1932  String& append(const char* chars, size_type chars_len)
1933  {
1934  if (chars_len == npos)
1935  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
1936 
1937  size_type newsz = d_cplength + chars_len;
1938 
1939  grow(newsz);
1940 
1941  utf32* pt = &ptr()[newsz-1];
1942 
1943  while(chars_len--)
1944  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
1945 
1946  setlen(newsz);
1947 
1948  return *this;
1949  }
1950 
1951 
1953  // Insertion Functions
1955 
1971  String& insert(size_type idx, const String& str)
1972  {
1973  return insert(idx, str, 0, npos);
1974  }
1975 
1998  String& insert(size_type idx, const String& str, size_type str_idx, size_type str_num)
1999  {
2000  if ((d_cplength < idx) || (str.d_cplength < str_idx))
2001  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2002 
2003  if ((str_num == npos) || (str_num > str.d_cplength - str_idx))
2004  str_num = str.d_cplength - str_idx;
2005 
2006  size_type newsz = d_cplength + str_num;
2007  grow(newsz);
2008  memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2009  memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2010  setlen(newsz);
2011 
2012  return *this;
2013  }
2014 
2035  String& insert(size_type idx, const std::string& std_str)
2036  {
2037  return insert(idx, std_str, 0, npos);
2038  }
2039 
2066  String& insert(size_type idx, const std::string& std_str, size_type str_idx, size_type str_num)
2067  {
2068  if (d_cplength < idx)
2069  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2070 
2071  if (std_str.size() < str_idx)
2072  CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
2073 
2074  if ((str_num == npos) || (str_num > (size_type)std_str.size() - str_idx))
2075  str_num = (size_type)std_str.size() - str_idx;
2076 
2077  size_type newsz = d_cplength + str_num;
2078  grow(newsz);
2079 
2080  memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2081 
2082  utf32* pt = &ptr()[idx + str_num - 1];
2083 
2084  while(str_num--)
2085  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2086 
2087  setlen(newsz);
2088 
2089  return *this;
2090  }
2091 
2114  String& insert(size_type idx, const utf8* utf8_str)
2115  {
2116  return insert(idx, utf8_str, utf_length(utf8_str));
2117  }
2118 
2144  String& insert(size_type idx, const utf8* utf8_str, size_type len)
2145  {
2146  if (d_cplength < idx)
2147  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2148 
2149  if (len == npos)
2150  CEGUI_THROW(std::length_error("Length of utf8 encoded string can not be 'npos'"));
2151 
2152  size_type encsz = encoded_size(utf8_str, len);
2153  size_type newsz = d_cplength + encsz;
2154 
2155  grow(newsz);
2156  memmove(&ptr()[idx + encsz], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2157  encode(utf8_str, &ptr()[idx], encsz, len);
2158  setlen(newsz);
2159 
2160  return *this;
2161  }
2162 
2182  String& insert(size_type idx, size_type num, utf32 code_point)
2183  {
2184  if (d_cplength < idx)
2185  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2186 
2187  if (num == npos)
2188  CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
2189 
2190  size_type newsz = d_cplength + num;
2191  grow(newsz);
2192 
2193  memmove(&ptr()[idx + num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2194 
2195  utf32* pt = &ptr()[idx + num - 1];
2196 
2197  while(num--)
2198  *pt-- = code_point;
2199 
2200  setlen(newsz);
2201 
2202  return *this;
2203  }
2204 
2223  void insert(iterator pos, size_type num, utf32 code_point)
2224  {
2225  insert(safe_iter_dif(pos, begin()), num, code_point);
2226  }
2227 
2243  iterator insert(iterator pos, utf32 code_point)
2244  {
2245  insert(pos, 1, code_point);
2246  return pos;
2247  }
2248 
2267  void insert(iterator iter_pos, const_iterator iter_beg, const_iterator iter_end)
2268  {
2269  replace(iter_pos, iter_pos, iter_beg, iter_end);
2270  }
2271 
2272 
2289  String& insert(size_type idx, const char* cstr)
2290  {
2291  return insert(idx, cstr, strlen(cstr));
2292  }
2293 
2294 
2314  String& insert(size_type idx, const char* chars, size_type chars_len)
2315  {
2316  if (d_cplength < idx)
2317  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2318 
2319  if (chars_len == npos)
2320  CEGUI_THROW(std::length_error("Length of char array can not be 'npos'"));
2321 
2322  size_type newsz = d_cplength + chars_len;
2323 
2324  grow(newsz);
2325  memmove(&ptr()[idx + chars_len], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2326 
2327  utf32* pt = &ptr()[idx + chars_len - 1];
2328 
2329  while(chars_len--)
2330  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
2331 
2332  setlen(newsz);
2333 
2334  return *this;
2335  }
2336 
2337 
2339  // Erasing characters
2341 
2348  void clear(void)
2349  {
2350  setlen(0);
2351  trim();
2352  }
2353 
2361  String& erase(void)
2362  {
2363  clear();
2364  return *this;
2365  }
2366 
2379  String& erase(size_type idx)
2380  {
2381  return erase(idx, 1);
2382  }
2383 
2399  String& erase(size_type idx, size_type len)
2400  {
2401  // cover the no-op case.
2402  if (len == 0)
2403  return *this;
2404 
2405  if (d_cplength <= idx)
2406  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2407 
2408  if (len == npos)
2409  len = d_cplength - idx;
2410 
2411  size_type newsz = d_cplength - len;
2412 
2413  memmove(&ptr()[idx], &ptr()[idx + len], (d_cplength - idx - len) * sizeof(utf32));
2414  setlen(newsz);
2415  return *this;
2416  }
2417 
2429  {
2430  return erase(safe_iter_dif(pos, begin()), 1);
2431  }
2432 
2446  String& erase(iterator iter_beg, iterator iter_end)
2447  {
2448  return erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
2449  }
2450 
2452  // Resizing
2454 
2466  void resize(size_type num)
2467  {
2468  resize(num, utf32());
2469  }
2470 
2486  void resize(size_type num, utf32 code_point)
2487  {
2488  if (num < d_cplength)
2489  {
2490  setlen(num);
2491  }
2492  else
2493  {
2494  append(num - d_cplength, code_point);
2495  }
2496 
2497  }
2498 
2500  // Replacing Characters
2502 
2521  String& replace(size_type idx, size_type len, const String& str)
2522  {
2523  return replace(idx, len, str, 0, npos);
2524  }
2525 
2547  String& replace(iterator iter_beg, iterator iter_end, const String& str)
2548  {
2549  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), str, 0, npos);
2550  }
2551 
2577  String& replace(size_type idx, size_type len, const String& str, size_type str_idx, size_type str_num)
2578  {
2579  if ((d_cplength < idx) || (str.d_cplength < str_idx))
2580  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2581 
2582  if (((str_idx + str_num) > str.d_cplength) || (str_num == npos))
2583  str_num = str.d_cplength - str_idx;
2584 
2585  if (((len + idx) > d_cplength) || (len == npos))
2586  len = d_cplength - idx;
2587 
2588  size_type newsz = d_cplength + str_num - len;
2589 
2590  grow(newsz);
2591 
2592  if ((idx + len) < d_cplength)
2593  memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2594 
2595  memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2596  setlen(newsz);
2597 
2598  return *this;
2599  }
2600 
2601 
2625  String& replace(size_type idx, size_type len, const std::string& std_str)
2626  {
2627  return replace(idx, len, std_str, 0, npos);
2628  }
2629 
2655  String& replace(iterator iter_beg, iterator iter_end, const std::string& std_str)
2656  {
2657  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), std_str, 0, npos);
2658  }
2659 
2689  String& replace(size_type idx, size_type len, const std::string& std_str, size_type str_idx, size_type str_num)
2690  {
2691  if (d_cplength < idx)
2692  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2693 
2694  if (std_str.size() < str_idx)
2695  CEGUI_THROW(std::out_of_range("Index is out of range for std::string"));
2696 
2697  if (((str_idx + str_num) > std_str.size()) || (str_num == npos))
2698  str_num = (size_type)std_str.size() - str_idx;
2699 
2700  if (((len + idx) > d_cplength) || (len == npos))
2701  len = d_cplength - idx;
2702 
2703  size_type newsz = d_cplength + str_num - len;
2704 
2705  grow(newsz);
2706 
2707  if ((idx + len) < d_cplength)
2708  memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2709 
2710  utf32* pt = &ptr()[idx + str_num - 1];
2711 
2712  while (str_num--)
2713  *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2714 
2715  setlen(newsz);
2716 
2717  return *this;
2718  }
2719 
2720 
2746  String& replace(size_type idx, size_type len, const utf8* utf8_str)
2747  {
2748  return replace(idx, len, utf8_str, utf_length(utf8_str));
2749  }
2750 
2778  String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str)
2779  {
2780  return replace(iter_beg, iter_end, utf8_str, utf_length(utf8_str));
2781  }
2782 
2811  String& replace(size_type idx, size_type len, const utf8* utf8_str, size_type str_len)
2812  {
2813  if (d_cplength < idx)
2814  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2815 
2816  if (str_len == npos)
2817  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
2818 
2819  if (((len + idx) > d_cplength) || (len == npos))
2820  len = d_cplength - idx;
2821 
2822  size_type encsz = encoded_size(utf8_str, str_len);
2823  size_type newsz = d_cplength + encsz - len;
2824 
2825  grow(newsz);
2826 
2827  if ((idx + len) < d_cplength)
2828  memmove(&ptr()[idx + encsz], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2829 
2830  encode(utf8_str, &ptr()[idx], encsz, str_len);
2831 
2832  setlen(newsz);
2833  return *this;
2834  }
2835 
2866  String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str, size_type str_len)
2867  {
2868  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), utf8_str, str_len);
2869  }
2870 
2893  String& replace(size_type idx, size_type len, size_type num, utf32 code_point)
2894  {
2895  if (d_cplength < idx)
2896  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
2897 
2898  if (num == npos)
2899  CEGUI_THROW(std::length_error("Code point count can not be 'npos'"));
2900 
2901  if (((len + idx) > d_cplength) || (len == npos))
2902  len = d_cplength - idx;
2903 
2904  size_type newsz = d_cplength + num - len;
2905 
2906  grow(newsz);
2907 
2908  if ((idx + len) < d_cplength)
2909  memmove(&ptr()[idx + num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2910 
2911  utf32* pt = &ptr()[idx + num - 1];
2912 
2913  while (num--)
2914  *pt-- = code_point;
2915 
2916  setlen(newsz);
2917 
2918  return *this;
2919  }
2920 
2945  String& replace(iterator iter_beg, iterator iter_end, size_type num, utf32 code_point)
2946  {
2947  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), num, code_point);
2948  }
2949 
2950 
2975  String& replace(iterator iter_beg, iterator iter_end, const_iterator iter_newBeg, const_iterator iter_newEnd)
2976  {
2977  if (iter_newBeg == iter_newEnd)
2978  {
2979  erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
2980  }
2981  else
2982  {
2983  size_type str_len = safe_iter_dif(iter_newEnd, iter_newBeg);
2984  size_type idx = safe_iter_dif(iter_beg, begin());
2985  size_type len = safe_iter_dif(iter_end, iter_beg);
2986 
2987  if ((len + idx) > d_cplength)
2988  len = d_cplength - idx;
2989 
2990  size_type newsz = d_cplength + str_len - len;
2991 
2992  grow(newsz);
2993 
2994  if ((idx + len) < d_cplength)
2995  memmove(&ptr()[idx + str_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2996 
2997  memcpy(&ptr()[idx], iter_newBeg.d_ptr, str_len * sizeof(utf32));
2998  setlen(newsz);
2999  }
3000 
3001  return *this;
3002  }
3003 
3004 
3024  String& replace(size_type idx, size_type len, const char* cstr)
3025  {
3026  return replace(idx, len, cstr, strlen(cstr));
3027  }
3028 
3029 
3051  String& replace(iterator iter_beg, iterator iter_end, const char* cstr)
3052  {
3053  return replace(iter_beg, iter_end, cstr, strlen(cstr));
3054  }
3055 
3056 
3079  String& replace(size_type idx, size_type len, const char* chars, size_type chars_len)
3080  {
3081  if (d_cplength < idx)
3082  CEGUI_THROW(std::out_of_range("Index is out of range for CEGUI::String"));
3083 
3084  if (chars_len == npos)
3085  CEGUI_THROW(std::length_error("Length for the char array can not be 'npos'"));
3086 
3087  if (((len + idx) > d_cplength) || (len == npos))
3088  len = d_cplength - idx;
3089 
3090  size_type newsz = d_cplength + chars_len - len;
3091 
3092  grow(newsz);
3093 
3094  if ((idx + len) < d_cplength)
3095  memmove(&ptr()[idx + chars_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
3096 
3097  utf32* pt = &ptr()[idx + chars_len - 1];
3098 
3099  while (chars_len--)
3100  *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
3101 
3102  setlen(newsz);
3103  return *this;
3104  }
3105 
3106 
3131  String& replace(iterator iter_beg, iterator iter_end, const char* chars, size_type chars_len)
3132  {
3133  return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), chars, chars_len);
3134  }
3135 
3136 
3138  // Find a code point
3140 
3154  size_type find(utf32 code_point, size_type idx = 0) const
3155  {
3156  if (idx < d_cplength)
3157  {
3158  const utf32* pt = &ptr()[idx];
3159 
3160  while (idx < d_cplength)
3161  {
3162  if (*pt++ == code_point)
3163  return idx;
3164 
3165  ++idx;
3166  }
3167 
3168  }
3169 
3170  return npos;
3171  }
3172 
3187  size_type rfind(utf32 code_point, size_type idx = npos) const
3188  {
3189  if (idx >= d_cplength)
3190  idx = d_cplength - 1;
3191 
3192  if (d_cplength > 0)
3193  {
3194  const utf32* pt = &ptr()[idx];
3195 
3196  do
3197  {
3198  if (*pt-- == code_point)
3199  return idx;
3200 
3201  } while (idx-- != 0);
3202 
3203  }
3204 
3205  return npos;
3206  }
3207 
3209  // Find a substring
3211 
3225  size_type find(const String& str, size_type idx = 0) const
3226  {
3227  if ((str.d_cplength == 0) && (idx < d_cplength))
3228  return idx;
3229 
3230  if (idx < d_cplength)
3231  {
3232  // loop while search string could fit in to search area
3233  while (d_cplength - idx >= str.d_cplength)
3234  {
3235  if (0 == compare(idx, str.d_cplength, str))
3236  return idx;
3237 
3238  ++idx;
3239  }
3240 
3241  }
3242 
3243  return npos;
3244  }
3245 
3260  size_type rfind(const String& str, size_type idx = npos) const
3261  {
3262  if (str.d_cplength == 0)
3263  return (idx < d_cplength) ? idx : d_cplength;
3264 
3265  if (str.d_cplength <= d_cplength)
3266  {
3267  if (idx > (d_cplength - str.d_cplength))
3268  idx = d_cplength - str.d_cplength;
3269 
3270  do
3271  {
3272  if (0 == compare(idx, str.d_cplength, str))
3273  return idx;
3274 
3275  } while (idx-- != 0);
3276 
3277  }
3278 
3279  return npos;
3280  }
3281 
3300  size_type find(const std::string& std_str, size_type idx = 0) const
3301  {
3302  std::string::size_type sze = std_str.size();
3303 
3304  if ((sze == 0) && (idx < d_cplength))
3305  return idx;
3306 
3307  if (idx < d_cplength)
3308  {
3309  // loop while search string could fit in to search area
3310  while (d_cplength - idx >= sze)
3311  {
3312  if (0 == compare(idx, (size_type)sze, std_str))
3313  return idx;
3314 
3315  ++idx;
3316  }
3317 
3318  }
3319 
3320  return npos;
3321  }
3322 
3341  size_type rfind(const std::string& std_str, size_type idx = npos) const
3342  {
3343  std::string::size_type sze = std_str.size();
3344 
3345  if (sze == 0)
3346  return (idx < d_cplength) ? idx : d_cplength;
3347 
3348  if (sze <= d_cplength)
3349  {
3350  if (idx > (d_cplength - sze))
3351  idx = d_cplength - sze;
3352 
3353  do
3354  {
3355  if (0 == compare(idx, (size_type)sze, std_str))
3356  return idx;
3357 
3358  } while (idx-- != 0);
3359 
3360  }
3361 
3362  return npos;
3363  }
3364 
3387  size_type find(const utf8* utf8_str, size_type idx = 0) const
3388  {
3389  return find(utf8_str, idx, utf_length(utf8_str));
3390  }
3391 
3414  size_type rfind(const utf8* utf8_str, size_type idx = npos) const
3415  {
3416  return rfind(utf8_str, idx, utf_length(utf8_str));
3417  }
3418 
3444  size_type find(const utf8* utf8_str, size_type idx, size_type str_len) const
3445  {
3446  if (str_len == npos)
3447  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
3448 
3449  size_type sze = encoded_size(utf8_str, str_len);
3450 
3451  if ((sze == 0) && (idx < d_cplength))
3452  return idx;
3453 
3454  if (idx < d_cplength)
3455  {
3456  // loop while search string could fit in to search area
3457  while (d_cplength - idx >= sze)
3458  {
3459  if (0 == compare(idx, sze, utf8_str, sze))
3460  return idx;
3461 
3462  ++idx;
3463  }
3464 
3465  }
3466 
3467  return npos;
3468  }
3469 
3495  size_type rfind(const utf8* utf8_str, size_type idx, size_type str_len) const
3496  {
3497  if (str_len == npos)
3498  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
3499 
3500  size_type sze = encoded_size(utf8_str, str_len);
3501 
3502  if (sze == 0)
3503  return (idx < d_cplength) ? idx : d_cplength;
3504 
3505  if (sze <= d_cplength)
3506  {
3507  if (idx > (d_cplength - sze))
3508  idx = d_cplength - sze;
3509 
3510  do
3511  {
3512  if (0 == compare(idx, sze, utf8_str, sze))
3513  return idx;
3514 
3515  } while (idx-- != 0);
3516 
3517  }
3518 
3519  return npos;
3520  }
3521 
3522 
3539  size_type find(const char* cstr, size_type idx = 0) const
3540  {
3541  return find(cstr, idx, strlen(cstr));
3542  }
3543 
3544 
3561  size_type rfind(const char* cstr, size_type idx = npos) const
3562  {
3563  return rfind(cstr, idx, strlen(cstr));
3564  }
3565 
3566 
3586  size_type find(const char* chars, size_type idx, size_type chars_len) const
3587  {
3588  if (chars_len == npos)
3589  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
3590 
3591  if ((chars_len == 0) && (idx < d_cplength))
3592  return idx;
3593 
3594  if (idx < d_cplength)
3595  {
3596  // loop while search string could fit in to search area
3597  while (d_cplength - idx >= chars_len)
3598  {
3599  if (0 == compare(idx, chars_len, chars, chars_len))
3600  return idx;
3601 
3602  ++idx;
3603  }
3604 
3605  }
3606 
3607  return npos;
3608  }
3609 
3610 
3630  size_type rfind(const char* chars, size_type idx, size_type chars_len) const
3631  {
3632  if (chars_len == npos)
3633  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
3634 
3635  if (chars_len == 0)
3636  return (idx < d_cplength) ? idx : d_cplength;
3637 
3638  if (chars_len <= d_cplength)
3639  {
3640  if (idx > (d_cplength - chars_len))
3641  idx = d_cplength - chars_len;
3642 
3643  do
3644  {
3645  if (0 == compare(idx, chars_len, chars, chars_len))
3646  return idx;
3647 
3648  } while (idx-- != 0);
3649 
3650  }
3651 
3652  return npos;
3653  }
3654 
3655 
3657  // Find first of different code-points
3659 
3673  size_type find_first_of(const String& str, size_type idx = 0) const
3674  {
3675  if (idx < d_cplength)
3676  {
3677  const utf32* pt = &ptr()[idx];
3678 
3679  do
3680  {
3681  if (npos != str.find(*pt++))
3682  return idx;
3683 
3684  } while (++idx != d_cplength);
3685 
3686  }
3687 
3688  return npos;
3689  }
3690 
3705  size_type find_first_not_of(const String& str, size_type idx = 0) const
3706  {
3707  if (idx < d_cplength)
3708  {
3709  const utf32* pt = &ptr()[idx];
3710 
3711  do
3712  {
3713  if (npos == str.find(*pt++))
3714  return idx;
3715 
3716  } while (++idx != d_cplength);
3717 
3718  }
3719 
3720  return npos;
3721  }
3722 
3723 
3742  size_type find_first_of(const std::string& std_str, size_type idx = 0) const
3743  {
3744  if (idx < d_cplength)
3745  {
3746  const utf32* pt = &ptr()[idx];
3747 
3748  do
3749  {
3750  if (npos != find_codepoint(std_str, *pt++))
3751  return idx;
3752 
3753  } while (++idx != d_cplength);
3754 
3755  }
3756 
3757  return npos;
3758  }
3759 
3778  size_type find_first_not_of(const std::string& std_str, size_type idx = 0) const
3779  {
3780  if (idx < d_cplength)
3781  {
3782  const utf32* pt = &ptr()[idx];
3783 
3784  do
3785  {
3786  if (npos == find_codepoint(std_str, *pt++))
3787  return idx;
3788 
3789  } while (++idx != d_cplength);
3790 
3791  }
3792 
3793  return npos;
3794  }
3795 
3796 
3819  size_type find_first_of(const utf8* utf8_str, size_type idx = 0) const
3820  {
3821  return find_first_of(utf8_str, idx, utf_length(utf8_str));
3822  }
3823 
3846  size_type find_first_not_of(const utf8* utf8_str, size_type idx = 0) const
3847  {
3848  return find_first_not_of(utf8_str, idx, utf_length(utf8_str));
3849  }
3850 
3876  size_type find_first_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3877  {
3878  if (str_len == npos)
3879  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
3880 
3881  if (idx < d_cplength)
3882  {
3883  size_type encsze = encoded_size(utf8_str, str_len);
3884 
3885  const utf32* pt = &ptr()[idx];
3886 
3887  do
3888  {
3889  if (npos != find_codepoint(utf8_str, encsze, *pt++))
3890  return idx;
3891 
3892  } while (++idx != d_cplength);
3893 
3894  }
3895 
3896  return npos;
3897  }
3898 
3924  size_type find_first_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3925  {
3926  if (str_len == npos)
3927  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
3928 
3929  if (idx < d_cplength)
3930  {
3931  size_type encsze = encoded_size(utf8_str, str_len);
3932 
3933  const utf32* pt = &ptr()[idx];
3934 
3935  do
3936  {
3937  if (npos == find_codepoint(utf8_str, encsze, *pt++))
3938  return idx;
3939 
3940  } while (++idx != d_cplength);
3941 
3942  }
3943 
3944  return npos;
3945  }
3946 
3947 
3962  size_type find_first_of(utf32 code_point, size_type idx = 0) const
3963  {
3964  return find(code_point, idx);
3965  }
3966 
3983  size_type find_first_not_of(utf32 code_point, size_type idx = 0) const
3984  {
3985  if (idx < d_cplength)
3986  {
3987  do
3988  {
3989  if ((*this)[idx] != code_point)
3990  return idx;
3991 
3992  } while(idx++ < d_cplength);
3993 
3994  }
3995 
3996  return npos;
3997  }
3998 
3999 
4016  size_type find_first_of(const char* cstr, size_type idx = 0) const
4017  {
4018  return find_first_of(cstr, idx, strlen(cstr));
4019  }
4020 
4021 
4038  size_type find_first_not_of(const char* cstr, size_type idx = 0) const
4039  {
4040  return find_first_not_of(cstr, idx, strlen(cstr));
4041  }
4042 
4043 
4063  size_type find_first_of(const char* chars, size_type idx, size_type chars_len) const
4064  {
4065  if (chars_len == npos)
4066  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
4067 
4068  if (idx < d_cplength)
4069  {
4070  const utf32* pt = &ptr()[idx];
4071 
4072  do
4073  {
4074  if (npos != find_codepoint(chars, chars_len, *pt++))
4075  return idx;
4076 
4077  } while (++idx != d_cplength);
4078 
4079  }
4080 
4081  return npos;
4082  }
4083 
4084 
4104  size_type find_first_not_of(const char* chars, size_type idx, size_type chars_len) const
4105  {
4106  if (chars_len == npos)
4107  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
4108 
4109  if (idx < d_cplength)
4110  {
4111  const utf32* pt = &ptr()[idx];
4112 
4113  do
4114  {
4115  if (npos == find_codepoint(chars, chars_len, *pt++))
4116  return idx;
4117 
4118  } while (++idx != d_cplength);
4119 
4120  }
4121 
4122  return npos;
4123  }
4124 
4125 
4127  // Find last of different code-points
4129 
4143  size_type find_last_of(const String& str, size_type idx = npos) const
4144  {
4145  if (d_cplength > 0)
4146  {
4147  if (idx >= d_cplength)
4148  idx = d_cplength - 1;
4149 
4150  const utf32* pt = &ptr()[idx];
4151 
4152  do
4153  {
4154  if (npos != str.find(*pt--))
4155  return idx;
4156 
4157  } while (idx-- != 0);
4158 
4159  }
4160 
4161  return npos;
4162  }
4163 
4178  size_type find_last_not_of(const String& str, size_type idx = npos) const
4179  {
4180  if (d_cplength > 0)
4181  {
4182  if (idx >= d_cplength)
4183  idx = d_cplength - 1;
4184 
4185  const utf32* pt = &ptr()[idx];
4186 
4187  do
4188  {
4189  if (npos == str.find(*pt--))
4190  return idx;
4191 
4192  } while (idx-- != 0);
4193 
4194  }
4195 
4196  return npos;
4197  }
4198 
4199 
4218  size_type find_last_of(const std::string& std_str, size_type idx = npos) const
4219  {
4220  if (d_cplength > 0)
4221  {
4222  if (idx >= d_cplength)
4223  idx = d_cplength - 1;
4224 
4225  const utf32* pt = &ptr()[idx];
4226 
4227  do
4228  {
4229  if (npos != find_codepoint(std_str, *pt--))
4230  return idx;
4231 
4232  } while (idx-- != 0);
4233 
4234  }
4235 
4236  return npos;
4237  }
4238 
4257  size_type find_last_not_of(const std::string& std_str, size_type idx = npos) const
4258  {
4259  if (d_cplength > 0)
4260  {
4261  if (idx >= d_cplength)
4262  idx = d_cplength - 1;
4263 
4264  const utf32* pt = &ptr()[idx];
4265 
4266  do
4267  {
4268  if (npos == find_codepoint(std_str, *pt--))
4269  return idx;
4270 
4271  } while (idx-- != 0);
4272 
4273  }
4274 
4275  return npos;
4276  }
4277 
4278 
4301  size_type find_last_of(const utf8* utf8_str, size_type idx = npos) const
4302  {
4303  return find_last_of(utf8_str, idx, utf_length(utf8_str));
4304  }
4305 
4328  size_type find_last_not_of(const utf8* utf8_str, size_type idx = npos) const
4329  {
4330  return find_last_not_of(utf8_str, idx, utf_length(utf8_str));
4331  }
4332 
4358  size_type find_last_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4359  {
4360  if (str_len == npos)
4361  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
4362 
4363  if (d_cplength > 0)
4364  {
4365  if (idx >= d_cplength)
4366  idx = d_cplength - 1;
4367 
4368  size_type encsze = encoded_size(utf8_str, str_len);
4369 
4370  const utf32* pt = &ptr()[idx];
4371 
4372  do
4373  {
4374  if (npos != find_codepoint(utf8_str, encsze, *pt--))
4375  return idx;
4376 
4377  } while (idx-- != 0);
4378 
4379  }
4380 
4381  return npos;
4382  }
4383 
4409  size_type find_last_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4410  {
4411  if (str_len == npos)
4412  CEGUI_THROW(std::length_error("Length for utf8 encoded string can not be 'npos'"));
4413 
4414  if (d_cplength > 0)
4415  {
4416  if (idx >= d_cplength)
4417  idx = d_cplength - 1;
4418 
4419  size_type encsze = encoded_size(utf8_str, str_len);
4420 
4421  const utf32* pt = &ptr()[idx];
4422 
4423  do
4424  {
4425  if (npos == find_codepoint(utf8_str, encsze, *pt--))
4426  return idx;
4427 
4428  } while (idx-- != 0);
4429 
4430  }
4431 
4432  return npos;
4433  }
4434 
4435 
4450  size_type find_last_of(utf32 code_point, size_type idx = npos) const
4451  {
4452  return rfind(code_point, idx);
4453  }
4454 
4469  size_type find_last_not_of(utf32 code_point, size_type idx = npos) const
4470  {
4471  if (d_cplength > 0)
4472  {
4473  if (idx >= d_cplength)
4474  idx = d_cplength - 1;
4475 
4476  do
4477  {
4478  if ((*this)[idx] != code_point)
4479  return idx;
4480 
4481  } while(idx-- != 0);
4482 
4483  }
4484 
4485  return npos;
4486  }
4487 
4488 
4505  size_type find_last_of(const char* cstr, size_type idx = npos) const
4506  {
4507  return find_last_of(cstr, idx, strlen(cstr));
4508  }
4509 
4510 
4527  size_type find_last_not_of(const char* cstr, size_type idx = npos) const
4528  {
4529  return find_last_not_of(cstr, idx, strlen(cstr));
4530  }
4531 
4532 
4552  size_type find_last_of(const char* chars, size_type idx, size_type chars_len) const
4553  {
4554  if (chars_len == npos)
4555  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
4556 
4557  if (d_cplength > 0)
4558  {
4559  if (idx >= d_cplength)
4560  idx = d_cplength - 1;
4561 
4562  const utf32* pt = &ptr()[idx];
4563 
4564  do
4565  {
4566  if (npos != find_codepoint(chars, chars_len, *pt--))
4567  return idx;
4568 
4569  } while (idx-- != 0);
4570 
4571  }
4572 
4573  return npos;
4574  }
4575 
4576 
4596  size_type find_last_not_of(const char* chars, size_type idx, size_type chars_len) const
4597  {
4598  if (chars_len == npos)
4599  CEGUI_THROW(std::length_error("Length for char array can not be 'npos'"));
4600 
4601  if (d_cplength > 0)
4602  {
4603  if (idx >= d_cplength)
4604  idx = d_cplength - 1;
4605 
4606  const utf32* pt = &ptr()[idx];
4607 
4608  do
4609  {
4610  if (npos == find_codepoint(chars, chars_len, *pt--))
4611  return idx;
4612 
4613  } while (idx-- != 0);
4614 
4615  }
4616 
4617  return npos;
4618  }
4619 
4620 
4622  // Substring
4624 
4639  String substr(size_type idx = 0, size_type len = npos) const
4640  {
4641  if (d_cplength < idx)
4642  CEGUI_THROW(std::out_of_range("Index is out of range for this CEGUI::String"));
4643 
4644  return String(*this, idx, len);
4645  }
4646 
4648  // Iterator creation
4650 
4658  {
4659  return iterator(ptr());
4660  }
4661 
4669  const_iterator begin(void) const
4670  {
4671  return const_iterator(ptr());
4672  }
4673 
4682  {
4683  return iterator(&ptr()[d_cplength]);
4684  }
4685 
4693  const_iterator end(void) const
4694  {
4695  return const_iterator(&ptr()[d_cplength]);
4696  }
4697 
4705  reverse_iterator rbegin(void)
4706  {
4707  return reverse_iterator(end());
4708  }
4709 
4717  const_reverse_iterator rbegin(void) const
4718  {
4719  return const_reverse_iterator(end());
4720  }
4721 
4729  reverse_iterator rend(void)
4730  {
4731  return reverse_iterator(begin());
4732  }
4733 
4741  const_reverse_iterator rend(void) const
4742  {
4743  return const_reverse_iterator(begin());
4744  }
4745 
4746 private:
4747  /*************************************************************************
4748  Implementation Functions
4749  *************************************************************************/
4750  // string management
4751 
4752  // change size of allocated buffer so it is at least 'new_size'.
4753  // May or may not cause re-allocation and copy of buffer if size is larger
4754  // will never re-allocate to make size smaller. (see trim())
4755  bool grow(size_type new_size);
4756 
4757  // perform re-allocation to remove wasted space.
4758  void trim(void);
4759 
4760  // set the length of the string, and terminate it, according to the given value (will not re-allocate, use grow() first).
4761  void setlen(size_type len)
4762  {
4763  d_cplength = len;
4764  ptr()[len] = (utf32)(0);
4765  }
4766 
4767  // initialise string object
4768  void init(void)
4769  {
4770  d_reserve = CEGUI_STR_QUICKBUFF_SIZE;
4771  d_encodedbuff = 0;
4772  d_encodedbufflen = 0;
4773  d_encodeddatlen = 0;
4774  d_buffer = 0;
4775  setlen(0);
4776  }
4777 
4778  // return true if the given pointer is inside the string data
4779  bool inside(utf32* inptr)
4780  {
4781  if (inptr < ptr() || ptr() + d_cplength <= inptr)
4782  return false;
4783  else
4784  return true;
4785  }
4786 
4787  // compute distance between two iterators, returning a 'safe' value
4788  size_type safe_iter_dif(const const_iterator& iter1, const const_iterator& iter2) const
4789  {
4790  return (iter1.d_ptr == 0) ? 0 : (iter1 - iter2);
4791  }
4792 
4793  // encoding functions
4794  // for all:
4795  // src_len is in code units, or 0 for null terminated string.
4796  // dest_len is in code units.
4797  // returns number of code units put into dest buffer.
4798  size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
4799  {
4800  // count length for null terminated source...
4801  if (src_len == 0)
4802  {
4803  src_len = utf_length(src);
4804  }
4805 
4806  size_type destCapacity = dest_len;
4807 
4808  // while there is data in the source buffer,
4809  for (uint idx = 0; idx < src_len; ++idx)
4810  {
4811  utf32 cp = src[idx];
4812 
4813  // check there is enough destination buffer to receive this encoded unit (exit loop & return if not)
4814  if (destCapacity < encoded_size(cp))
4815  {
4816  break;
4817  }
4818 
4819  if (cp < 0x80)
4820  {
4821  *dest++ = (utf8)cp;
4822  --destCapacity;
4823  }
4824  else if (cp < 0x0800)
4825  {
4826  *dest++ = (utf8)((cp >> 6) | 0xC0);
4827  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4828  destCapacity -= 2;
4829  }
4830  else if (cp < 0x10000)
4831  {
4832  *dest++ = (utf8)((cp >> 12) | 0xE0);
4833  *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4834  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4835  destCapacity -= 3;
4836  }
4837  else
4838  {
4839  *dest++ = (utf8)((cp >> 18) | 0xF0);
4840  *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
4841  *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4842  *dest++ = (utf8)((cp & 0x3F) | 0x80);
4843  destCapacity -= 4;
4844  }
4845 
4846  }
4847 
4848  return dest_len - destCapacity;
4849  }
4850 
4851  size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
4852  {
4853  // count length for null terminated source...
4854  if (src_len == 0)
4855  {
4856  src_len = utf_length(src);
4857  }
4858 
4859  size_type destCapacity = dest_len;
4860 
4861  // while there is data in the source buffer, and space in the dest buffer
4862  for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
4863  {
4864  utf32 cp;
4865  utf8 cu = src[idx++];
4866 
4867  if (cu < 0x80)
4868  {
4869  cp = (utf32)(cu);
4870  }
4871  else if (cu < 0xE0)
4872  {
4873  cp = ((cu & 0x1F) << 6);
4874  cp |= (src[idx++] & 0x3F);
4875  }
4876  else if (cu < 0xF0)
4877  {
4878  cp = ((cu & 0x0F) << 12);
4879  cp |= ((src[idx++] & 0x3F) << 6);
4880  cp |= (src[idx++] & 0x3F);
4881  }
4882  else
4883  {
4884  cp = ((cu & 0x07) << 18);
4885  cp |= ((src[idx++] & 0x3F) << 12);
4886  cp |= ((src[idx++] & 0x3F) << 6);
4887  cp |= (src[idx++] & 0x3F);
4888  }
4889 
4890  *dest++ = cp;
4891  --destCapacity;
4892  }
4893 
4894  return dest_len - destCapacity;
4895  }
4896 
4897  // return the number of utf8 code units required to encode the given utf32 code point
4898  size_type encoded_size(utf32 code_point) const
4899  {
4900  if (code_point < 0x80)
4901  return 1;
4902  else if (code_point < 0x0800)
4903  return 2;
4904  else if (code_point < 0x10000)
4905  return 3;
4906  else
4907  return 4;
4908  }
4909 
4910  // return number of code units required to re-encode given null-terminated utf32 data as utf8. return does not include terminating null.
4911  size_type encoded_size(const utf32* buf) const
4912  {
4913  return encoded_size(buf, utf_length(buf));
4914  }
4915 
4916  // return number of code units required to re-encode given utf32 data as utf8. len is number of code units in 'buf'.
4917  size_type encoded_size(const utf32* buf, size_type len) const
4918  {
4919  size_type count = 0;
4920 
4921  while (len--)
4922  {
4923  count += encoded_size(*buf++);
4924  }
4925 
4926  return count;
4927  }
4928 
4929  // return number of utf32 code units required to re-encode given utf8 data as utf32. return does not include terminating null.
4930  size_type encoded_size(const utf8* buf) const
4931  {
4932  return encoded_size(buf, utf_length(buf));
4933  }
4934 
4935  // return number of utf32 code units required to re-encode given utf8 data as utf32. len is number of code units in 'buf'.
4936  size_type encoded_size(const utf8* buf, size_type len) const
4937  {
4938  utf8 tcp;
4939  size_type count = 0;
4940 
4941  while (len--)
4942  {
4943  tcp = *buf++;
4944  ++count;
4945  size_type size = 0;
4946 
4947  if (tcp < 0x80)
4948  {
4949  }
4950  else if (tcp < 0xE0)
4951  {
4952  size = 1;
4953  ++buf;
4954  }
4955  else if (tcp < 0xF0)
4956  {
4957  size = 2;
4958  buf += 2;
4959  }
4960  else
4961  {
4962  size = 3;
4963  buf += 3;
4964  }
4965 
4966  if (len >= size)
4967  len -= size;
4968  else
4969  break;
4970  }
4971 
4972  return count;
4973  }
4974 
4975  // return number of code units in a null terminated string
4976  size_type utf_length(const utf8* utf8_str) const
4977  {
4978  size_type cnt = 0;
4979  while (*utf8_str++)
4980  cnt++;
4981 
4982  return cnt;
4983  }
4984 
4985  // return number of code units in a null terminated string
4986  size_type utf_length(const utf32* utf32_str) const
4987  {
4988  size_type cnt = 0;
4989  while (*utf32_str++)
4990  cnt++;
4991 
4992  return cnt;
4993  }
4994 
4995  // build an internal buffer with the string encoded as utf8 (remains valid until string is modified).
4996  utf8* build_utf8_buff(void) const;
4997 
4998  // compare two utf32 buffers
4999  int utf32_comp_utf32(const utf32* buf1, const utf32* buf2, size_type cp_count) const
5000  {
5001  if (!cp_count)
5002  return 0;
5003 
5004  while ((--cp_count) && (*buf1 == *buf2))
5005  buf1++, buf2++;
5006 
5007  return *buf1 - *buf2;
5008  }
5009 
5010  // compare utf32 buffer with char buffer (chars are taken to be code-points in the range 0x00-0xFF)
5011  int utf32_comp_char(const utf32* buf1, const char* buf2, size_type cp_count) const
5012  {
5013  if (!cp_count)
5014  return 0;
5015 
5016  while ((--cp_count) && (*buf1 == static_cast<utf32>(static_cast<unsigned char>(*buf2))))
5017  buf1++, buf2++;
5018 
5019  return *buf1 - static_cast<utf32>(static_cast<unsigned char>(*buf2));
5020  }
5021 
5022  // compare utf32 buffer with encoded utf8 data
5023  int utf32_comp_utf8(const utf32* buf1, const utf8* buf2, size_type cp_count) const
5024  {
5025  if (!cp_count)
5026  return 0;
5027 
5028  utf32 cp;
5029  utf8 cu;
5030 
5031  do
5032  {
5033  cu = *buf2++;
5034 
5035  if (cu < 0x80)
5036  {
5037  cp = (utf32)(cu);
5038  }
5039  else if (cu < 0xE0)
5040  {
5041  cp = ((cu & 0x1F) << 6);
5042  cp |= (*buf2++ & 0x3F);
5043  }
5044  else if (cu < 0xF0)
5045  {
5046  cp = ((cu & 0x0F) << 12);
5047  cp |= ((*buf2++ & 0x3F) << 6);
5048  cp |= (*buf2++ & 0x3F);
5049  }
5050  else
5051  {
5052  cp = ((cu & 0x07) << 18);
5053  cp |= ((*buf2++ & 0x3F) << 12);
5054  cp |= ((*buf2++ & 0x3F) << 6);
5055  cp |= (*buf2++ & 0x3F);
5056  }
5057 
5058  } while ((*buf1++ == cp) && (--cp_count));
5059 
5060  return (*--buf1) - cp;
5061  }
5062 
5063  // return index of first occurrence of 'code_point' in std::string 'str', or npos if none
5064  size_type find_codepoint(const std::string& str, utf32 code_point) const
5065  {
5066  size_type idx = 0, sze = (size_type)str.size();
5067 
5068  while (idx != sze)
5069  {
5070  if (code_point == static_cast<utf32>(static_cast<unsigned char>(str[idx])))
5071  return idx;
5072 
5073  ++idx;
5074  }
5075 
5076  return npos;
5077  }
5078 
5079  // return index of first occurrence of 'code_point' in utf8 encoded string 'str', or npos if none. len is in code points.
5080  size_type find_codepoint(const utf8* str, size_type len, utf32 code_point) const
5081  {
5082  size_type idx = 0;
5083 
5084  utf32 cp;
5085  utf8 cu;
5086 
5087  while (idx != len) {
5088  cu = *str++;
5089 
5090  if (cu < 0x80)
5091  {
5092  cp = (utf32)(cu);
5093  }
5094  else if (cu < 0xE0)
5095  {
5096  cp = ((cu & 0x1F) << 6);
5097  cp |= (*str++ & 0x3F);
5098  }
5099  else if (cu < 0xF0)
5100  {
5101  cp = ((cu & 0x0F) << 12);
5102  cp |= ((*str++ & 0x3F) << 6);
5103  cp |= (*str++ & 0x3F);
5104  }
5105  else
5106  {
5107  cp = ((cu & 0x07) << 18);
5108  cp |= ((*str++ & 0x3F) << 12);
5109  cp |= ((*str++ & 0x3F) << 6);
5110  cp |= (*str++ & 0x3F);
5111  }
5112 
5113  if (code_point == cp)
5114  return idx;
5115 
5116  ++idx;
5117  }
5118 
5119  return npos;
5120  }
5121 
5122 
5123  // return index of first occurrence of 'code_point' in char array 'chars', or npos if none
5124  size_type find_codepoint(const char* chars, size_type chars_len, utf32 code_point) const
5125  {
5126  for (size_type idx = 0; idx != chars_len; ++idx)
5127  {
5128  if (code_point == static_cast<utf32>(static_cast<unsigned char>(chars[idx])))
5129  return idx;
5130  }
5131 
5132  return npos;
5133  }
5134 
5135 };
5136 
5137 
5139 // Comparison operators
5141 
5145 bool CEGUIEXPORT operator==(const String& str1, const String& str2);
5146 
5151 bool CEGUIEXPORT operator==(const String& str, const std::string& std_str);
5152 
5157 bool CEGUIEXPORT operator==(const std::string& std_str, const String& str);
5158 
5163 bool CEGUIEXPORT operator==(const String& str, const utf8* utf8_str);
5164 
5169 bool CEGUIEXPORT operator==(const utf8* utf8_str, const String& str);
5170 
5175 bool CEGUIEXPORT operator!=(const String& str1, const String& str2);
5176 
5181 bool CEGUIEXPORT operator!=(const String& str, const std::string& std_str);
5182 
5187 bool CEGUIEXPORT operator!=(const std::string& std_str, const String& str);
5188 
5193 bool CEGUIEXPORT operator!=(const String& str, const utf8* utf8_str);
5194 
5199 bool CEGUIEXPORT operator!=(const utf8* utf8_str, const String& str);
5200 
5205 bool CEGUIEXPORT operator<(const String& str1, const String& str2);
5206 
5211 bool CEGUIEXPORT operator<(const String& str, const std::string& std_str);
5212 
5217 bool CEGUIEXPORT operator<(const std::string& std_str, const String& str);
5218 
5223 bool CEGUIEXPORT operator<(const String& str, const utf8* utf8_str);
5224 
5229 bool CEGUIEXPORT operator<(const utf8* utf8_str, const String& str);
5230 
5235 bool CEGUIEXPORT operator>(const String& str1, const String& str2);
5236 
5241 bool CEGUIEXPORT operator>(const String& str, const std::string& std_str);
5242 
5247 bool CEGUIEXPORT operator>(const std::string& std_str, const String& str);
5248 
5253 bool CEGUIEXPORT operator>(const String& str, const utf8* utf8_str);
5254 
5259 bool CEGUIEXPORT operator>(const utf8* utf8_str, const String& str);
5260 
5265 bool CEGUIEXPORT operator<=(const String& str1, const String& str2);
5266 
5271 bool CEGUIEXPORT operator<=(const String& str, const std::string& std_str);
5272 
5277 bool CEGUIEXPORT operator<=(const std::string& std_str, const String& str);
5278 
5283 bool CEGUIEXPORT operator<=(const String& str, const utf8* utf8_str);
5284 
5289 bool CEGUIEXPORT operator<=(const utf8* utf8_str, const String& str);
5290 
5295 bool CEGUIEXPORT operator>=(const String& str1, const String& str2);
5296 
5301 bool CEGUIEXPORT operator>=(const String& str, const std::string& std_str);
5302 
5307 bool CEGUIEXPORT operator>=(const std::string& std_str, const String& str);
5308 
5313 bool CEGUIEXPORT operator>=(const String& str, const utf8* utf8_str);
5314 
5319 bool CEGUIEXPORT operator>=(const utf8* utf8_str, const String& str);
5320 
5325 bool CEGUIEXPORT operator==(const String& str, const char* c_str);
5326 
5331 bool CEGUIEXPORT operator==(const char* c_str, const String& str);
5332 
5337 bool CEGUIEXPORT operator!=(const String& str, const char* c_str);
5338 
5343 bool CEGUIEXPORT operator!=(const char* c_str, const String& str);
5344 
5349 bool CEGUIEXPORT operator<(const String& str, const char* c_str);
5350 
5355 bool CEGUIEXPORT operator<(const char* c_str, const String& str);
5356 
5361 bool CEGUIEXPORT operator>(const String& str, const char* c_str);
5362 
5367 bool CEGUIEXPORT operator>(const char* c_str, const String& str);
5368 
5373 bool CEGUIEXPORT operator<=(const String& str, const char* c_str);
5374 
5379 bool CEGUIEXPORT operator<=(const char* c_str, const String& str);
5380 
5385 bool CEGUIEXPORT operator>=(const String& str, const char* c_str);
5386 
5391 bool CEGUIEXPORT operator>=(const char* c_str, const String& str);
5392 
5394 // Concatenation operator functions
5396 
5411 String CEGUIEXPORT operator+(const String& str1, const String& str2);
5412 
5428 String CEGUIEXPORT operator+(const String& str, const std::string& std_str);
5429 
5445 String CEGUIEXPORT operator+(const std::string& std_str, const String& str);
5446 
5462 String CEGUIEXPORT operator+(const String& str, const utf8* utf8_str);
5463 
5479 String CEGUIEXPORT operator+(const utf8* utf8_str, const String& str);
5480 
5496 String CEGUIEXPORT operator+(const String& str, utf32 code_point);
5497 
5513 String CEGUIEXPORT operator+(utf32 code_point, const String& str);
5514 
5530 String CEGUIEXPORT operator+(const String& str, const char* c_str);
5531 
5547 String CEGUIEXPORT operator+(const char* c_str, const String& str);
5548 
5549 
5551 // Output (stream) functions
5553 CEGUIEXPORT std::ostream& operator<<(std::ostream& s, const String& str);
5554 
5555 
5557 // Modifying operations
5559 
5572 void CEGUIEXPORT swap(String& str1, String& str2);
5573 
5580 {
5581  bool operator() (const String& a, const String& b) const
5582  {
5583  const size_t la = a.length();
5584  const size_t lb = b.length();
5585  if (la == lb)
5586  return (memcmp(a.ptr(), b.ptr(), la * sizeof(utf32)) < 0);
5587 
5588  return (la < lb);
5589  }
5590 };
5591 
5592 #else
5593 
5595 typedef char encoded_char;
5596 
5597 #if CEGUI_STRING_CLASS == CEGUI_STRING_CLASS_STD
5598 
5599 typedef std::string String;
5600 
5601 #else // CEGUI_STRING_CLASS_STD_AO
5602 
5603 typedef std::basic_string<char, std::char_traits<char>, STLAllocatorWrapper<char, AllocatorConfig<STLAllocator>::Allocator> > String;
5604 
5605 #endif
5606 
5612 struct StringFastLessCompare
5613 {
5614  bool operator() (const String& a, const String& b) const
5615  {
5616  const size_t la = a.length();
5617  const size_t lb = b.length();
5618  if (la == lb)
5619  return (memcmp(a.c_str(), b.c_str(), la * sizeof(String::value_type)) < 0);
5620 
5621  return (la < lb);
5622  }
5623 };
5624 
5625 #if defined(_MSC_VER)
5626 # pragma warning(disable : 4251)
5627 #endif
5628 
5629 #endif
5630 
5631 } // End of CEGUI namespace section
5632 
5633 
5634 #endif // end of guard _CEGUIString_h_
String & replace(iterator iter_beg, iterator iter_end, const utf8 *utf8_str, size_type str_len)
Replace the code points in the range [beg, end) with the specified null-terminated utf8 encoded data...
Definition: String.h:2866
String & replace(iterator iter_beg, iterator iter_end, const char *chars, size_type chars_len)
Replace the code points in the range [beg, end) with chars from the given char array.
Definition: String.h:3131
size_type find_first_of(const utf8 *utf8_str, size_type idx, size_type str_len) const
Find the first occurrence of one of a set of code points.
Definition: String.h:3876
const_iterator begin(void) const
Return a constant forwards iterator that describes the beginning of the String.
Definition: String.h:4669
std::reverse_iterator< const_iterator > const_reverse_iterator
Constant reverse iterator class for String objects.
Definition: String.h:321
size_type find_last_of(utf32 code_point, size_type idx=npos) const
Search for last occurrence of a given code point.
Definition: String.h:4450
String(const std::string &std_str)
Constructs a new string and initialises it using the std::string std_str.
Definition: String.h:414
bool CEGUIEXPORT operator>(const String &str1, const String &str2)
Return true if String str1 is lexicographically greater than String str2.
String & erase(iterator pos)
Erase the code point described by the given iterator.
Definition: String.h:2428
const utf32 * ptr(void) const
Returns a pointer to the buffer in use. (const version)
Definition: String.h:1179
size_type find(const char *cstr, size_type idx=0) const
Search forwards for a sub-string.
Definition: String.h:3539
Functor that can be used as comparator in a std::map with String keys. It's faster than using the def...
Definition: String.h:5579
void CEGUIEXPORT swap(String &str1, String &str2)
Swap the contents for two String objects.
reference operator[](size_type idx)
Returns the code point at the given index.
Definition: String.h:1062
size_type find_last_of(const char *cstr, size_type idx=npos) const
Find the last occurrence of one of a set of chars.
Definition: String.h:4505
String & append(const utf8 *utf8_str)
Appends to the String the null-terminated utf8 encoded data in the buffer utf8_str.
Definition: String.h:1750
String & operator+=(utf32 code_point)
Appends a single code point to the string.
Definition: String.h:1805
size_type rfind(utf32 code_point, size_type idx=npos) const
Search backwards for a given code point.
Definition: String.h:3187
String & insert(size_type idx, const utf8 *utf8_str)
Inserts the given null-terminated utf8 encoded data at the specified position.
Definition: String.h:2114
String & operator+=(const std::string &std_str)
Appends the std::string std_str.
Definition: String.h:1660
size_type find(const utf8 *utf8_str, size_type idx, size_type str_len) const
Search forwards for a sub-string.
Definition: String.h:3444
regular iterator for String.
Definition: String.h:98
String & replace(iterator iter_beg, iterator iter_end, const utf8 *utf8_str)
Replace the code points in the range [beg, end) with the specified null-terminated utf8 encoded data...
Definition: String.h:2778
Definition: MemoryAllocatedObject.h:109
size_type find(const String &str, size_type idx=0) const
Search forwards for a sub-string.
Definition: String.h:3225
size_type find_first_of(const std::string &std_str, size_type idx=0) const
Find the first occurrence of one of a set of code points.
Definition: String.h:3742
String & replace(iterator iter_beg, iterator iter_end, const_iterator iter_newBeg, const_iterator iter_newEnd)
Replace the code points in the range [beg, end) with code points from the range [newBeg, newEnd).
Definition: String.h:2975
String & insert(size_type idx, const char *cstr)
Inserts the given c-string at the specified position.
Definition: String.h:2289
String & replace(size_type idx, size_type len, const utf8 *utf8_str)
Replace code points in the String with the specified null-terminated utf8 encoded data...
Definition: String.h:2746
String & erase(void)
Removes all data from the String.
Definition: String.h:2361
void swap(String &str)
Swaps the value of this String with the given String str.
Definition: String.h:1564
bool CEGUIEXPORT operator==(const String &str1, const String &str2)
Return true if String str1 is equal to String str2.
std::ptrdiff_t difference_type
Signed type used for differences.
Definition: String.h:71
String(const char *chars, size_type chars_len)
Constructs a new String object and initialise it using characters from the provided char array...
Definition: String.h:592
String(const_iterator iter_beg, const_iterator iter_end)
Construct a new string object and initialise it with code-points from the range [beg, end).
Definition: String.h:549
Main namespace for Crazy Eddie's GUI Library.
Definition: arch_overview.dox:1
size_type rfind(const std::string &std_str, size_type idx=npos) const
Search backwards for a sub-string.
Definition: String.h:3341
size_t size_type
Unsigned type used for size values and indices.
Definition: String.h:70
bool empty(void) const
Returns true if the String is empty.
Definition: String.h:633
bool CEGUIEXPORT operator>=(const String &str1, const String &str2)
Return true if String str1 is lexicographically greater than or equal to String str2.
String(const utf8 *utf8_str, size_type chars_len)
Constructs a new String object and initialise it using the provided utf8 encoded string buffer...
Definition: String.h:502
size_type find_last_of(const char *chars, size_type idx, size_type chars_len) const
Find the last occurrence of one of a set of chars.
Definition: String.h:4552
String & append(const_iterator iter_beg, const_iterator iter_end)
Appends the code points in the reange [beg, end)
Definition: String.h:1875
String & operator=(const char *cstr)
Assign to this String the given C-string.
Definition: String.h:1500
String & append(const std::string &std_str, size_type str_idx=0, size_type str_num=npos)
Appends a sub-string of the std::string std_str.
Definition: String.h:1688
size_type find_first_not_of(utf32 code_point, size_type idx=0) const
Search forwards for the first code point that does not match a given code point.
Definition: String.h:3983
String & assign(const char *chars, size_type chars_len)
Assign to this String a number of chars from a char array.
Definition: String.h:1539
value_type operator[](size_type idx) const
Returns the code point at the given index.
Definition: String.h:1081
String & operator=(const utf8 *utf8_str)
Assign to this String the string value represented by the given null-terminated utf8 encoded data...
Definition: String.h:1380
size_type find_last_of(const utf8 *utf8_str, size_type idx=npos) const
Find the last occurrence of one of a set of code points.
Definition: String.h:4301
size_type length(void) const
Returns the size of the String in code points.
Definition: String.h:621
String & assign(const utf8 *utf8_str, size_type str_num)
Assign to this String the string value represented by the given utf8 encoded data.
Definition: String.h:1429
String & replace(size_type idx, size_type len, const utf8 *utf8_str, size_type str_len)
Replace code points in the String with the specified utf8 encoded data.
Definition: String.h:2811
String substr(size_type idx=0, size_type len=npos) const
Returns a substring of this String.
Definition: String.h:4639
const iterator for String.
Definition: String.h:203
String & insert(size_type idx, const std::string &std_str, size_type str_idx, size_type str_num)
Inserts a sub-string of the given std::string object at the specified position.
Definition: String.h:2066
size_type utf8_stream_len(size_type num=npos, size_type idx=0) const
Return the number of utf8 code units required to hold an area of the String when encoded as utf8 data...
Definition: String.h:1236
String & replace(iterator iter_beg, iterator iter_end, const char *cstr)
Replace the code points in the range [beg, end) with the specified c-string.
Definition: String.h:3051
iterator end(void)
Return a forwards iterator that describes the end of the String.
Definition: String.h:4681
String & operator+=(const char *cstr)
Appends to the String the given c-string.
Definition: String.h:1893
void push_back(utf32 code_point)
Appends a single code point to the string.
Definition: String.h:1855
int compare(const std::string &std_str) const
Compares this String with the std::string 'std_str'.
Definition: String.h:781
const utf8 * data(void) const
Returns contents of the String as utf8 encoded data.
Definition: String.h:1161
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator class for String objects.
Definition: String.h:331
size_type capacity(void) const
Return the number of code points that the String could hold before a re-allocation would be required...
Definition: String.h:665
size_type rfind(const String &str, size_type idx=npos) const
Search backwards for a sub-string.
Definition: String.h:3260
void insert(iterator pos, size_type num, utf32 code_point)
Inserts a code point multiple times into the String.
Definition: String.h:2223
size_type find_first_of(const char *chars, size_type idx, size_type chars_len) const
Find the first occurrence of one of a set of chars.
Definition: String.h:4063
const_reverse_iterator rbegin(void) const
Return a constant reverse iterator that describes the beginning of the String.
Definition: String.h:4717
String & operator=(const String &str)
Assign the value of String str to this String.
Definition: String.h:1261
String(const std::string &std_str, size_type str_idx, size_type str_num=npos)
Constructs a new string initialised with characters from the given std::string object.
Definition: String.h:442
utf32 * ptr(void)
Returns a pointer to the buffer in use.
Definition: String.h:1170
int compare(size_type idx, size_type len, const utf8 *utf8_str) const
Compares code points from this String with the null-terminated utf8 encoded 'utf8_str'.
Definition: String.h:896
utf32 * pointer
Type used for utf32 code point pointers.
Definition: String.h:74
size_type size(void) const
Returns the size of the String in code points.
Definition: String.h:609
size_type find_first_of(const char *cstr, size_type idx=0) const
Find the first occurrence of one of a set of chars.
Definition: String.h:4016
size_type find(utf32 code_point, size_type idx=0) const
Search forwards for a given code point.
Definition: String.h:3154
const_reference at(size_type idx) const
Returns the code point at the given index.
Definition: String.h:1118
const_iterator end(void) const
Return a constant forwards iterator that describes the end of the String.
Definition: String.h:4693
size_type find_first_not_of(const utf8 *utf8_str, size_type idx=0) const
Find the first code point that is not one of a set of code points.
Definition: String.h:3846
String & replace(size_type idx, size_type len, const String &str)
Replace code points in the String with the specified String object.
Definition: String.h:2521
String & operator=(utf32 code_point)
Assigns the specified utf32 code point to this String. Result is always a String 1 code point in leng...
Definition: String.h:1452
String & insert(size_type idx, size_type num, utf32 code_point)
Inserts a code point multiple times into the String.
Definition: String.h:2182
size_type find_last_not_of(utf32 code_point, size_type idx=npos) const
Search for the last code point that does not match a given code point.
Definition: String.h:4469
String & assign(const utf8 *utf8_str)
Assign to this String the string value represented by the given null-terminated utf8 encoded data...
Definition: String.h:1403
String & replace(iterator iter_beg, iterator iter_end, size_type num, utf32 code_point)
Replace the code points in the range [beg, end) with occurrences of a given code point.
Definition: String.h:2945
String & replace(size_type idx, size_type len, const String &str, size_type str_idx, size_type str_num)
Replace code points in the String with a specified sub-string of a given String object.
Definition: String.h:2577
String & replace(iterator iter_beg, iterator iter_end, const std::string &std_str)
Replace the code points in the range [beg, end) with the specified std::string object.
Definition: String.h:2655
const char * c_str(void) const
Returns contents of the String as a null terminated string of utf8 encoded data.
Definition: String.h:1143
const utf32 * const_pointer
Type used for constant utf32 code point pointers.
Definition: String.h:75
int compare(size_type idx, size_type len, const std::string &std_str, size_type str_idx=0, size_type str_len=npos) const
Compares code points from this String with code points from the std::string 'std_str'.
Definition: String.h:820
int compare(size_type idx, size_type len, const char *cstr) const
Compares code points from this String with the given c-string.
Definition: String.h:995
void resize(size_type num)
Resizes the String either by inserting default utf32 code points to make it larger, or by truncating to make it smaller.
Definition: String.h:2466
String & assign(size_type num, utf32 code_point)
Assigns the specified code point repeatedly to the String.
Definition: String.h:1472
int compare(size_type idx, size_type len, const char *chars, size_type chars_len) const
Compares code points from this String with chars in the given char array.
Definition: String.h:1028
String & insert(size_type idx, const char *chars, size_type chars_len)
Inserts chars from the given char array at the specified position.
Definition: String.h:2314
utf32 & reference
Type used for utf32 code point references.
Definition: String.h:72
size_type find_first_not_of(const char *chars, size_type idx, size_type chars_len) const
Find the first code point that is not one of a set of chars.
Definition: String.h:4104
String & insert(size_type idx, const String &str)
Inserts the given String object at the specified position.
Definition: String.h:1971
size_type rfind(const utf8 *utf8_str, size_type idx=npos) const
Search backwards for a sub-string.
Definition: String.h:3414
bool CEGUIEXPORT operator<=(const String &str1, const String &str2)
Return true if String str1 is lexicographically less than or equal to String str2.
size_type copy(utf8 *buf, size_type len=npos, size_type idx=0) const
Copies an area of the String into the provided buffer as encoded utf8 data.
Definition: String.h:1206
utf8 encoded_char
encoded char signifies that it's a char (8bit) with encoding (in this case utf8)
Definition: String.h:50
void insert(iterator iter_pos, const_iterator iter_beg, const_iterator iter_end)
Inserts code points specified by the range [beg, end).
Definition: String.h:2267
String & replace(size_type idx, size_type len, const char *cstr)
Replace code points in the String with the specified c-string.
Definition: String.h:3024
size_type find_first_not_of(const std::string &std_str, size_type idx=0) const
Find the first code point that is not one of a set of code points.
Definition: String.h:3778
String & erase(iterator iter_beg, iterator iter_end)
Erase a range of code points described by the iterators [beg, end).
Definition: String.h:2446
const utf32 & const_reference
Type used for constant utf32 code point references.
Definition: String.h:73
String(const String &str, size_type str_idx, size_type str_num=npos)
Constructs a new string initialised with code points from another String object.
Definition: String.h:389
String & assign(const std::string &std_str, size_type str_idx=0, size_type str_num=npos)
Assign a sub-string of std::string std_str to this String.
Definition: String.h:1343
String & assign(const char *cstr)
Assign to this String the given C-string.
Definition: String.h:1518
String(void)
Constructs an empty string.
Definition: String.h:342
String CEGUIEXPORT operator+(const String &str1, const String &str2)
Return String object that is the concatenation of the given inputs.
bool CEGUIEXPORT operator<(const String &str1, const String &str2)
Return true if String str1 is lexicographically less than String str2.
size_type find_last_not_of(const char *cstr, size_type idx=npos) const
Find the last code point that is not one of a set of chars.
Definition: String.h:4527
String & insert(size_type idx, const std::string &std_str)
Inserts the given std::string object at the specified position.
Definition: String.h:2035
size_type find_first_of(const String &str, size_type idx=0) const
Find the first occurrence of one of a set of code points.
Definition: String.h:3673
String & replace(size_type idx, size_type len, const std::string &std_str, size_type str_idx, size_type str_num)
Replace code points in the String with a specified sub-string of a given std::string object...
Definition: String.h:2689
size_type find_first_of(utf32 code_point, size_type idx=0) const
Search forwards for a given code point.
Definition: String.h:3962
size_type find_last_of(const std::string &std_str, size_type idx=npos) const
Find the last occurrence of one of a set of code points.
Definition: String.h:4218
String & append(const char *cstr)
Appends to the String the given c-string.
Definition: String.h:1911
size_type find_last_of(const utf8 *utf8_str, size_type idx, size_type str_len) const
Find the last occurrence of one of a set of code points.
Definition: String.h:4358
void reserve(size_type num=0)
Specifies the amount of reserve capacity to allocate.
Definition: String.h:685
size_type find_last_of(const String &str, size_type idx=npos) const
Find the last occurrence of one of a set of code points.
Definition: String.h:4143
size_type rfind(const char *cstr, size_type idx=npos) const
Search backwards for a sub-string.
Definition: String.h:3561
String(const char *cstr)
Constructs a new String object and initialise it using the provided c-string.
Definition: String.h:571
iterator insert(iterator pos, utf32 code_point)
Inserts a single code point into the String.
Definition: String.h:2243
String & append(size_type num, utf32 code_point)
Appends a single code point multiple times to the string.
Definition: String.h:1825
size_type find_last_not_of(const std::string &std_str, size_type idx=npos) const
Find the last code point that is not one of a set of code points.
Definition: String.h:4257
size_type rfind(const utf8 *utf8_str, size_type idx, size_type str_len) const
Search backwards for a sub-string.
Definition: String.h:3495
reverse_iterator rbegin(void)
Return a reverse iterator that describes the beginning of the String.
Definition: String.h:4705
String & operator+=(const String &str)
Appends the String str.
Definition: String.h:1605
size_type find_first_not_of(const char *cstr, size_type idx=0) const
Find the first code point that is not one of a set of chars.
Definition: String.h:4038
utf32 value_type
Basic 'code point' type used for String (utf32)
Definition: String.h:69
size_type find_last_not_of(const utf8 *utf8_str, size_type idx=npos) const
Find the last code point that is not one of a set of code points.
Definition: String.h:4328
bool CEGUIEXPORT operator!=(const String &str1, const String &str2)
Return true if String str1 is not equal to String str2.
String & operator=(const std::string &std_str)
Assign the value of std::string std_str to this String.
Definition: String.h:1315
size_type rfind(const char *chars, size_type idx, size_type chars_len) const
Search backwards for a sub-string.
Definition: String.h:3630
size_type find_last_not_of(const utf8 *utf8_str, size_type idx, size_type str_len) const
Find the last code point that is not one of a set of code points.
Definition: String.h:4409
int compare(const String &str) const
Compares this String with the String 'str'.
Definition: String.h:711
String & replace(size_type idx, size_type len, const char *chars, size_type chars_len)
Replace code points in the String with chars from the given char array.
Definition: String.h:3079
size_type find_first_not_of(const String &str, size_type idx=0) const
Find the first code point that is not one of a set of code points.
Definition: String.h:3705
int compare(size_type idx, size_type len, const utf8 *utf8_str, size_type str_cplen) const
Compares code points from this String with the utf8 encoded data in buffer 'utf8_str'.
Definition: String.h:934
iterator begin(void)
Return a forwards iterator that describes the beginning of the String.
Definition: String.h:4657
String & insert(size_type idx, const String &str, size_type str_idx, size_type str_num)
Inserts a sub-string of the given String object at the specified position.
Definition: String.h:1998
int compare(const char *cstr) const
Compares this String with the given c-string.
Definition: String.h:966
const_reverse_iterator rend(void) const
Return a constant reverse iterator that describes the end of the String.
Definition: String.h:4741
size_type find_first_of(const utf8 *utf8_str, size_type idx=0) const
Find the first occurrence of one of a set of code points.
Definition: String.h:3819
String(size_type num, utf32 code_point)
Constructs a new String that is initialised with the specified code point.
Definition: String.h:526
String & replace(size_type idx, size_type len, const std::string &std_str)
Replace code points in the String with the specified std::string object.
Definition: String.h:2625
String & insert(size_type idx, const utf8 *utf8_str, size_type len)
Inserts the given utf8 encoded data at the specified position.
Definition: String.h:2144
size_type find(const char *chars, size_type idx, size_type chars_len) const
Search forwards for a sub-string.
Definition: String.h:3586
static const size_type npos
Value used to represent 'not found' conditions and 'all code points' etc.
Definition: String.h:77
reference at(size_type idx)
Returns the code point at the given index.
Definition: String.h:1098
String(const String &str)
Copy constructor - Creates a new string with the same value as str.
Definition: String.h:366
int compare(const utf8 *utf8_str) const
Compares this String with the null-terminated utf8 encoded 'utf8_str'.
Definition: String.h:861
size_type find_first_not_of(const utf8 *utf8_str, size_type idx, size_type str_len) const
Find the first code point that is not one of a set of code points.
Definition: String.h:3924
size_type find_last_not_of(const String &str, size_type idx=npos) const
Find the last code point that is not one of a set of code points.
Definition: String.h:4178
void resize(size_type num, utf32 code_point)
Resizes the String either by inserting the given utf32 code point to make it larger, or by truncating to make it smaller.
Definition: String.h:2486
String & replace(size_type idx, size_type len, size_type num, utf32 code_point)
Replaces a specified range of code points with occurrences of a given code point. ...
Definition: String.h:2893
String & erase(size_type idx, size_type len)
Erase a range of code points.
Definition: String.h:2399
int compare(size_type idx, size_type len, const String &str, size_type str_idx=0, size_type str_len=npos) const
Compares code points from this String with code points from the String 'str'.
Definition: String.h:745
size_type max_size(void) const
Returns the maximum size of a String.
Definition: String.h:647
String & assign(const String &str, size_type str_idx=0, size_type str_num=npos)
Assign a sub-string of String str to this String.
Definition: String.h:1284
void clear(void)
Removes all data from the String.
Definition: String.h:2348
size_type find_last_not_of(const char *chars, size_type idx, size_type chars_len) const
Find the last code point that is not one of a set of chars.
Definition: String.h:4596
String & append(const char *chars, size_type chars_len)
Appends to the String chars from the given char array.
Definition: String.h:1932
String & replace(iterator iter_beg, iterator iter_end, const String &str)
Replace the code points in the range [beg, end) with the specified String object. ...
Definition: String.h:2547
size_type find(const utf8 *utf8_str, size_type idx=0) const
Search forwards for a sub-string.
Definition: String.h:3387
reverse_iterator rend(void)
Return a reverse iterator that describes the end of the String.
Definition: String.h:4729
String & append(const utf8 *utf8_str, size_type len)
Appends to the String the utf8 encoded data in the buffer utf8_str.
Definition: String.h:1777
String & erase(size_type idx)
Erase a single code point from the string.
Definition: String.h:2379
String & operator+=(const utf8 *utf8_str)
Appends to the String the null-terminated utf8 encoded data in the buffer utf8_str.
Definition: String.h:1727
String(const utf8 *utf8_str)
Constructs a new String object and initialise it using the provided utf8 encoded string buffer...
Definition: String.h:470
String & append(const String &str, size_type str_idx=0, size_type str_num=npos)
Appends a sub-string of the String str.
Definition: String.h:1629
String class used within the GUI system.
Definition: String.h:62
size_type find(const std::string &std_str, size_type idx=0) const
Search forwards for a sub-string.
Definition: String.h:3300