updated on Wed Jan 25 16:08:47 UTC 2012
[aur-mirror.git] / cegui-0.5 / CEGUIString.h
blob13a61ba15de160bd1b1d21fd0626ceb57651f592
1 /***********************************************************************
2 filename: CEGUIString.h
3 created: 26/2/2004
4 author: Paul D Turner
6 purpose: Defines string class used within the GUI system.
7 *************************************************************************/
8 /***************************************************************************
9 * Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
11 * Permission is hereby granted, free of charge, to any person obtaining
12 * a copy of this software and associated documentation files (the
13 * "Software"), to deal in the Software without restriction, including
14 * without limitation the rights to use, copy, modify, merge, publish,
15 * distribute, sublicense, and/or sell copies of the Software, and to
16 * permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
19 * The above copyright notice and this permission notice shall be
20 * included in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 ***************************************************************************/
30 #ifndef _CEGUIString_h_
31 #define _CEGUIString_h_
33 #include "CEGUIBase.h"
34 #include <string>
35 #include <string.h>
36 #include <stdexcept>
38 // Start of CEGUI namespace section
39 namespace CEGUI
41 #define STR_QUICKBUFF_SIZE 32
42 /*************************************************************************
43 Basic Types
44 *************************************************************************/
45 typedef uint8 utf8;
46 //typedef uint16 utf16; // removed typedef to prevent usage, as utf16 is not supported (yet)
47 typedef uint32 utf32;
49 /*!
50 \brief
51 String class used within the GUI system.
53 For the most part, this class can replace std::string in basic usage. However, currently String does not use the
54 current locale, and also comparisons do not take into account the Unicode data tables, so are not 'correct'
55 as such.
57 class CEGUIEXPORT String
59 public:
60 /*************************************************************************
61 Integral Types
62 *************************************************************************/
63 typedef utf32 value_type; //!< Basic 'code point' type used for String (utf32)
64 typedef size_t size_type; //!< Unsigned type used for size values and indices
65 typedef std::ptrdiff_t difference_type; //!< Signed type used for differences
66 typedef utf32& reference; //!< Type used for utf32 code point references
67 typedef const utf32& const_reference; //!< Type used for constant utf32 code point references
68 typedef utf32* pointer; //!< Type used for utf32 code point pointers
69 typedef const utf32* const_pointer; //!< Type used for constant utf32 code point pointers
71 static const size_type npos; //!< Value used to represent 'not found' conditions and 'all code points' etc.
73 private:
74 /*************************************************************************
75 Implementation data
76 *************************************************************************/
77 size_type d_cplength; //!< holds length of string in code points (not including null termination)
78 size_type d_reserve; //!< code point reserve size (currently allocated buffer size in code points).
80 mutable utf8* d_encodedbuff; //!< holds string data encoded as utf8 (generated only by calls to c_str() and data())
81 mutable size_type d_encodeddatlen; //!< holds length of encoded data (in case it's smaller than buffer).
82 mutable size_type d_encodedbufflen; //!< length of above buffer (since buffer can be bigger then the data it holds to save re-allocations).
84 utf32 d_quickbuff[STR_QUICKBUFF_SIZE]; //!< This is a integrated 'quick' buffer to save allocations for smallish strings
85 utf32* d_buffer; //!< Pointer the the main buffer memory. This is only valid when quick-buffer is not being used
87 public:
88 /*************************************************************************
89 Iterator Classes
90 *************************************************************************/
91 /*!
92 \brief
93 Constant forward iterator class for String objects
95 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
96 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32>
97 #else
98 class const_iterator : public std::iterator<std::random_access_iterator_tag, utf32, std::ptrdiff_t, const utf32*, const utf32&>
99 #endif
102 public:
103 //////////////////////////////////////////////////////////////////////////
104 // data
105 //////////////////////////////////////////////////////////////////////////
106 const utf32* d_ptr;
109 //////////////////////////////////////////////////////////////////////////
110 // Methods
111 //////////////////////////////////////////////////////////////////////////
112 const_iterator(void)
114 d_ptr = 0;
116 const_iterator(const_pointer ptr)
118 d_ptr = ptr;
121 const_reference operator*() const
123 return *d_ptr;
126 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
127 # pragma warning (push)
128 # pragma warning (disable : 4284)
129 #endif
130 const_pointer operator->() const
132 return &**this;
135 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
136 # pragma warning (pop)
137 #endif
139 const_iterator& operator++()
141 ++d_ptr;
142 return *this;
145 const_iterator operator++(int)
147 const_iterator temp = *this;
148 ++*this;
149 return temp;
152 const_iterator& operator--()
154 --d_ptr;
155 return *this;
158 const_iterator operator--(int)
160 const_iterator temp = *this;
161 --*this;
162 return temp;
165 const_iterator& operator+=(difference_type offset)
167 d_ptr += offset;
168 return *this;
171 const_iterator operator+(difference_type offset) const
173 const_iterator temp = *this;
174 return temp += offset;
177 const_iterator& operator-=(difference_type offset)
179 return *this += -offset;
182 const_iterator operator-(difference_type offset) const
184 const_iterator temp = *this;
185 return temp -= offset;
188 difference_type operator-(const const_iterator& iter) const
190 return d_ptr - iter.d_ptr;
193 const_reference operator[](difference_type offset) const
195 return *(*this + offset);
198 bool operator==(const const_iterator& iter) const
200 return d_ptr == iter.d_ptr;
203 bool operator!=(const const_iterator& iter) const
205 return !(*this == iter);
208 bool operator<(const const_iterator& iter) const
210 return d_ptr < iter.d_ptr;
213 bool operator>(const const_iterator& iter) const
215 return (!(iter < *this));
218 bool operator<=(const const_iterator& iter) const
220 return (!(iter < *this));
223 bool operator>=(const const_iterator& iter) const
225 return (!(*this < iter));
228 friend const_iterator operator+(difference_type offset, const const_iterator& iter)
230 return iter + offset;
236 \brief
237 Forward iterator class for String objects
239 class iterator : public const_iterator
241 public:
242 iterator(void) {}
243 iterator(pointer ptr) : const_iterator(ptr) {}
246 reference operator*() const
248 return ((reference)**(const_iterator *)this);
251 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
252 # pragma warning (push)
253 # pragma warning (disable : 4284)
254 #endif
256 pointer operator->() const
258 return &**this;
261 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
262 # pragma warning (pop)
263 #endif
265 iterator& operator++()
267 ++this->d_ptr;
268 return *this;
271 iterator operator++(int)
273 iterator temp = *this;
274 ++*this;
275 return temp;
278 iterator& operator--()
280 --this->d_ptr;
281 return *this;
284 iterator operator--(int)
286 iterator temp = *this;
287 --*this;
288 return temp;
291 iterator& operator+=(difference_type offset)
293 this->d_ptr += offset;
294 return *this;
297 iterator operator+(difference_type offset) const
299 iterator temp = *this;
300 return temp + offset;
303 iterator& operator-=(difference_type offset)
305 return *this += -offset;
308 iterator operator-(difference_type offset) const
310 iterator temp = *this;
311 return temp -= offset;
314 difference_type operator-(const const_iterator& iter) const
316 return ((const_iterator)*this - iter);
319 reference operator[](difference_type offset) const
321 return *(*this + offset);
324 friend iterator operator+(difference_type offset, const iterator& iter)
326 return iter + offset;
332 \brief
333 Constant reverse iterator class for String objects
335 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
336 typedef std::reverse_iterator<const_iterator, const_pointer, const_reference, difference_type> const_reverse_iterator;
337 #else
338 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
339 #endif
342 \brief
343 Reverse iterator class for String objects
345 #if defined(_MSC_VER) && ((_MSC_VER <= 1200) || ((_MSC_VER <= 1300) && defined(_STLPORT_VERSION)))
346 typedef std::reverse_iterator<iterator, pointer, reference, difference_type> reverse_iterator;
347 #else
348 typedef std::reverse_iterator<iterator> reverse_iterator;
349 #endif
351 public:
353 \brief
354 Functor that can be used as comparator in a std::map with String keys.
355 It's faster than using the default, but the map will no longer be sorted alphabetically.
357 struct FastLessCompare
359 bool operator() (const String& a, const String& b) const
361 const size_t la = a.length();
362 const size_t lb = b.length();
363 if (la == lb)
364 return (memcmp(a.ptr(), b.ptr(), la*sizeof(utf32)) < 0);
365 return (la < lb);
369 public:
370 //////////////////////////////////////////////////////////////////////////
371 // Default Construction and Destructor
372 //////////////////////////////////////////////////////////////////////////
374 \brief
375 Constructs an empty string
377 String(void)
379 init();
383 \brief
384 Destructor for String objects
386 ~String(void);
388 //////////////////////////////////////////////////////////////////////////
389 // Construction via CEGUI::String
390 //////////////////////////////////////////////////////////////////////////
392 \brief
393 Copy constructor - Creates a new string with the same value as \a str
395 \param str
396 String object used to initialise the newly created string
398 \return
399 Nothing
401 String(const String& str)
403 init();
404 assign(str);
409 \brief
410 Constructs a new string initialised with code points from another String object.
412 \param str
413 String object used to initialise the newly created string
415 \param str_idx
416 Starting code-point of \a str to be used when initialising the new String
418 \param str_num
419 Maximum number of code points from \a str that are to be assigned to the new String
421 \return
422 Nothing
424 String(const String& str, size_type str_idx, size_type str_num = npos)
426 init();
427 assign(str, str_idx, str_num);
430 //////////////////////////////////////////////////////////////////////////
431 // Construction via std::string
432 //////////////////////////////////////////////////////////////////////////
434 \brief
435 Constructs a new string and initialises it using the std::string std_str
437 \param std_str
438 The std::string object that is to be used to initialise the new String object.
440 \note
441 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
442 the provided data will occur.
444 \return
445 Nothing
447 \exception std::length_error Thrown if resulting String object would be too big.
449 String(const std::string& std_str)
451 init();
452 assign(std_str);
456 \brief
457 Constructs a new string initialised with characters from the given std::string object.
459 \param std_str
460 std::string object used to initialise the newly created string
462 \param str_idx
463 Starting character of \a std_str to be used when initialising the new String
465 \note
466 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
467 the provided data will occur.
469 \param str_num
470 Maximum number of characters from \a std_str that are to be assigned to the new String
472 \return
473 Nothing
475 \exception std::length_error Thrown if resulting String object would be too big.
477 String(const std::string& std_str, size_type str_idx, size_type str_num = npos)
479 init();
480 assign(std_str, str_idx, str_num);
484 //////////////////////////////////////////////////////////////////////////
485 // Construction via UTF-8 stream (for straight ASCII use, only codes 0x00 - 0x7f are valid)
486 //////////////////////////////////////////////////////////////////////////
488 \brief
489 Constructs a new String object and initialise it using the provided utf8 encoded string buffer.
491 \param utf8_str
492 Pointer to a buffer containing a null-terminated Unicode string encoded as utf8 data.
494 \note
495 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
496 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
497 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
498 results.
500 \return
501 Nothing
503 \exception std::length_error Thrown if resulting String object would be too big.
505 String(const utf8* utf8_str)
507 init();
508 assign(utf8_str);
512 \brief
513 Constructs a new String object and initialise it using the provided utf8 encoded string buffer.
515 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
516 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
517 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
518 results.
520 \param utf8_str
521 Pointer to a buffer containing Unicode string data encoded as utf8.
523 \note
524 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
525 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
526 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
527 results.
529 \param chars_len
530 Length of the provided utf8 string in code units (not code-points).
532 \return
533 Nothing
535 \exception std::length_error Thrown if resulting String object would be too big.
537 String(const utf8* utf8_str, size_type chars_len)
539 init();
540 assign(utf8_str, chars_len);
543 //////////////////////////////////////////////////////////////////////////
544 // Construction via code-point (using a UTF-32 code unit)
545 //////////////////////////////////////////////////////////////////////////
547 \brief
548 Constructs a new String that is initialised with the specified code point
550 \param num
551 The number of times \a code_point is to be put into new String object
553 \param code_point
554 The Unicode code point to be used when initialising the String object
556 \return
557 Nothing
559 \exception std::length_error Thrown if resulting String object would be too big.
561 String(size_type num, utf32 code_point)
563 init();
564 assign(num, code_point);
567 //////////////////////////////////////////////////////////////////////////
568 // Construction via iterator
569 //////////////////////////////////////////////////////////////////////////
570 // Create string with characters in the range [beg, end)
572 \brief
573 Construct a new string object and initialise it with code-points from the range [beg, end).
575 \param beg
576 Iterator describing the start of the data to be used when initialising the String object
578 \param end
579 Iterator describing the (exclusive) end of the data to be used when initialising the String object
581 \return
582 Nothing
584 String(const_iterator iter_beg, const_iterator iter_end)
586 init();
587 append(iter_beg, iter_end);
591 //////////////////////////////////////////////////////////////////////////
592 // Construction via c-string
593 //////////////////////////////////////////////////////////////////////////
595 \brief
596 Constructs a new String object and initialise it using the provided c-string.
598 \param c_str
599 Pointer to a c-string.
601 \return
602 Nothing
604 \exception std::length_error Thrown if resulting String object would be too big.
606 String(const char* cstr)
608 init();
609 assign(cstr);
613 \brief
614 Constructs a new String object and initialise it using characters from the provided char array.
616 \param chars
617 char array.
619 \param chars_len
620 Number of chars from the array to be used.
622 \return
623 Nothing
625 \exception std::length_error Thrown if resulting String object would be too big.
627 String(const char* chars, size_type chars_len)
629 init();
630 assign(chars, chars_len);
634 //////////////////////////////////////////////////////////////////////////
635 // Size operations
636 //////////////////////////////////////////////////////////////////////////
638 \brief
639 Returns the size of the String in code points
641 \return
642 Number of code points currently in the String
644 size_type size(void) const
646 return d_cplength;
650 \brief
651 Returns the size of the String in code points
653 \return
654 Number of code points currently in the String
656 size_type length(void) const
658 return d_cplength;
662 \brief
663 Returns true if the String is empty
665 \return
666 true if the String is empty, else false.
668 bool empty(void) const
670 return (d_cplength == 0);
674 \brief
675 Returns the maximum size of a String.
677 Any operation that would result in a String that is larger than this value will throw the std::length_error exception.
679 \return
680 The maximum number of code points that a string can contain
682 static size_type max_size(void)
684 return (((size_type)-1) / sizeof(utf32));
687 //////////////////////////////////////////////////////////////////////////
688 // Capacity Operations
689 //////////////////////////////////////////////////////////////////////////
690 // return the number of code points the string could hold without re-allocation
691 // (due to internal encoding this will always report the figure for worst-case encoding, and could even be < size()!)
693 \brief
694 Return the number of code points that the String could hold before a re-allocation would be required.
696 \return
697 Size of the current reserve buffer. This is the maximum number of code points the String could hold before a buffer
698 re-allocation would be required
700 size_type capacity(void) const
702 return d_reserve - 1;
705 // reserve internal memory for at-least 'num' code-points (characters). if num is 0, request is shrink-to-fit.
707 \brief
708 Specifies the amount of reserve capacity to allocate.
710 \param num
711 The number of code points to allocate space for. If \a num is larger that the current reserve, then a re-allocation will occur. If
712 \a num is smaller than the current reserve (but not 0) the buffer may be shrunk to the larger of the specified number, or the current
713 String size (operation is currently not implemented). If \a num is 0, then the buffer is re-allocated to fit the current String size.
715 \return
716 Nothing
718 \exception std::length_error Thrown if resulting String object would be too big.
720 void reserve(size_type num = 0)
722 if (num == 0)
723 trim();
724 else
725 grow(num);
728 //////////////////////////////////////////////////////////////////////////
729 // Comparisons
730 //////////////////////////////////////////////////////////////////////////
732 \brief
733 Compares this String with the String 'str'.
735 \note
736 This does currently not properly consider Unicode and / or the system locale.
738 \param str
739 The String object that is to compared with this String.
741 \return
742 - 0 if the String objects are equal
743 - <0 if this String is lexicographically smaller than \a str
744 - >0 if this String is lexicographically greater than \a str
746 int compare(const String& str) const
748 return compare(0, d_cplength, str);
752 \brief
753 Compares code points from this String with code points from the String 'str'.
755 \note
756 This does currently not properly consider Unicode and / or the system locale.
758 \param idx
759 Index of the first code point from this String to consider.
761 \param len
762 Maximum number of code points from this String to consider.
764 \param str
765 The String object that is to compared with this String.
767 \param str_idx
768 Index of the first code point from String \a str to consider.
770 \param str_len
771 Maximum number of code points from String \a str to consider
773 \return
774 - 0 if the specified sub-strings are equal
775 - <0 if specified sub-strings are lexicographically smaller than \a str
776 - >0 if specified sub-strings are lexicographically greater than \a str
778 \exception std::out_of_range Thrown if either \a idx or \a str_idx are invalid.
780 int compare(size_type idx, size_type len, const String& str, size_type str_idx = 0, size_type str_len = npos) const
782 if ((d_cplength < idx) || (str.d_cplength < str_idx))
783 throw std::out_of_range("Index is out of range for CEGUI::String");
785 if ((len == npos) || (idx + len > d_cplength))
786 len = d_cplength - idx;
788 if ((str_len == npos) || (str_idx + str_len > str.d_cplength))
789 str_len = str.d_cplength - str_idx;
791 int val = (len == 0) ? 0 : utf32_comp_utf32(&ptr()[idx], &str.ptr()[str_idx], (len < str_len) ? len : str_len);
793 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
798 \brief
799 Compares this String with the std::string 'std_str'.
801 \note
802 This does currently not properly consider Unicode and / or the system locale.
804 \param std_str
805 The std::string object that is to compared with this String.
807 \note
808 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
809 the encountered data is performed.
811 \return
812 - 0 if the string objects are equal
813 - <0 if this string is lexicographically smaller than \a std_str
814 - >0 if this string is lexicographically greater than \a std_str
816 int compare(const std::string& std_str) const
818 return compare(0, d_cplength, std_str);
823 \brief
824 Compares code points from this String with code points from the std::string 'std_str'.
826 \note
827 This does currently not properly consider Unicode and / or the system locale.
829 \param idx
830 Index of the first code point from this String to consider.
832 \param len
833 Maximum number of code points from this String to consider.
835 \param std_str
836 The std::string object that is to compared with this String.
838 \note
839 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
840 the encountered data is performed.
842 \param str_idx
843 Index of the first character from std::string \a std_str to consider.
845 \param str_len
846 Maximum number of characters from std::string \a std_str to consider
848 \return
849 - 0 if the specified sub-strings are equal
850 - <0 if specified sub-strings are lexicographically smaller than \a std_str
851 - >0 if specified sub-strings are lexicographically greater than \a std_str
853 \exception std::out_of_range Thrown if either \a idx or \a str_idx are invalid.
855 int compare(size_type idx, size_type len, const std::string& std_str, size_type str_idx = 0, size_type str_len = npos) const
857 if (d_cplength < idx)
858 throw std::out_of_range("Index is out of range for CEGUI::String");
860 if (std_str.size() < str_idx)
861 throw std::out_of_range("Index is out of range for std::string");
863 if ((len == npos) || (idx + len > d_cplength))
864 len = d_cplength - idx;
866 if ((str_len == npos) || (str_idx + str_len > std_str.size()))
867 str_len = (size_type)std_str.size() - str_idx;
869 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], &std_str.c_str()[str_idx], (len < str_len) ? len : str_len);
871 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_len) ? -1 : (len == str_len) ? 0 : 1;
876 \brief
877 Compares this String with the null-terminated utf8 encoded 'utf8_str'.
879 \note
880 This does currently not properly consider Unicode and / or the system locale.
882 \param utf8_str
883 The buffer containing valid Unicode data encoded as utf8 that is to compared with this String.
885 \note
886 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
887 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
888 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
889 results.
891 \return
892 - 0 if the strings are equal
893 - <0 if this string is lexicographically smaller than \a utf8_str
894 - >0 if this string is lexicographically greater than \a utf8_str
896 int compare(const utf8* utf8_str) const
898 return compare(0, d_cplength, utf8_str, encoded_size(utf8_str));
903 \brief
904 Compares code points from this String with the null-terminated utf8 encoded 'utf8_str'.
906 \note
907 This does currently not properly consider Unicode and / or the system locale.
909 \param idx
910 Index of the first code point from this String to consider.
912 \param len
913 Maximum number of code points from this String to consider.
915 \param utf8_str
916 The buffer containing valid Unicode data encoded as utf8 that is to compared with this String.
918 \note
919 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
920 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
921 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
922 results.
924 \return
925 - 0 if the specified sub-strings are equal
926 - <0 if specified sub-strings are lexicographically smaller than \a utf8_str
927 - >0 if specified sub-strings are lexicographically greater than \a utf8_str
929 \exception std::out_of_range Thrown if \a idx is invalid.
931 int compare(size_type idx, size_type len, const utf8* utf8_str) const
933 return compare(idx, len, utf8_str, encoded_size(utf8_str));
937 \brief
938 Compares code points from this String with the utf8 encoded data in buffer 'utf8_str'.
940 \note
941 This does currently not properly consider Unicode and / or the system locale.
943 \param idx
944 Index of the first code point from this String to consider.
946 \param len
947 Maximum number of code points from this String to consider.
949 \param utf8_str
950 The buffer containing valid Unicode data encoded as utf8 that is to compared with this String.
952 \note
953 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
954 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
955 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
956 results.
958 \param str_cplen
959 The number of encoded code points in the buffer \a utf8_str (this is not the same as the number of code units).
961 \return
962 - 0 if the specified sub-strings are equal
963 - <0 if specified sub-strings are lexicographically smaller than \a utf8_str
964 - >0 if specified sub-strings are lexicographically greater than \a utf8_str
966 \exception std::out_of_range Thrown if \a idx is invalid.
967 \exception std::length_error Thrown if \a str_cplen is set to npos.
969 int compare(size_type idx, size_type len, const utf8* utf8_str, size_type str_cplen) const
971 if (d_cplength < idx)
972 throw std::out_of_range("Index is out of range for CEGUI::String");
974 if (str_cplen == npos)
975 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
977 if ((len == npos) || (idx + len > d_cplength))
978 len = d_cplength - idx;
980 int val = (len == 0) ? 0 : utf32_comp_utf8(&ptr()[idx], utf8_str, (len < str_cplen) ? len : str_cplen);
982 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < str_cplen) ? -1 : (len == str_cplen) ? 0 : 1;
987 \brief
988 Compares this String with the given c-string.
990 \note
991 This does currently not properly consider Unicode and / or the system locale.
993 \param c_str
994 The c-string that is to compared with this String.
996 \return
997 - 0 if the strings are equal
998 - <0 if this string is lexicographically smaller than \a c_str
999 - >0 if this string is lexicographically greater than \a c_str
1001 int compare(const char* cstr) const
1003 return compare(0, d_cplength, cstr, strlen(cstr));
1008 \brief
1009 Compares code points from this String with the given c-string.
1011 \note
1012 This does currently not properly consider Unicode and / or the system locale.
1014 \param idx
1015 Index of the first code point from this String to consider.
1017 \param len
1018 Maximum number of code points from this String to consider.
1020 \param c_str
1021 The c-string that is to compared with this String.
1023 \return
1024 - 0 if the specified sub-strings are equal
1025 - <0 if specified sub-strings are lexicographically smaller than \a c_str
1026 - >0 if specified sub-strings are lexicographically greater than \a c_str
1028 \exception std::out_of_range Thrown if \a idx is invalid.
1030 int compare(size_type idx, size_type len, const char* cstr) const
1032 return compare(idx, len, cstr, strlen(cstr));
1037 \brief
1038 Compares code points from this String with chars in the given char array.
1040 \note
1041 This does currently not properly consider Unicode and / or the system locale.
1043 \param idx
1044 Index of the first code point from this String to consider.
1046 \param len
1047 Maximum number of code points from this String to consider.
1049 \param chars
1050 The array containing the chars that are to compared with this String.
1052 \param chars_len
1053 The number of chars in the array.
1055 \return
1056 - 0 if the specified sub-strings are equal
1057 - <0 if specified sub-strings are lexicographically smaller than \a chars
1058 - >0 if specified sub-strings are lexicographically greater than \a chars
1060 \exception std::out_of_range Thrown if \a idx is invalid.
1061 \exception std::length_error Thrown if \a chars_len is set to npos.
1063 int compare(size_type idx, size_type len, const char* chars, size_type chars_len) const
1065 if (d_cplength < idx)
1066 throw std::out_of_range("Index is out of range for CEGUI::String");
1068 if (chars_len == npos)
1069 throw std::length_error("Length for char array can not be 'npos'");
1071 if ((len == npos) || (idx + len > d_cplength))
1072 len = d_cplength - idx;
1074 int val = (len == 0) ? 0 : utf32_comp_char(&ptr()[idx], chars, (len < chars_len) ? len : chars_len);
1076 return (val != 0) ? ((val < 0) ? -1 : 1) : (len < chars_len) ? -1 : (len == chars_len) ? 0 : 1;
1080 //////////////////////////////////////////////////////////////////////////
1081 // Character access
1082 //////////////////////////////////////////////////////////////////////////
1084 \brief
1085 Returns the code point at the given index.
1087 \param idx
1088 Zero based index of the code point to be returned.
1090 \note
1091 - For constant strings length()/size() provide a valid index and will access the default utf32 value.
1092 - For non-constant strings length()/size() is an invalid index, and acceesing (especially writing) this index could cause string corruption.
1094 \return
1095 The utf32 code point at the given index within the String.
1097 reference operator[](size_type idx)
1099 return (ptr()[idx]);
1103 \brief
1104 Returns the code point at the given index.
1106 \param idx
1107 Zero based index of the code point to be returned.
1109 \note
1110 - For constant strings length()/size() provide a valid index and will access the default utf32 value.
1111 - For non-constant strings length()/size() is an invalid index, and acceesing (especially writing) this index could cause string corruption.
1113 \return
1114 The utf32 code point at the given index within the String.
1116 value_type operator[](size_type idx) const
1118 return ptr()[idx];
1122 \brief
1123 Returns the code point at the given index.
1125 \param idx
1126 Zero based index of the code point to be returned.
1128 \return
1129 The utf32 code point at the given index within the String.
1131 \exception std::out_of_range Thrown if \a idx is >= length().
1133 reference at(size_type idx)
1135 if (d_cplength <= idx)
1136 throw std::out_of_range("Index is out of range for CEGUI::String");
1138 return ptr()[idx];
1142 \brief
1143 Returns the code point at the given index.
1145 \param idx
1146 Zero based index of the code point to be returned.
1148 \return
1149 The utf32 code point at the given index within the String.
1151 \exception std::out_of_range Thrown if \a idx is >= length().
1153 const_reference at(size_type idx) const
1155 if (d_cplength <= idx)
1156 throw std::out_of_range("Index is out of range for CEGUI::String");
1158 return ptr()[idx];
1162 //////////////////////////////////////////////////////////////////////////
1163 // C-Strings and arrays
1164 //////////////////////////////////////////////////////////////////////////
1166 \brief
1167 Returns contents of the String as a null terminated string of utf8 encoded data.
1169 \return
1170 Pointer to a char buffer containing the contents of the String encoded as null-terminated utf8 data.
1172 \note
1173 The buffer returned from this function is owned by the String object.
1175 \note
1176 Any function that modifies the String data will invalidate the buffer returned by this call.
1178 const char* c_str(void) const
1180 return (const char*)build_utf8_buff();
1184 \brief
1185 Returns contents of the String as utf8 encoded data.
1187 \return
1188 Pointer to a buffer containing the contents of the String encoded utf8 data.
1190 \note
1191 The buffer returned from this function is owned by the String object.
1193 \note
1194 Any function that modifies the String data will invalidate the buffer returned by this call.
1196 const utf8* data(void) const
1198 return build_utf8_buff();
1202 \brief
1203 Returns a pointer to the buffer in use.
1205 utf32* ptr(void)
1207 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1211 \brief
1212 Returns a pointer to the buffer in use. (const version)
1214 const utf32* ptr(void) const
1216 return (d_reserve > STR_QUICKBUFF_SIZE) ? d_buffer : d_quickbuff;
1219 // copy, at most, 'len' code-points of the string, begining with code-point 'idx', into the array 'buf' as valid utf8 encoded data
1220 // return number of utf8 code units placed into the buffer
1222 \brief
1223 Copies an area of the String into the provided buffer as encoded utf8 data.
1225 \param buf
1226 Pointer to a buffer that is to receive the encoded data (this must be big enough to hold the encoded data)
1228 \param len
1229 Maximum number of code points from the String that should be encoded into the buffer
1231 \param idx
1232 Index of the first code point to be encoded into the buffer
1234 \return
1235 The number of utf8 encoded code units transferred to the buffer.
1237 \note A code unit does not equal a code point. A utf32 code point, when encoded as utf8, can occupy between 1 and 4 code units.
1239 \exception std::out_of_range Thrown if \a idx was invalid for this String.
1241 size_type copy(utf8* buf, size_type len = npos, size_type idx = 0) const
1243 if (d_cplength < idx)
1244 throw std::out_of_range("Index is out of range for CEGUI::String");
1246 if (len == npos)
1247 len = d_cplength;
1249 return encode(&ptr()[idx], buf, npos, len);
1252 //////////////////////////////////////////////////////////////////////////
1253 // UTF8 Encoding length information
1254 //////////////////////////////////////////////////////////////////////////
1255 // return the number of bytes required to hold 'num' code-points, starting at code-point 'idx', of the the string when encoded as utf8 data.
1257 \brief
1258 Return the number of utf8 code units required to hold an area of the String when encoded as utf8 data
1260 \param num
1261 Maximum number of code points to consider when calculating utf8 encoded size.
1263 \param idx
1264 Index of the first code point to consider when calculating the utf8 encoded size
1266 \return
1267 The number of utf8 code units (bytes) required to hold the specified sub-string when encoded as utf8 data.
1269 \exception std::out_of_range Thrown if \a idx was invalid for this String.
1271 size_type utf8_stream_len(size_type num = npos, size_type idx = 0) const
1273 using namespace std;
1275 if (d_cplength < idx)
1276 throw out_of_range("Index was out of range for CEGUI::String object");
1278 size_type maxlen = d_cplength - idx;
1280 return encoded_size(&ptr()[idx], ceguimin(num, maxlen));
1283 //////////////////////////////////////////////////////////////////////////
1284 // Assignment Functions
1285 //////////////////////////////////////////////////////////////////////////
1287 \brief
1288 Assign the value of String \a str to this String
1290 \param str
1291 String object containing the string value to be assigned.
1293 \return
1294 This String after the assignment has happened
1296 String& operator=(const String& str)
1298 return assign(str);
1302 \brief
1303 Assign a sub-string of String \a str to this String
1305 \param str
1306 String object containing the string data to be assigned.
1308 \param str_idx
1309 Index of the first code point in \a str that is to be assigned
1311 \param str_num
1312 Maximum number of code points from \a str that are be be assigned
1314 \return
1315 This String after the assignment has happened
1317 \exception std::out_of_range Thrown if str_idx is invalid for \a str
1319 String& assign(const String& str, size_type str_idx = 0, size_type str_num = npos)
1321 if (str.d_cplength < str_idx)
1322 throw std::out_of_range("Index was out of range for CEGUI::String object");
1324 if (str_num == npos)
1325 str_num = str.d_cplength - str_idx;
1327 grow(str_num);
1328 setlen(str_num);
1329 memcpy(ptr(), &str.ptr()[str_idx], str_num * sizeof(utf32));
1331 return *this;
1335 \brief
1336 Assign the value of std::string \a std_str to this String
1338 \note
1339 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
1340 the provided data will occur.
1342 \param std_str
1343 std::string object containing the string value to be assigned.
1345 \return
1346 This String after the assignment has happened
1348 \exception std::length_error Thrown if the resulting String would have been too large.
1350 String& operator=(const std::string& std_str)
1352 return assign(std_str);
1356 \brief
1357 Assign a sub-string of std::string \a std_str to this String
1359 \note
1360 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
1361 the provided data will occur.
1363 \param std_str
1364 std::string object containing the string value to be assigned.
1366 \param str_idx
1367 Index of the first character of \a std_str to be assigned
1369 \param str_num
1370 Maximum number of characters from \a std_str to be assigned
1372 \return
1373 This String after the assignment has happened
1375 \exception std::out_of_range Thrown if \a str_idx is invalid for \a std_str
1376 \exception std::length_error Thrown if the resulting String would have been too large.
1378 String& assign(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1380 if (std_str.size() < str_idx)
1381 throw std::out_of_range("Index was out of range for std::string object");
1383 if (str_num == npos)
1384 str_num = (size_type)std_str.size() - str_idx;
1386 grow(str_num);
1387 setlen(str_num);
1389 while(str_num--)
1391 ((*this)[str_num]) = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num + str_idx]));
1394 return *this;
1398 \brief
1399 Assign to this String the string value represented by the given null-terminated utf8 encoded data
1401 \note
1402 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1403 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1404 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1405 results.
1407 \param utf8_str
1408 Buffer containing valid null-terminated utf8 encoded data
1410 \return
1411 This String after the assignment has happened
1413 \exception std::length_error Thrown if the resulting String would have been too large.
1415 String& operator=(const utf8* utf8_str)
1417 return assign(utf8_str, utf_length(utf8_str));
1421 \brief
1422 Assign to this String the string value represented by the given null-terminated utf8 encoded data
1424 \note
1425 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1426 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1427 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1428 results.
1430 \param utf8_str
1431 Buffer containing valid null-terminated utf8 encoded data
1433 \return
1434 This String after the assignment has happened
1436 \exception std::length_error Thrown if the resulting String would have been too large.
1438 String& assign(const utf8* utf8_str)
1440 return assign(utf8_str, utf_length(utf8_str));
1444 \brief
1445 Assign to this String the string value represented by the given utf8 encoded data
1447 \note
1448 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1449 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1450 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1451 results.
1453 \param utf8_str
1454 Buffer containing valid utf8 encoded data
1456 \param str_num
1457 Number of code units (not code points) in the buffer pointed to by \a utf8_str
1459 \return
1460 This String after the assignment has happened
1462 \exception std::length_error Thrown if the resulting String would have been too large, or if str_num is 'npos'.
1464 String& assign(const utf8* utf8_str, size_type str_num)
1466 if (str_num == npos)
1467 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
1469 size_type enc_sze = encoded_size(utf8_str, str_num);
1471 grow(enc_sze);
1472 encode(utf8_str, ptr(), d_reserve, str_num);
1473 setlen(enc_sze);
1474 return *this;
1478 \brief
1479 Assigns the specified utf32 code point to this String. Result is always a String 1 code point in length.
1481 \param code_point
1482 Valid utf32 Unicode code point to be assigned to the string
1484 \return
1485 This String after assignment
1487 String& operator=(utf32 code_point)
1489 return assign(1, code_point);
1493 \brief
1494 Assigns the specified code point repeatedly to the String
1496 \param num
1497 The number of times to assign the code point
1499 \param code_point
1500 Valid utf32 Unicode code point to be assigned to the string
1502 \return
1503 This String after assignment.
1505 \exception std::length_error Thrown if \a num was 'npos'
1507 String& assign(size_type num, utf32 code_point)
1509 if (num == npos)
1510 throw std::length_error("Code point count can not be 'npos'");
1512 grow(num);
1513 setlen(num);
1514 utf32* p = ptr();
1516 while(num--)
1517 *p++ = code_point;
1519 return *this;
1524 \brief
1525 Assign to this String the given C-string.
1527 \param c_str
1528 Pointer to a valid C style string.
1530 \return
1531 This String after the assignment has happened
1533 \exception std::length_error Thrown if the resulting String would have been too large.
1535 String& operator=(const char* cstr)
1537 return assign(cstr, strlen(cstr));
1542 \brief
1543 Assign to this String the given C-string.
1545 \param c_str
1546 Pointer to a valid C style string.
1548 \return
1549 This String after the assignment has happened
1551 \exception std::length_error Thrown if the resulting String would have been too large.
1553 String& assign(const char* cstr)
1555 return assign(cstr, strlen(cstr));
1560 \brief
1561 Assign to this String a number of chars from a char array.
1563 \param chars
1564 char array.
1566 \param chars_len
1567 Number of chars to be assigned.
1569 \return
1570 This String after the assignment has happened
1572 \exception std::length_error Thrown if the resulting String would have been too large.
1574 String& assign(const char* chars, size_type chars_len)
1576 grow(chars_len);
1577 utf32* pt = ptr();
1579 for (size_type i = 0; i < chars_len; ++i)
1581 *pt++ = static_cast<utf32>(static_cast<unsigned char>(*chars++));
1584 setlen(chars_len);
1585 return *this;
1590 \brief
1591 Swaps the value of this String with the given String \a str
1593 \param str
1594 String object whos value is to be swapped with this String.
1596 \return
1597 Nothing
1599 void swap(String& str)
1601 size_type temp_len = d_cplength;
1602 d_cplength = str.d_cplength;
1603 str.d_cplength = temp_len;
1605 size_type temp_res = d_reserve;
1606 d_reserve = str.d_reserve;
1607 str.d_reserve = temp_res;
1609 utf32* temp_buf = d_buffer;
1610 d_buffer = str.d_buffer;
1611 str.d_buffer = temp_buf;
1613 // see if we need to swap 'quick buffer' data
1614 if (temp_res <= STR_QUICKBUFF_SIZE)
1616 utf32 temp_qbf[STR_QUICKBUFF_SIZE];
1618 memcpy(temp_qbf, d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
1619 memcpy(d_quickbuff, str.d_quickbuff, STR_QUICKBUFF_SIZE * sizeof(utf32));
1620 memcpy(str.d_quickbuff, temp_qbf, STR_QUICKBUFF_SIZE * sizeof(utf32));
1625 //////////////////////////////////////////////////////////////////////////
1626 // Appending Functions
1627 //////////////////////////////////////////////////////////////////////////
1629 \brief
1630 Appends the String \a str
1632 \param str
1633 String object that is to be appended
1635 \return
1636 This String after the append operation
1638 \exception std::length_error Thrown if resulting String would be too large.
1640 String& operator+=(const String& str)
1642 return append(str);
1646 \brief
1647 Appends a sub-string of the String \a str
1649 \param str
1650 String object containing data to be appended
1652 \param str_idx
1653 Index of the first code point to be appended
1655 \param str_num
1656 Maximum number of code points to be appended
1658 \return
1659 This String after the append operation
1661 \exception std::out_of_range Thrown if \a str_idx is invalid for \a str.
1662 \exception std::length_error Thrown if resulting String would be too large.
1664 String& append(const String& str, size_type str_idx = 0, size_type str_num = npos)
1666 if (str.d_cplength < str_idx)
1667 throw std::out_of_range("Index is out of range for CEGUI::String");
1669 if (str_num == npos)
1670 str_num = str.d_cplength - str_idx;
1672 grow(d_cplength + str_num);
1673 memcpy(&ptr()[d_cplength], &str.ptr()[str_idx], str_num * sizeof(utf32));
1674 setlen(d_cplength + str_num);
1675 return *this;
1680 \brief
1681 Appends the std::string \a std_str
1683 \param std_str
1684 std::string object that is to be appended
1686 \note
1687 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
1688 the provided data will occur.
1690 \return
1691 This String after the append operation
1693 \exception std::length_error Thrown if resulting String would be too large.
1695 String& operator+=(const std::string& std_str)
1697 return append(std_str);
1701 \brief
1702 Appends a sub-string of the std::string \a std_str
1704 \param std_str
1705 std::string object containing data to be appended
1707 \note
1708 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
1709 the provided data will occur.
1711 \param str_idx
1712 Index of the first character to be appended
1714 \param str_num
1715 Maximum number of characters to be appended
1717 \return
1718 This String after the append operation
1720 \exception std::out_of_range Thrown if \a str_idx is invalid for \a std_str.
1721 \exception std::length_error Thrown if resulting String would be too large.
1723 String& append(const std::string& std_str, size_type str_idx = 0, size_type str_num = npos)
1725 if (std_str.size() < str_idx)
1726 throw std::out_of_range("Index is out of range for std::string");
1728 if (str_num == npos)
1729 str_num = (size_type)std_str.size() - str_idx;
1731 size_type newsze = d_cplength + str_num;
1733 grow(newsze);
1734 utf32* pt = &ptr()[newsze-1];
1736 while(str_num--)
1737 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_num]));
1739 setlen(newsze);
1740 return *this;
1745 \brief
1746 Appends to the String the null-terminated utf8 encoded data in the buffer utf8_str.
1748 \param utf8_str
1749 buffer holding the null-terminated utf8 encoded data that is to be appended
1751 \note
1752 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1753 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1754 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1755 results.
1757 \return
1758 This String after the append operation
1760 \exception std::length_error Thrown if resulting String would be too large.
1762 String& operator+=(const utf8* utf8_str)
1764 return append(utf8_str, utf_length(utf8_str));
1768 \brief
1769 Appends to the String the null-terminated utf8 encoded data in the buffer utf8_str.
1771 \param utf8_str
1772 Buffer holding the null-terminated utf8 encoded data that is to be appended
1774 \note
1775 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1776 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1777 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1778 results.
1780 \return
1781 This String after the append operation
1783 \exception std::length_error Thrown if resulting String would be too large.
1785 String& append(const utf8* utf8_str)
1787 return append(utf8_str, utf_length(utf8_str));
1792 \brief
1793 Appends to the String the utf8 encoded data in the buffer utf8_str.
1795 \param utf8_str
1796 Buffer holding the utf8 encoded data that is to be appended
1798 \note
1799 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
1800 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
1801 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
1802 results.
1804 \param len
1805 Number of code units (not code points) in the buffer to be appended
1807 \return
1808 This String after the append operation
1810 \exception std::length_error Thrown if resulting String would be too large, or if \a len was 'npos'
1812 String& append(const utf8* utf8_str, size_type len)
1814 if (len == npos)
1815 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
1817 size_type encsz = encoded_size(utf8_str, len);
1818 size_type newsz = d_cplength + encsz;
1820 grow(newsz);
1821 encode(utf8_str, &ptr()[d_cplength], encsz, len);
1822 setlen(newsz);
1824 return *this;
1829 \brief
1830 Appends a single code point to the string
1832 \param code_point
1833 utf32 Unicode code point that is to be appended
1835 \return
1836 This String after the append operation
1838 \exception std::length_error Thrown if resulting String would be too long.
1840 String& operator+=(utf32 code_point)
1842 return append(1, code_point);
1846 \brief
1847 Appends a single code point multiple times to the string
1849 \param num
1850 Number of copies of the code point to be appended
1852 \param code_point
1853 utf32 Unicode code point that is to be appended
1855 \return
1856 This String after the append operation
1858 \exception std::length_error Thrown if resulting String would be too long, or if \a num was 'npos'.
1860 String& append(size_type num, utf32 code_point)
1862 if (num == npos)
1863 throw std::length_error("Code point count can not be 'npos'");
1865 size_type newsz = d_cplength + num;
1866 grow(newsz);
1868 utf32* p = &ptr()[d_cplength];
1870 while(num--)
1871 *p++ = code_point;
1873 setlen(newsz);
1875 return *this;
1879 \brief
1880 Appends a single code point to the string
1882 \param code_point
1883 utf32 Unicode code point that is to be appended
1885 \return
1886 Nothing
1888 \exception std::length_error Thrown if resulting String would be too long.
1890 void push_back(utf32 code_point)
1892 append(1, code_point);
1896 \brief
1897 Appends the code points in the reange [beg, end)
1899 \param beg
1900 Iterator describing the start of the range to be appended
1902 \param end
1903 Iterator describing the (exclusive) end of the range to be appended.
1905 \return
1906 This String after the append operation
1908 \exception std::length_error Thrown if the resulting string would be too large.
1910 String& append(const_iterator iter_beg, const_iterator iter_end)
1912 return replace(end(), end(), iter_beg, iter_end);
1917 \brief
1918 Appends to the String the given c-string.
1920 \param c_str
1921 c-string that is to be appended.
1923 \return
1924 This String after the append operation
1926 \exception std::length_error Thrown if resulting String would be too large.
1928 String& operator+=(const char* cstr)
1930 return append(cstr, strlen(cstr));
1935 \brief
1936 Appends to the String the given c-string.
1938 \param c_str
1939 c-string that is to be appended.
1941 \return
1942 This String after the append operation
1944 \exception std::length_error Thrown if resulting String would be too large.
1946 String& append(const char* cstr)
1948 return append(cstr, strlen(cstr));
1953 \brief
1954 Appends to the String chars from the given char array.
1956 \param chars
1957 char array holding the chars that are to be appended
1959 \param chars_len
1960 Number of chars to be appended
1962 \return
1963 This String after the append operation
1965 \exception std::length_error Thrown if resulting String would be too large, or if \a chars_len was 'npos'
1967 String& append(const char* chars, size_type chars_len)
1969 if (chars_len == npos)
1970 throw std::length_error("Length for char array can not be 'npos'");
1972 size_type newsz = d_cplength + chars_len;
1974 grow(newsz);
1976 utf32* pt = &ptr()[newsz-1];
1978 while(chars_len--)
1979 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
1981 setlen(newsz);
1983 return *this;
1987 //////////////////////////////////////////////////////////////////////////
1988 // Insertion Functions
1989 //////////////////////////////////////////////////////////////////////////
1991 \brief
1992 Inserts the given String object at the specified position.
1994 \param idx
1995 Index where the string is to be inserted.
1997 \param str
1998 String object that is to be inserted.
2000 \return
2001 This String after the insert.
2003 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2004 \exception std::length_error Thrown if resulting String would be too large.
2006 String& insert(size_type idx, const String& str)
2008 return insert(idx, str, 0, npos);
2012 \brief
2013 Inserts a sub-string of the given String object at the specified position.
2015 \param idx
2016 Index where the string is to be inserted.
2018 \param str
2019 String object containing data to be inserted.
2021 \param str_idx
2022 Index of the first code point from \a str to be inserted.
2024 \param str_num
2025 Maximum number of code points from \a str to be inserted.
2027 \return
2028 This String after the insert.
2030 \exception std::out_of_range Thrown if \a idx or \a str_idx are out of range.
2031 \exception std::length_error Thrown if resulting String would be too large.
2033 String& insert(size_type idx, const String& str, size_type str_idx, size_type str_num)
2035 if ((d_cplength < idx) || (str.d_cplength < str_idx))
2036 throw std::out_of_range("Index is out of range for CEGUI::String");
2038 if (str_num == npos)
2039 str_num = str.d_cplength - str_idx;
2041 size_type newsz = d_cplength + str_num;
2042 grow(newsz);
2043 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2044 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2045 setlen(newsz);
2047 return *this;
2051 \brief
2052 Inserts the given std::string object at the specified position.
2054 \param idx
2055 Index where the std::string is to be inserted.
2057 \param std_str
2058 std::string object that is to be inserted.
2060 \note
2061 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
2062 the provided data will occur.
2064 \return
2065 This String after the insert.
2067 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2068 \exception std::length_error Thrown if resulting String would be too large.
2070 String& insert(size_type idx, const std::string& std_str)
2072 return insert(idx, std_str, 0, npos);
2076 \brief
2077 Inserts a sub-string of the given std::string object at the specified position.
2079 \param idx
2080 Index where the string is to be inserted.
2082 \param std_str
2083 std::string object containing data to be inserted.
2085 \note
2086 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
2087 the provided data will occur.
2089 \param str_idx
2090 Index of the first character from \a std_str to be inserted.
2092 \param str_num
2093 Maximum number of characters from \a str to be inserted.
2095 \return
2096 This String after the insert.
2098 \exception std::out_of_range Thrown if \a idx or \a str_idx are out of range.
2099 \exception std::length_error Thrown if resulting String would be too large.
2101 String& insert(size_type idx, const std::string& std_str, size_type str_idx, size_type str_num)
2103 if (d_cplength < idx)
2104 throw std::out_of_range("Index is out of range for CEGUI::String");
2106 if (std_str.size() < str_idx)
2107 throw std::out_of_range("Index is out of range for std::string");
2109 if (str_num == npos)
2110 str_num = (size_type)std_str.size() - str_idx;
2112 size_type newsz = d_cplength + str_num;
2113 grow(newsz);
2115 memmove(&ptr()[idx + str_num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2117 utf32* pt = &ptr()[idx + str_num - 1];
2119 while(str_num--)
2120 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2122 setlen(newsz);
2124 return *this;
2128 \brief
2129 Inserts the given null-terminated utf8 encoded data at the specified position.
2131 \param idx
2132 Index where the data is to be inserted.
2134 \param utf8_str
2135 Buffer containing the null-terminated utf8 encoded data that is to be inserted.
2137 \note
2138 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2139 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2140 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2141 results.
2143 \return
2144 This String after the insert.
2146 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2147 \exception std::length_error Thrown if resulting String would be too large.
2149 String& insert(size_type idx, const utf8* utf8_str)
2151 return insert(idx, utf8_str, utf_length(utf8_str));
2155 \brief
2156 Inserts the given utf8 encoded data at the specified position.
2158 \param idx
2159 Index where the data is to be inserted.
2161 \param utf8_str
2162 Buffer containing the utf8 encoded data that is to be inserted.
2164 \note
2165 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2166 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2167 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2168 results.
2170 \param len
2171 Length of the data to be inserted in uf8 code units (not code points)
2173 \return
2174 This String after the insert.
2176 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2177 \exception std::length_error Thrown if resulting String would be too large, or if \a len is 'npos'
2179 String& insert(size_type idx, const utf8* utf8_str, size_type len)
2181 if (d_cplength < idx)
2182 throw std::out_of_range("Index is out of range for CEGUI::String");
2184 if (len == npos)
2185 throw std::length_error("Length of utf8 encoded string can not be 'npos'");
2187 size_type encsz = encoded_size(utf8_str, len);
2188 size_type newsz = d_cplength + encsz;
2190 grow(newsz);
2191 memmove(&ptr()[idx + encsz], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2192 encode(utf8_str, &ptr()[idx], encsz, len);
2193 setlen(newsz);
2195 return *this;
2199 \brief
2200 Inserts a code point multiple times into the String
2202 \param idx
2203 Index where the code point(s) are to be inserted
2205 \param num
2206 The number of times to insert the code point
2208 \param code_point
2209 The utf32 code point that is to be inserted
2211 \return
2212 This String after the insertion.
2214 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2215 \exception std::length_error Thrown if resulting String would be too large, or if \a num is 'npos'
2217 String& insert(size_type idx, size_type num, utf32 code_point)
2219 if (d_cplength < idx)
2220 throw std::out_of_range("Index is out of range for CEGUI::String");
2222 if (num == npos)
2223 throw std::length_error("Code point count can not be 'npos'");
2225 size_type newsz = d_cplength + num;
2226 grow(newsz);
2228 memmove(&ptr()[idx + num], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2230 utf32* pt = &ptr()[idx + num - 1];
2232 while(num--)
2233 *pt-- = code_point;
2235 setlen(newsz);
2237 return *this;
2241 \brief
2242 Inserts a code point multiple times into the String
2244 \param pos
2245 Iterator describing the position where the code point(s) are to be inserted
2247 \param num
2248 The number of times to insert the code point
2250 \param code_point
2251 The utf32 code point that is to be inserted
2253 \return
2254 This String after the insertion.
2256 \exception std::length_error Thrown if resulting String would be too large, or if \a num is 'npos'
2258 void insert(iterator pos, size_type num, utf32 code_point)
2260 insert(safe_iter_dif(pos, begin()), num, code_point);
2264 \brief
2265 Inserts a single code point into the String
2267 \param pos
2268 Iterator describing the position where the code point is to be inserted
2270 \param code_point
2271 The utf32 code point that is to be inserted
2273 \return
2274 This String after the insertion.
2276 \exception std::length_error Thrown if resulting String would be too large.
2278 iterator insert(iterator pos, utf32 code_point)
2280 insert(pos, 1, code_point);
2281 return pos;
2285 \brief
2286 Inserts code points specified by the range [beg, end).
2288 \param pos
2289 Iterator describing the position where the data is to be inserted
2291 \param beg
2292 Iterator describing the begining of the range to be inserted
2294 \param end
2295 Iterator describing the (exclusive) end of the range to be inserted.
2297 \return
2298 Nothing.
2300 \exception std::length_error Thrown if resulting String would be too large.
2302 void insert(iterator iter_pos, const_iterator iter_beg, const_iterator iter_end)
2304 replace(iter_pos, iter_pos, iter_beg, iter_end);
2309 \brief
2310 Inserts the given c-string at the specified position.
2312 \param idx
2313 Index where the c-string is to be inserted.
2315 \param c_str
2316 c-string that is to be inserted.
2318 \return
2319 This String after the insert.
2321 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2322 \exception std::length_error Thrown if resulting String would be too large.
2324 String& insert(size_type idx, const char* cstr)
2326 return insert(idx, cstr, strlen(cstr));
2331 \brief
2332 Inserts chars from the given char array at the specified position.
2334 \param idx
2335 Index where the data is to be inserted.
2337 \param chars
2338 char array containing the chars that are to be inserted.
2340 \param chars_len
2341 Length of the char array to be inserted.
2343 \return
2344 This String after the insert.
2346 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2347 \exception std::length_error Thrown if resulting String would be too large, or if \a chars_len is 'npos'
2349 String& insert(size_type idx, const char* chars, size_type chars_len)
2351 if (d_cplength < idx)
2352 throw std::out_of_range("Index is out of range for CEGUI::String");
2354 if (chars_len == npos)
2355 throw std::length_error("Length of char array can not be 'npos'");
2357 size_type newsz = d_cplength + chars_len;
2359 grow(newsz);
2360 memmove(&ptr()[idx + chars_len], &ptr()[idx], (d_cplength - idx) * sizeof(utf32));
2362 utf32* pt = &ptr()[idx + chars_len - 1];
2364 while(chars_len--)
2365 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
2367 setlen(newsz);
2369 return *this;
2373 //////////////////////////////////////////////////////////////////////////
2374 // Erasing characters
2375 //////////////////////////////////////////////////////////////////////////
2377 \brief
2378 Removes all data from the String
2380 \return
2381 Nothing
2383 void clear(void)
2385 setlen(0);
2386 trim();
2390 \brief
2391 Removes all data from the String
2393 \return
2394 The empty String (*this)
2396 String& erase(void)
2398 clear();
2399 return *this;
2403 \brief
2404 Erase a single code point from the string
2406 \param idx
2407 The index of the code point to be removed.
2409 \return
2410 This String after the erase operation
2412 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2414 String& erase(size_type idx)
2416 return erase(idx, 1);
2420 \brief
2421 Erase a range of code points
2423 \param idx
2424 Index of the first code point to be removed.
2426 \param len
2427 Maximum number of code points to be removed.
2429 \return
2430 This String after the erase operation.
2432 \exception std::out_of_range Thrown if \a idx is invalid for this String.
2434 String& erase(size_type idx, size_type len = npos)
2436 if (d_cplength < idx)
2437 throw std::out_of_range("Index is out of range foe CEGUI::String");
2439 if (len == npos)
2440 len = d_cplength - idx;
2442 size_type newsz = d_cplength - len;
2444 memmove(&ptr()[idx], &ptr()[idx + len], (d_cplength - idx - len) * sizeof(utf32));
2445 setlen(newsz);
2446 return *this;
2450 \brief
2451 Erase the code point described by the given iterator
2453 \param pos
2454 Iterator describing the code point to be erased
2456 \return
2457 This String after the erase operation.
2459 String& erase(iterator pos)
2461 return erase(safe_iter_dif(pos, begin()), 1);
2465 \brief
2466 Erase a range of code points described by the iterators [beg, end).
2468 \param beg
2469 Iterator describing the postion of the beginning of the range to erase
2471 \param end
2472 Iterator describing the postion of the (exclusive) end of the range to erase
2474 \return
2475 This String after the erase operation.
2477 String& erase(iterator iter_beg, iterator iter_end)
2479 return erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
2482 //////////////////////////////////////////////////////////////////////////
2483 // Resizing
2484 //////////////////////////////////////////////////////////////////////////
2486 \brief
2487 Resizes the String either by inserting default utf32 code points to make it larger, or by truncating to make it smaller
2489 \param num
2490 The length, in code points, that the String is to be made.
2492 \return
2493 Nothing.
2495 \exception std::length_error Thrown if the String would be too large.
2497 void resize(size_type num)
2499 resize(num, utf32());
2503 \brief
2504 Resizes the String either by inserting the given utf32 code point to make it larger, or by truncating to make it smaller
2506 \param num
2507 The length, in code points, that the String is to be made.
2509 \param code_point
2510 The utf32 code point that should be used when majing the String larger
2512 \return
2513 Nothing.
2515 \exception std::length_error Thrown if the String would be too large.
2517 void resize(size_type num, utf32 code_point)
2519 if (num < d_cplength)
2521 setlen(num);
2523 else
2525 append(num - d_cplength, code_point);
2530 //////////////////////////////////////////////////////////////////////////
2531 // Replacing Characters
2532 //////////////////////////////////////////////////////////////////////////
2534 \brief
2535 Replace code points in the String with the specified String object
2537 \param idx
2538 Index of the first code point to be replaced
2540 \param len
2541 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
2543 \param str
2544 The String object that is to replace the specified code points
2546 \return
2547 This String after the replace operation
2549 \exception std::out_of_range Thrown if \a idx is invalid for this String
2550 \exception std::length_error Thrown if the resulting String would be too large.
2552 String& replace(size_type idx, size_type len, const String& str)
2554 return replace(idx, len, str, 0, npos);
2558 \brief
2559 Replace the code points in the range [beg, end) with the specified String object
2561 \note
2562 If \a beg == \a end, the operation is a insert at iterator position \a beg
2564 \param beg
2565 Iterator describing the start of the range to be replaced
2567 \param end
2568 Iterator describing the (exclusive) end of the range to be replaced.
2570 \param str
2571 The String object that is to replace the specified range of code points
2573 \return
2574 This String after the replace operation
2576 \exception std::length_error Thrown if the resulting String would be too large.
2578 String& replace(iterator iter_beg, iterator iter_end, const String& str)
2580 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), str, 0, npos);
2584 \brief
2585 Replace code points in the String with a specified sub-string of a given String object.
2587 \param idx
2588 Index of the first code point to be replaced
2590 \param len
2591 Maximum number of code points to be replaced. If this is 0, the operation is an insert at position \a idx.
2593 \param str
2594 String object containing the data that will replace the specified range of code points
2596 \param str_idx
2597 Index of the first code point of \a str that is to replace the specified code point range
2599 \param str_num
2600 Maximum number of code points of \a str that are to replace the specified code point range
2602 \return
2603 This String after the replace operation
2605 \exception std::out_of_range Thrown if either \a idx, or \a str_idx are invalid
2606 \exception std::length_error Thrown if the resulting String would have been too large.
2608 String& replace(size_type idx, size_type len, const String& str, size_type str_idx, size_type str_num)
2610 if ((d_cplength < idx) || (str.d_cplength < str_idx))
2611 throw std::out_of_range("Index is out of range for CEGUI::String");
2613 if (((str_idx + str_num) > str.d_cplength) || (str_num == npos))
2614 str_num = str.d_cplength - str_idx;
2616 if (((len + idx) > d_cplength) || (len == npos))
2617 len = d_cplength - idx;
2619 size_type newsz = d_cplength + str_num - len;
2621 grow(newsz);
2623 if ((idx + len) < d_cplength)
2624 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2626 memcpy(&ptr()[idx], &str.ptr()[str_idx], str_num * sizeof(utf32));
2627 setlen(newsz);
2629 return *this;
2634 \brief
2635 Replace code points in the String with the specified std::string object
2637 \param idx
2638 Index of the first code point to be replaced
2640 \param len
2641 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
2643 \param std_str
2644 The std::string object that is to replace the specified code points
2646 \note
2647 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
2648 the encountered data is performed.
2650 \return
2651 This String after the replace operation
2653 \exception std::out_of_range Thrown if \a idx is invalid for this String
2654 \exception std::length_error Thrown if the resulting String would be too large.
2656 String& replace(size_type idx, size_type len, const std::string& std_str)
2658 return replace(idx, len, std_str, 0, npos);
2662 \brief
2663 Replace the code points in the range [beg, end) with the specified std::string object
2665 \note
2666 If \a beg == \a end, the operation is a insert at iterator position \a beg
2668 \param beg
2669 Iterator describing the start of the range to be replaced
2671 \param end
2672 Iterator describing the (exclusive) end of the range to be replaced.
2674 \param std_str
2675 The std::string object that is to replace the specified range of code points
2677 \note
2678 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
2679 the encountered data is performed.
2681 \return
2682 This String after the replace operation
2684 \exception std::length_error Thrown if the resulting String would be too large.
2686 String& replace(iterator iter_beg, iterator iter_end, const std::string& std_str)
2688 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), std_str, 0, npos);
2692 \brief
2693 Replace code points in the String with a specified sub-string of a given std::string object.
2695 \param idx
2696 Index of the first code point to be replaced
2698 \param len
2699 Maximum number of code points to be replaced. If this is 0, the operation is an insert at position \a idx.
2701 \param std_str
2702 std::string object containing the data that will replace the specified range of code points
2704 \note
2705 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
2706 the encountered data is performed.
2708 \param str_idx
2709 Index of the first code point of \a std_str that is to replace the specified code point range
2711 \param str_num
2712 Maximum number of code points of \a std_str that are to replace the specified code point range
2714 \return
2715 This String after the replace operation
2717 \exception std::out_of_range Thrown if either \a idx, or \a str_idx are invalid
2718 \exception std::length_error Thrown if the resulting String would have been too large.
2720 String& replace(size_type idx, size_type len, const std::string& std_str, size_type str_idx, size_type str_num)
2722 if (d_cplength < idx)
2723 throw std::out_of_range("Index is out of range for CEGUI::String");
2725 if (std_str.size() < str_idx)
2726 throw std::out_of_range("Index is out of range for std::string");
2728 if (((str_idx + str_num) > std_str.size()) || (str_num == npos))
2729 str_num = (size_type)std_str.size() - str_idx;
2731 if (((len + idx) > d_cplength) || (len == npos))
2732 len = d_cplength - idx;
2734 size_type newsz = d_cplength + str_num - len;
2736 grow(newsz);
2738 if ((idx + len) < d_cplength)
2739 memmove(&ptr()[idx + str_num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2741 utf32* pt = &ptr()[idx + str_num - 1];
2743 while (str_num--)
2744 *pt-- = static_cast<utf32>(static_cast<unsigned char>(std_str[str_idx + str_num]));
2746 setlen(newsz);
2748 return *this;
2753 \brief
2754 Replace code points in the String with the specified null-terminated utf8 encoded data.
2756 \param idx
2757 Index of the first code point to be replaced
2759 \param len
2760 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
2762 \param utf8_str
2763 Buffer containing the null-terminated utf8 encoded data that is to replace the specified code points
2765 \note
2766 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2767 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2768 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2769 results.
2771 \return
2772 This String after the replace operation
2774 \exception std::out_of_range Thrown if \a idx is invalid for this String
2775 \exception std::length_error Thrown if the resulting String would be too large.
2777 String& replace(size_type idx, size_type len, const utf8* utf8_str)
2779 return replace(idx, len, utf8_str, utf_length(utf8_str));
2783 \brief
2784 Replace the code points in the range [beg, end) with the specified null-terminated utf8 encoded data.
2786 \note
2787 If \a beg == \a end, the operation is a insert at iterator position \a beg
2789 \param beg
2790 Iterator describing the start of the range to be replaced
2792 \param end
2793 Iterator describing the (exclusive) end of the range to be replaced.
2795 \param utf8_str
2796 Buffer containing the null-terminated utf8 encoded data that is to replace the specified range of code points
2798 \note
2799 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2800 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2801 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2802 results.
2804 \return
2805 This String after the replace operation
2807 \exception std::length_error Thrown if the resulting String would be too large.
2809 String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str)
2811 return replace(iter_beg, iter_end, utf8_str, utf_length(utf8_str));
2815 \brief
2816 Replace code points in the String with the specified utf8 encoded data.
2818 \param idx
2819 Index of the first code point to be replaced
2821 \param len
2822 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
2824 \param utf8_str
2825 Buffer containing the null-terminated utf8 encoded data that is to replace the specified code points
2827 \note
2828 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2829 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2830 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2831 results.
2833 \param str_len
2834 Length of the utf8 encoded data in utf8 code units (not code points).
2836 \return
2837 This String after the replace operation
2839 \exception std::out_of_range Thrown if \a idx is invalid for this String
2840 \exception std::length_error Thrown if the resulting String would be too large, or if \a str_len was 'npos'.
2842 String& replace(size_type idx, size_type len, const utf8* utf8_str, size_type str_len)
2844 if (d_cplength < idx)
2845 throw std::out_of_range("Index is out of range for CEGUI::String");
2847 if (str_len == npos)
2848 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
2850 if (((len + idx) > d_cplength) || (len == npos))
2851 len = d_cplength - idx;
2853 size_type encsz = encoded_size(utf8_str, str_len);
2854 size_type newsz = d_cplength + encsz - len;
2856 grow(newsz);
2858 if ((idx + len) < d_cplength)
2859 memmove(&ptr()[idx + encsz], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2861 encode(utf8_str, &ptr()[idx], encsz, str_len);
2863 setlen(newsz);
2864 return *this;
2868 \brief
2869 Replace the code points in the range [beg, end) with the specified null-terminated utf8 encoded data.
2871 \note
2872 If \a beg == \a end, the operation is a insert at iterator position \a beg
2874 \param beg
2875 Iterator describing the start of the range to be replaced
2877 \param end
2878 Iterator describing the (exclusive) end of the range to be replaced.
2880 \param utf8_str
2881 Buffer containing the null-terminated utf8 encoded data that is to replace the specified range of code points
2883 \note
2884 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
2885 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
2886 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
2887 results.
2889 \param str_len
2890 Length of the utf8 encoded data in utf8 code units (not code points).
2892 \return
2893 This String after the replace operation
2895 \exception std::length_error Thrown if the resulting String would be too large, or if \a str_len was 'npos'.
2897 String& replace(iterator iter_beg, iterator iter_end, const utf8* utf8_str, size_type str_len)
2899 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), utf8_str, str_len);
2903 \brief
2904 Replaces a specified range of code points with occurrences of a given code point
2906 \param idx
2907 Index of the first code point to be replaced
2909 \param len
2910 Maximum number of code points to replace. If this is 0 the operation is an insert
2912 \param num
2913 Number of occurrences of \a code_point that are to replace the specified range of code points
2915 \param code_point
2916 Code point that is to be used when replacing the specified range of code points
2918 \return
2919 This String after the replace operation.
2921 \exception std::out_of_range Thrown if \a idx is invalid for this String
2922 \exception std::length_error Thrown if resulting String would have been too long, or if \a num was 'npos'.
2924 String& replace(size_type idx, size_type len, size_type num, utf32 code_point)
2926 if (d_cplength < idx)
2927 throw std::out_of_range("Index is out of range for CEGUI::String");
2929 if (num == npos)
2930 throw std::length_error("Code point count can not be 'npos'");
2932 if (((len + idx) > d_cplength) || (len == npos))
2933 len = d_cplength - idx;
2935 size_type newsz = d_cplength + num - len;
2937 grow(newsz);
2939 if ((idx + len) < d_cplength)
2940 memmove(&ptr()[idx + num], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
2942 utf32* pt = &ptr()[idx + num - 1];
2944 while (num--)
2945 *pt-- = code_point;
2947 setlen(newsz);
2949 return *this;
2953 \brief
2954 Replace the code points in the range [beg, end) with occurrences of a given code point
2956 \note
2957 If \a beg == \a end, the operation is an insert at iterator position \a beg
2959 \param beg
2960 Iterator describing the start of the range to be replaced
2962 \param end
2963 Iterator describing the (exclusive) end of the range to be replaced.
2965 \param num
2966 Number of occurrences of \a code_point that are to replace the specified range of code points
2968 \param code_point
2969 Code point that is to be used when replacing the specified range of code points
2971 \return
2972 This String after the replace operation
2974 \exception std::length_error Thrown if resulting String would have been too long, or if \a num was 'npos'.
2976 String& replace(iterator iter_beg, iterator iter_end, size_type num, utf32 code_point)
2978 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), num, code_point);
2983 \brief
2984 Replace the code points in the range [beg, end) with code points from the range [newBeg, newEnd).
2986 \note
2987 If \a beg == \a end, the operation is an insert at iterator position \a beg
2989 \param beg
2990 Iterator describing the start of the range to be replaced
2992 \param end
2993 Iterator describing the (exclusive) end of the range to be replaced.
2995 \param newBeg
2996 Iterator describing the beginning of the range to insert.
2998 \param newEnd
2999 Iterator describing the (exclusive) end of the range to insert.
3001 \return
3002 This String after the insert operation.
3004 \exception std::length_error Thrown if the resulting string would be too long.
3006 String& replace(iterator iter_beg, iterator iter_end, const_iterator iter_newBeg, const_iterator iter_newEnd)
3008 if (iter_beg == iter_end)
3010 erase(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg));
3012 else
3014 size_type str_len = safe_iter_dif(iter_newEnd, iter_newBeg);
3015 size_type idx = safe_iter_dif(iter_beg, begin());
3016 size_type len = safe_iter_dif(iter_end, iter_beg);
3018 if ((len + idx) > d_cplength)
3019 len = d_cplength - idx;
3021 size_type newsz = d_cplength + str_len - len;
3023 grow(newsz);
3025 if ((idx + len) < d_cplength)
3026 memmove(&ptr()[idx + str_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
3028 memcpy(&ptr()[idx], iter_newBeg.d_ptr, str_len * sizeof(utf32));
3029 setlen(newsz);
3032 return *this;
3037 \brief
3038 Replace code points in the String with the specified c-string.
3040 \param idx
3041 Index of the first code point to be replaced
3043 \param len
3044 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
3046 \param c_str
3047 c-string that is to replace the specified code points
3049 \return
3050 This String after the replace operation
3052 \exception std::out_of_range Thrown if \a idx is invalid for this String
3053 \exception std::length_error Thrown if the resulting String would be too large.
3055 String& replace(size_type idx, size_type len, const char* cstr)
3057 return replace(idx, len, cstr, strlen(cstr));
3062 \brief
3063 Replace the code points in the range [beg, end) with the specified c-string.
3065 \note
3066 If \a beg == \a end, the operation is a insert at iterator position \a beg
3068 \param beg
3069 Iterator describing the start of the range to be replaced
3071 \param end
3072 Iterator describing the (exclusive) end of the range to be replaced.
3074 \param c_str
3075 c-string that is to replace the specified range of code points
3077 \return
3078 This String after the replace operation
3080 \exception std::length_error Thrown if the resulting String would be too large.
3082 String& replace(iterator iter_beg, iterator iter_end, const char* cstr)
3084 return replace(iter_beg, iter_end, cstr, strlen(cstr));
3089 \brief
3090 Replace code points in the String with chars from the given char array.
3092 \param idx
3093 Index of the first code point to be replaced
3095 \param len
3096 Maximum number of code points to be replaced (if this is 0, operation is an insert at position \a idx)
3098 \param chars
3099 char array containing the cars that are to replace the specified code points
3101 \param chars_len
3102 Number of chars in the char array.
3104 \return
3105 This String after the replace operation
3107 \exception std::out_of_range Thrown if \a idx is invalid for this String
3108 \exception std::length_error Thrown if the resulting String would be too large, or if \a chars_len was 'npos'.
3110 String& replace(size_type idx, size_type len, const char* chars, size_type chars_len)
3112 if (d_cplength < idx)
3113 throw std::out_of_range("Index is out of range for CEGUI::String");
3115 if (chars_len == npos)
3116 throw std::length_error("Length for the char array can not be 'npos'");
3118 if (((len + idx) > d_cplength) || (len == npos))
3119 len = d_cplength - idx;
3121 size_type newsz = d_cplength + chars_len - len;
3123 grow(newsz);
3125 if ((idx + len) < d_cplength)
3126 memmove(&ptr()[idx + chars_len], &ptr()[len + idx], (d_cplength - idx - len) * sizeof(utf32));
3128 utf32* pt = &ptr()[idx + chars_len - 1];
3130 while (chars_len--)
3131 *pt-- = static_cast<utf32>(static_cast<unsigned char>(chars[chars_len]));
3133 setlen(newsz);
3134 return *this;
3139 \brief
3140 Replace the code points in the range [beg, end) with chars from the given char array.
3142 \note
3143 If \a beg == \a end, the operation is a insert at iterator position \a beg
3145 \param beg
3146 Iterator describing the start of the range to be replaced
3148 \param end
3149 Iterator describing the (exclusive) end of the range to be replaced.
3151 \param chars
3152 char array containing the chars that are to replace the specified range of code points
3154 \param chars_len
3155 Number of chars in the char array.
3157 \return
3158 This String after the replace operation
3160 \exception std::length_error Thrown if the resulting String would be too large, or if \a chars_len was 'npos'.
3162 String& replace(iterator iter_beg, iterator iter_end, const char* chars, size_type chars_len)
3164 return replace(safe_iter_dif(iter_beg, begin()), safe_iter_dif(iter_end, iter_beg), chars, chars_len);
3168 //////////////////////////////////////////////////////////////////////////
3169 // Find a code point
3170 //////////////////////////////////////////////////////////////////////////
3172 \brief
3173 Search forwards for a given code point
3175 \param code_point
3176 The utf32 code point to search for
3178 \param idx
3179 Index of the code point where the search is to start.
3181 \return
3182 - Index of the first occurrence of \a code_point travelling forwards from \a idx.
3183 - npos if the code point could not be found
3185 size_type find(utf32 code_point, size_type idx = 0) const
3187 if (idx < d_cplength)
3189 const utf32* pt = &ptr()[idx];
3191 while (idx < d_cplength)
3193 if (*pt++ == code_point)
3194 return idx;
3196 ++idx;
3201 return npos;
3205 \brief
3206 Search backwards for a given code point
3208 \param code_point
3209 The utf32 code point to search for
3211 \param idx
3212 Index of the code point where the search is to start.
3214 \return
3215 - Index of the first occurrence of \a code_point travelling backwards from \a idx.
3216 - npos if the code point could not be found
3218 size_type rfind(utf32 code_point, size_type idx = npos) const
3220 if (idx >= d_cplength)
3221 idx = d_cplength - 1;
3223 if (d_cplength > 0)
3225 const utf32* pt = &ptr()[idx];
3229 if (*pt-- == code_point)
3230 return idx;
3232 } while (idx-- != 0);
3236 return npos;
3239 //////////////////////////////////////////////////////////////////////////
3240 // Find a substring
3241 //////////////////////////////////////////////////////////////////////////
3243 \brief
3244 Search forwards for a sub-string
3246 \param str
3247 String object describing the sub-string to search for
3249 \param idx
3250 Index of the code point where the search is to start
3252 \return
3253 - Index of the first occurrence of sub-string \a str travelling forwards from \a idx.
3254 - npos if the sub-string could not be found
3256 size_type find(const String& str, size_type idx = 0) const
3258 if ((str.d_cplength == 0) && (idx < d_cplength))
3259 return idx;
3261 if (idx < d_cplength)
3263 // loop while search string could fit in to search area
3264 while (d_cplength - idx >= str.d_cplength)
3266 if (0 == compare(idx, str.d_cplength, str))
3267 return idx;
3269 ++idx;
3274 return npos;
3278 \brief
3279 Search backwards for a sub-string
3281 \param str
3282 String object describing the sub-string to search for
3284 \param idx
3285 Index of the code point where the search is to start
3287 \return
3288 - Index of the first occurrence of sub-string \a str travelling backwards from \a idx.
3289 - npos if the sub-string could not be found
3291 size_type rfind(const String& str, size_type idx = npos) const
3293 if (str.d_cplength == 0)
3294 return (idx < d_cplength) ? idx : d_cplength;
3296 if (str.d_cplength <= d_cplength)
3298 if (idx > (d_cplength - str.d_cplength))
3299 idx = d_cplength - str.d_cplength;
3303 if (0 == compare(idx, str.d_cplength, str))
3304 return idx;
3306 } while (idx-- != 0);
3310 return npos;
3314 \brief
3315 Search forwards for a sub-string
3317 \param std_str
3318 std::string object describing the sub-string to search for
3320 \note
3321 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
3322 the encountered data is performed.
3324 \param idx
3325 Index of the code point where the search is to start
3327 \return
3328 - Index of the first occurrence of sub-string \a std_str travelling forwards from \a idx.
3329 - npos if the sub-string could not be found
3331 size_type find(const std::string& std_str, size_type idx = 0) const
3333 std::string::size_type sze = std_str.size();
3335 if ((sze == 0) && (idx < d_cplength))
3336 return idx;
3338 if (idx < d_cplength)
3340 // loop while search string could fit in to search area
3341 while (d_cplength - idx >= sze)
3343 if (0 == compare(idx, (size_type)sze, std_str))
3344 return idx;
3346 ++idx;
3351 return npos;
3355 \brief
3356 Search backwards for a sub-string
3358 \param std_str
3359 std::string object describing the sub-string to search for
3361 \note
3362 Characters from \a std_str are considered to represent Unicode code points in the range 0x00..0xFF. No translation of
3363 the encountered data is performed.
3365 \param idx
3366 Index of the code point where the search is to start
3368 \return
3369 - Index of the first occurrence of sub-string \a std_str travelling backwards from \a idx.
3370 - npos if the sub-string could not be found
3372 size_type rfind(const std::string& std_str, size_type idx = npos) const
3374 std::string::size_type sze = std_str.size();
3376 if (sze == 0)
3377 return (idx < d_cplength) ? idx : d_cplength;
3379 if (sze <= d_cplength)
3381 if (idx > (d_cplength - sze))
3382 idx = d_cplength - sze;
3386 if (0 == compare(idx, (size_type)sze, std_str))
3387 return idx;
3389 } while (idx-- != 0);
3393 return npos;
3397 \brief
3398 Search forwards for a sub-string
3400 \param utf8_str
3401 Buffer containing null-terminated utf8 encoded data describing the sub-string to search for
3403 \note
3404 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3405 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3406 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3407 results.
3409 \param idx
3410 Index of the code point where the search is to start
3412 \return
3413 - Index of the first occurrence of sub-string \a utf8_str travelling forwards from \a idx.
3414 - npos if the sub-string could not be found
3416 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3418 size_type find(const utf8* utf8_str, size_type idx = 0) const
3420 return find(utf8_str, idx, utf_length(utf8_str));
3424 \brief
3425 Search backwards for a sub-string
3427 \param utf8_str
3428 Buffer containing null-terminated utf8 encoded data describing the sub-string to search for
3430 \note
3431 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3432 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3433 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3434 results.
3436 \param idx
3437 Index of the code point where the search is to start
3439 \return
3440 - Index of the first occurrence of sub-string \a utf8_str travelling backwards from \a idx.
3441 - npos if the sub-string could not be found
3443 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3445 size_type rfind(const utf8* utf8_str, size_type idx = npos) const
3447 return rfind(utf8_str, idx, utf_length(utf8_str));
3451 \brief
3452 Search forwards for a sub-string
3454 \param utf8_str
3455 Buffer containing utf8 encoded data describing the sub-string to search for
3457 \note
3458 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3459 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3460 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3461 results.
3463 \param idx
3464 Index of the code point where the search is to start
3466 \param str_len
3467 Length of the utf8 encoded sub-string in utf8 code units (not code points)
3469 \return
3470 - Index of the first occurrence of sub-string \a utf8_str travelling forwards from \a idx.
3471 - npos if the sub-string could not be found
3473 \exception std::length_error Thrown if \a str_len is 'npos'
3475 size_type find(const utf8* utf8_str, size_type idx, size_type str_len) const
3477 if (str_len == npos)
3478 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3480 size_type sze = encoded_size(utf8_str, str_len);
3482 if ((sze == 0) && (idx < d_cplength))
3483 return idx;
3485 if (idx < d_cplength)
3487 // loop while search string could fit in to search area
3488 while (d_cplength - idx >= sze)
3490 if (0 == compare(idx, sze, utf8_str, sze))
3491 return idx;
3493 ++idx;
3498 return npos;
3502 \brief
3503 Search backwards for a sub-string
3505 \param utf8_str
3506 Buffer containing utf8 encoded data describing the sub-string to search for
3508 \note
3509 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3510 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3511 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3512 results.
3514 \param idx
3515 Index of the code point where the search is to start
3517 \param str_len
3518 Length of the utf8 encoded sub-string in utf8 code units (not code points)
3520 \return
3521 - Index of the first occurrence of sub-string \a utf8_str travelling backwards from \a idx.
3522 - npos if the sub-string could not be found
3524 \exception std::length_error Thrown if \a str_len is 'npos'
3526 size_type rfind(const utf8* utf8_str, size_type idx, size_type str_len) const
3528 if (str_len == npos)
3529 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3531 size_type sze = encoded_size(utf8_str, str_len);
3533 if (sze == 0)
3534 return (idx < d_cplength) ? idx : d_cplength;
3536 if (sze <= d_cplength)
3538 if (idx > (d_cplength - sze))
3539 idx = d_cplength - sze;
3543 if (0 == compare(idx, sze, utf8_str, sze))
3544 return idx;
3546 } while (idx-- != 0);
3550 return npos;
3555 \brief
3556 Search forwards for a sub-string
3558 \param c_str
3559 c-string describing the sub-string to search for
3561 \param idx
3562 Index of the code point where the search is to start
3564 \return
3565 - Index of the first occurrence of sub-string \a c_str travelling forwards from \a idx.
3566 - npos if the sub-string could not be found
3568 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3570 size_type find(const char* cstr, size_type idx = 0) const
3572 return find(cstr, idx, strlen(cstr));
3577 \brief
3578 Search backwards for a sub-string
3580 \param c_str
3581 c-string describing the sub-string to search for
3583 \param idx
3584 Index of the code point where the search is to start
3586 \return
3587 - Index of the first occurrence of sub-string \a c_str travelling backwards from \a idx.
3588 - npos if the sub-string could not be found
3590 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3592 size_type rfind(const char* cstr, size_type idx = npos) const
3594 return rfind(cstr, idx, strlen(cstr));
3599 \brief
3600 Search forwards for a sub-string
3602 \param chars
3603 char array describing the sub-string to search for
3605 \param idx
3606 Index of the code point where the search is to start
3608 \param chars_len
3609 Number of chars in the char array.
3611 \return
3612 - Index of the first occurrence of sub-string \a chars travelling forwards from \a idx.
3613 - npos if the sub-string could not be found
3615 \exception std::length_error Thrown if \a chars_len is 'npos'
3617 size_type find(const char* chars, size_type idx, size_type chars_len) const
3619 if (chars_len == npos)
3620 throw std::length_error("Length for char array can not be 'npos'");
3622 if ((chars_len == 0) && (idx < d_cplength))
3623 return idx;
3625 if (idx < d_cplength)
3627 // loop while search string could fit in to search area
3628 while (d_cplength - idx >= chars_len)
3630 if (0 == compare(idx, chars_len, chars, chars_len))
3631 return idx;
3633 ++idx;
3638 return npos;
3643 \brief
3644 Search backwards for a sub-string
3646 \param chars
3647 char array describing the sub-string to search for
3649 \param idx
3650 Index of the code point where the search is to start
3652 \param chars_len
3653 Number of chars in the char array.
3655 \return
3656 - Index of the first occurrence of sub-string \a chars travelling backwards from \a idx.
3657 - npos if the sub-string could not be found
3659 \exception std::length_error Thrown if \a chars_len is 'npos'
3661 size_type rfind(const char* chars, size_type idx, size_type chars_len) const
3663 if (chars_len == npos)
3664 throw std::length_error("Length for char array can not be 'npos'");
3666 if (chars_len == 0)
3667 return (idx < d_cplength) ? idx : d_cplength;
3669 if (chars_len <= d_cplength)
3671 if (idx > (d_cplength - chars_len))
3672 idx = d_cplength - chars_len;
3676 if (0 == compare(idx, chars_len, chars, chars_len))
3677 return idx;
3679 } while (idx-- != 0);
3683 return npos;
3687 //////////////////////////////////////////////////////////////////////////
3688 // Find first of different code-points
3689 //////////////////////////////////////////////////////////////////////////
3691 \brief
3692 Find the first occurrence of one of a set of code points.
3694 \param str
3695 String object describing the set of code points.
3697 \param idx
3698 Index of the start point for the search
3700 \return
3701 - Index of the first occurrence of any one of the code points in \a str starting from from \a idx.
3702 - npos if none of the code points in \a str were found.
3704 size_type find_first_of(const String& str, size_type idx = 0) const
3706 if (idx < d_cplength)
3708 const utf32* pt = &ptr()[idx];
3712 if (npos != str.find(*pt++))
3713 return idx;
3715 } while (++idx != d_cplength);
3719 return npos;
3723 \brief
3724 Find the first code point that is not one of a set of code points.
3726 \param str
3727 String object describing the set of code points.
3729 \param idx
3730 Index of the start point for the search
3732 \return
3733 - Index of the first code point that does not match any one of the code points in \a str starting from from \a idx.
3734 - npos if all code points matched one of the code points in \a str.
3736 size_type find_first_not_of(const String& str, size_type idx = 0) const
3738 if (idx < d_cplength)
3740 const utf32* pt = &ptr()[idx];
3744 if (npos == str.find(*pt++))
3745 return idx;
3747 } while (++idx != d_cplength);
3751 return npos;
3756 \brief
3757 Find the first occurrence of one of a set of code points.
3759 \param std_str
3760 std::string object describing the set of code points.
3762 \note
3763 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
3764 the provided data will occur.
3766 \param idx
3767 Index of the start point for the search
3769 \return
3770 - Index of the first occurrence of any one of the code points in \a std_str starting from from \a idx.
3771 - npos if none of the code points in \a std_str were found.
3773 size_type find_first_of(const std::string& std_str, size_type idx = 0) const
3775 if (idx < d_cplength)
3777 const utf32* pt = &ptr()[idx];
3781 if (npos != find_codepoint(std_str, *pt++))
3782 return idx;
3784 } while (++idx != d_cplength);
3788 return npos;
3792 \brief
3793 Find the first code point that is not one of a set of code points.
3795 \param std_str
3796 std::string object describing the set of code points.
3798 \note
3799 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
3800 the provided data will occur.
3802 \param idx
3803 Index of the start point for the search
3805 \return
3806 - Index of the first code point that does not match any one of the code points in \a std_str starting from from \a idx.
3807 - npos if all code points matched one of the code points in \a std_str.
3809 size_type find_first_not_of(const std::string& std_str, size_type idx = 0) const
3811 if (idx < d_cplength)
3813 const utf32* pt = &ptr()[idx];
3817 if (npos == find_codepoint(std_str, *pt++))
3818 return idx;
3820 } while (++idx != d_cplength);
3824 return npos;
3829 \brief
3830 Find the first occurrence of one of a set of code points.
3832 \param utf8_str
3833 Buffer containing null-terminated utf8 encoded data describing the set of code points.
3835 \note
3836 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3837 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3838 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3839 results.
3841 \param idx
3842 Index of the start point for the search
3844 \return
3845 - Index of the first occurrence of any one of the code points in \a utf8_str starting from from \a idx.
3846 - npos if none of the code points in \a utf8_str were found.
3848 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3850 size_type find_first_of(const utf8* utf8_str, size_type idx = 0) const
3852 return find_first_of(utf8_str, idx, utf_length(utf8_str));
3856 \brief
3857 Find the first code point that is not one of a set of code points.
3859 \param utf8_str
3860 Buffer containing null-terminated utf8 encoded data describing the set of code points.
3862 \note
3863 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3864 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3865 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3866 results.
3868 \param idx
3869 Index of the start point for the search
3871 \return
3872 - Index of the first code point that does not match any one of the code points in \a utf8_str starting from from \a idx.
3873 - npos if all code points matched one of the code points in \a utf8_str.
3875 \exception std::out_of_range Thrown if \a idx is invalid for this String.
3877 size_type find_first_not_of(const utf8* utf8_str, size_type idx = 0) const
3879 return find_first_not_of(utf8_str, idx, utf_length(utf8_str));
3883 \brief
3884 Find the first occurrence of one of a set of code points.
3886 \param utf8_str
3887 Buffer containing utf8 encoded data describing the set of code points.
3889 \note
3890 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3891 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3892 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3893 results.
3895 \param idx
3896 Index of the start point for the search
3898 \param str_len
3899 Length of the utf8 encoded data in utf8 code units (not code points).
3901 \return
3902 - Index of the first occurrence of any one of the code points in \a utf8_str starting from from \a idx.
3903 - npos if none of the code points in \a utf8_str were found.
3905 \exception std::length_error Thrown if \a str_len was 'npos'.
3907 size_type find_first_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3909 if (str_len == npos)
3910 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3912 if (idx < d_cplength)
3914 size_type encsze = encoded_size(utf8_str, str_len);
3916 const utf32* pt = &ptr()[idx];
3920 if (npos != find_codepoint(utf8_str, encsze, *pt++))
3921 return idx;
3923 } while (++idx != d_cplength);
3927 return npos;
3931 \brief
3932 Find the first code point that is not one of a set of code points.
3934 \param utf8_str
3935 Buffer containing utf8 encoded data describing the set of code points.
3937 \note
3938 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
3939 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
3940 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
3941 results.
3943 \param idx
3944 Index of the start point for the search
3946 \param str_len
3947 Length of the utf8 encoded data in utf8 code units (not code points).
3949 \return
3950 - Index of the first code point that does not match any one of the code points in \a utf8_str starting from from \a idx.
3951 - npos if all code points matched one of the code points in \a utf8_str.
3953 \exception std::length_error Thrown if \a str_len was 'npos'.
3955 size_type find_first_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
3957 if (str_len == npos)
3958 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
3960 if (idx < d_cplength)
3962 size_type encsze = encoded_size(utf8_str, str_len);
3964 const utf32* pt = &ptr()[idx];
3968 if (npos == find_codepoint(utf8_str, encsze, *pt++))
3969 return idx;
3971 } while (++idx != d_cplength);
3975 return npos;
3980 \brief
3981 Search forwards for a given code point
3983 \param code_point
3984 The utf32 code point to search for
3986 \param idx
3987 Index of the code point where the search is to start.
3989 \return
3990 - Index of the first occurrence of \a code_point starting from from \a idx.
3991 - npos if the code point could not be found
3993 size_type find_first_of(utf32 code_point, size_type idx = 0) const
3995 return find(code_point, idx);
3999 \brief
4000 Search forwards for the first code point that does not match a given code point
4002 \param code_point
4003 The utf32 code point to search for
4005 \param idx
4006 Index of the code point where the search is to start.
4008 \return
4009 - Index of the first code point that does not match \a code_point starting from from \a idx.
4010 - npos if all code points matched \a code_point
4012 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4014 size_type find_first_not_of(utf32 code_point, size_type idx = 0) const
4016 if (idx < d_cplength)
4020 if ((*this)[idx] != code_point)
4021 return idx;
4023 } while(idx++ < d_cplength);
4027 return npos;
4032 \brief
4033 Find the first occurrence of one of a set of chars.
4035 \param c_str
4036 c-string describing the set of chars.
4038 \param idx
4039 Index of the start point for the search
4041 \return
4042 - Index of the first occurrence of any one of the chars in \a c_str starting from from \a idx.
4043 - npos if none of the chars in \a c_str were found.
4045 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4047 size_type find_first_of(const char* cstr, size_type idx = 0) const
4049 return find_first_of(cstr, idx, strlen(cstr));
4054 \brief
4055 Find the first code point that is not one of a set of chars.
4057 \param c_str
4058 c-string describing the set of chars.
4060 \param idx
4061 Index of the start point for the search
4063 \return
4064 - Index of the first code point that does not match any one of the chars in \a c_str starting from from \a idx.
4065 - npos if all code points matched any of the chars in \a c_str.
4067 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4069 size_type find_first_not_of(const char* cstr, size_type idx = 0) const
4071 return find_first_not_of(cstr, idx, strlen(cstr));
4076 \brief
4077 Find the first occurrence of one of a set of chars.
4079 \param chars
4080 char array containing the set of chars.
4082 \param idx
4083 Index of the start point for the search
4085 \param chars_len
4086 Number of chars in the char array.
4088 \return
4089 - Index of the first occurrence of any one of the chars in \a chars starting from from \a idx.
4090 - npos if none of the chars in \a chars were found.
4092 \exception std::length_error Thrown if \a chars_len was 'npos'.
4094 size_type find_first_of(const char* chars, size_type idx, size_type chars_len) const
4096 if (chars_len == npos)
4097 throw std::length_error("Length for char array can not be 'npos'");
4099 if (idx < d_cplength)
4101 const utf32* pt = &ptr()[idx];
4105 if (npos != find_codepoint(chars, chars_len, *pt++))
4106 return idx;
4108 } while (++idx != d_cplength);
4112 return npos;
4117 \brief
4118 Find the first code point that is not one of a set of chars.
4120 \param chars
4121 char array containing the set of chars.
4123 \param idx
4124 Index of the start point for the search
4126 \param chars_len
4127 Number of chars in the car array.
4129 \return
4130 - Index of the first code point that does not match any one of the chars in \a chars starting from from \a idx.
4131 - npos if all code points matched any of the chars in \a chars.
4133 \exception std::length_error Thrown if \a chars_len was 'npos'.
4135 size_type find_first_not_of(const char* chars, size_type idx, size_type chars_len) const
4137 if (chars_len == npos)
4138 throw std::length_error("Length for char array can not be 'npos'");
4140 if (idx < d_cplength)
4142 const utf32* pt = &ptr()[idx];
4146 if (npos == find_codepoint(chars, chars_len, *pt++))
4147 return idx;
4149 } while (++idx != d_cplength);
4153 return npos;
4157 //////////////////////////////////////////////////////////////////////////
4158 // Find last of different code-points
4159 //////////////////////////////////////////////////////////////////////////
4161 \brief
4162 Find the last occurrence of one of a set of code points.
4164 \param str
4165 String object describing the set of code points.
4167 \param idx
4168 Index of the start point for the search
4170 \return
4171 - Index of the last occurrence of any one of the code points in \a str starting from \a idx.
4172 - npos if none of the code points in \a str were found.
4174 size_type find_last_of(const String& str, size_type idx = npos) const
4176 if (d_cplength > 0)
4178 if (idx >= d_cplength)
4179 idx = d_cplength - 1;
4181 const utf32* pt = &ptr()[idx];
4185 if (npos != str.find(*pt--))
4186 return idx;
4188 } while (idx-- != 0);
4192 return npos;
4196 \brief
4197 Find the last code point that is not one of a set of code points.
4199 \param str
4200 String object describing the set of code points.
4202 \param idx
4203 Index of the start point for the search
4205 \return
4206 - Index of the last code point that does not match any one of the code points in \a str starting from \a idx.
4207 - npos if all code points matched one of the code points in \a str.
4209 size_type find_last_not_of(const String& str, size_type idx = npos) const
4211 if (d_cplength > 0)
4213 if (idx >= d_cplength)
4214 idx = d_cplength - 1;
4216 const utf32* pt = &ptr()[idx];
4220 if (npos == str.find(*pt--))
4221 return idx;
4223 } while (idx-- != 0);
4227 return npos;
4232 \brief
4233 Find the last occurrence of one of a set of code points.
4235 \param std_str
4236 std::string object describing the set of code points.
4238 \note
4239 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
4240 the provided data will occur.
4242 \param idx
4243 Index of the start point for the search
4245 \return
4246 - Index of the last occurrence of any one of the code points in \a std_str starting from \a idx.
4247 - npos if none of the code points in \a std_str were found.
4249 size_type find_last_of(const std::string& std_str, size_type idx = npos) const
4251 if (d_cplength > 0)
4253 if (idx >= d_cplength)
4254 idx = d_cplength - 1;
4256 const utf32* pt = &ptr()[idx];
4260 if (npos != find_codepoint(std_str, *pt--))
4261 return idx;
4263 } while (idx-- != 0);
4267 return npos;
4271 \brief
4272 Find the last code point that is not one of a set of code points.
4274 \param std_str
4275 std::string object describing the set of code points.
4277 \note
4278 The characters of \a std_str are taken to be unencoded data which represent Unicode code points 0x00..0xFF. No translation of
4279 the provided data will occur.
4281 \param idx
4282 Index of the start point for the search
4284 \return
4285 - Index of the last code point that does not match any one of the code points in \a std_str starting from \a idx.
4286 - npos if all code points matched one of the code points in \a std_str.
4288 size_type find_last_not_of(const std::string& std_str, size_type idx = npos) const
4290 if (d_cplength > 0)
4292 if (idx >= d_cplength)
4293 idx = d_cplength - 1;
4295 const utf32* pt = &ptr()[idx];
4299 if (npos == find_codepoint(std_str, *pt--))
4300 return idx;
4302 } while (idx-- != 0);
4306 return npos;
4311 \brief
4312 Find the last occurrence of one of a set of code points.
4314 \param utf8_str
4315 Buffer containing null-terminated utf8 encoded data describing the set of code points.
4317 \note
4318 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
4319 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
4320 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
4321 results.
4323 \param idx
4324 Index of the start point for the search
4326 \return
4327 - Index of the last occurrence of any one of the code points in \a utf8_str starting from \a idx.
4328 - npos if none of the code points in \a utf8_str were found.
4330 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4332 size_type find_last_of(const utf8* utf8_str, size_type idx = npos) const
4334 return find_last_of(utf8_str, idx, utf_length(utf8_str));
4338 \brief
4339 Find the last code point that is not one of a set of code points.
4341 \param utf8_str
4342 Buffer containing null-terminated utf8 encoded data describing the set of code points.
4344 \note
4345 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
4346 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
4347 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
4348 results.
4350 \param idx
4351 Index of the start point for the search
4353 \return
4354 - Index of the last code point that does not match any one of the code points in \a utf8_str starting from \a idx.
4355 - npos if all code points matched one of the code points in \a utf8_str.
4357 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4359 size_type find_last_not_of(const utf8* utf8_str, size_type idx = npos) const
4361 return find_last_not_of(utf8_str, idx, utf_length(utf8_str));
4365 \brief
4366 Find the last occurrence of one of a set of code points.
4368 \param utf8_str
4369 Buffer containing utf8 encoded data describing the set of code points.
4371 \note
4372 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
4373 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
4374 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
4375 results.
4377 \param idx
4378 Index of the start point for the search
4380 \param str_len
4381 Length of the utf8 encoded data in utf8 code units (not code points).
4383 \return
4384 - Index of the last occurrence of any one of the code points in \a utf8_str starting from from \a idx.
4385 - npos if none of the code points in \a utf8_str were found.
4387 \exception std::length_error Thrown if \a str_len was 'npos'.
4389 size_type find_last_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4391 if (str_len == npos)
4392 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
4394 if (d_cplength > 0)
4396 if (idx >= d_cplength)
4397 idx = d_cplength - 1;
4399 size_type encsze = encoded_size(utf8_str, str_len);
4401 const utf32* pt = &ptr()[idx];
4405 if (npos != find_codepoint(utf8_str, encsze, *pt--))
4406 return idx;
4408 } while (idx-- != 0);
4412 return npos;
4416 \brief
4417 Find the last code point that is not one of a set of code points.
4419 \param utf8_str
4420 Buffer containing utf8 encoded data describing the set of code points.
4422 \note
4423 A basic string literal (cast to utf8*) can be passed to this function, provided that the string is
4424 comprised only of code points 0x00..0x7f. The use of extended ASCII characters (with values >0x7f)
4425 would result in incorrect behaviour as the String will attempt to 'decode' the data, with unpredictable
4426 results.
4428 \param idx
4429 Index of the start point for the search
4431 \param str_len
4432 Length of the utf8 encoded data in utf8 code units (not code points).
4434 \return
4435 - Index of the last code point that does not match any one of the code points in \a utf8_str starting from from \a idx.
4436 - npos if all code points matched one of the code points in \a utf8_str.
4438 \exception std::length_error Thrown if \a str_len was 'npos'.
4440 size_type find_last_not_of(const utf8* utf8_str, size_type idx, size_type str_len) const
4442 if (str_len == npos)
4443 throw std::length_error("Length for utf8 encoded string can not be 'npos'");
4445 if (d_cplength > 0)
4447 if (idx >= d_cplength)
4448 idx = d_cplength - 1;
4450 size_type encsze = encoded_size(utf8_str, str_len);
4452 const utf32* pt = &ptr()[idx];
4456 if (npos == find_codepoint(utf8_str, encsze, *pt--))
4457 return idx;
4459 } while (idx-- != 0);
4463 return npos;
4468 \brief
4469 Search for last occurrence of a given code point
4471 \param code_point
4472 The utf32 code point to search for
4474 \param idx
4475 Index of the code point where the search is to start.
4477 \return
4478 - Index of the last occurrence of \a code_point starting from \a idx.
4479 - npos if the code point could not be found
4481 size_type find_last_of(utf32 code_point, size_type idx = npos) const
4483 return rfind(code_point, idx);
4487 \brief
4488 Search for the last code point that does not match a given code point
4490 \param code_point
4491 The utf32 code point to search for
4493 \param idx
4494 Index of the code point where the search is to start.
4496 \return
4497 - Index of the last code point that does not match \a code_point starting from from \a idx.
4498 - npos if all code points matched \a code_point
4500 size_type find_last_not_of(utf32 code_point, size_type idx = npos) const
4502 if (d_cplength > 0)
4504 if (idx >= d_cplength)
4505 idx = d_cplength - 1;
4509 if ((*this)[idx] != code_point)
4510 return idx;
4512 } while(idx-- != 0);
4516 return npos;
4521 \brief
4522 Find the last occurrence of one of a set of chars.
4524 \param c_str
4525 c-string describing the set of chars.
4527 \param idx
4528 Index of the start point for the search
4530 \return
4531 - Index of the last occurrence of any one of the chars in \a c_str starting from \a idx.
4532 - npos if none of the chars in \a c_str were found.
4534 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4536 size_type find_last_of(const char* cstr, size_type idx = npos) const
4538 return find_last_of(cstr, idx, strlen(cstr));
4543 \brief
4544 Find the last code point that is not one of a set of chars.
4546 \param c_str
4547 c-string describing the set of chars.
4549 \param idx
4550 Index of the start point for the search
4552 \return
4553 - Index of the last code point that does not match any one of the chars in \a c_str starting from \a idx.
4554 - npos if all code points matched any of the chars in \a c_str.
4556 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4558 size_type find_last_not_of(const char* cstr, size_type idx = npos) const
4560 return find_last_not_of(cstr, idx, strlen(cstr));
4565 \brief
4566 Find the last occurrence of one of a set of chars.
4568 \param chars
4569 char array containing the set of chars.
4571 \param idx
4572 Index of the start point for the search
4574 \param chars_len
4575 Number of chars in the char array.
4577 \return
4578 - Index of the last occurrence of any one of the chars in \a chars, starting from from \a idx.
4579 - npos if none of the chars in \a chars were found.
4581 \exception std::length_error Thrown if \a chars_len was 'npos'.
4583 size_type find_last_of(const char* chars, size_type idx, size_type chars_len) const
4585 if (chars_len == npos)
4586 throw std::length_error("Length for char array can not be 'npos'");
4588 if (d_cplength > 0)
4590 if (idx >= d_cplength)
4591 idx = d_cplength - 1;
4593 const utf32* pt = &ptr()[idx];
4597 if (npos != find_codepoint(chars, chars_len, *pt--))
4598 return idx;
4600 } while (idx-- != 0);
4604 return npos;
4609 \brief
4610 Find the last code point that is not one of a set of chars.
4612 \param chars
4613 char array containing the set of chars.
4615 \param idx
4616 Index of the start point for the search
4618 \param chars_len
4619 Number of chars in the char array.
4621 \return
4622 - Index of the last code point that does not match any one of the chars in \a chars, starting from from \a idx.
4623 - npos if all code points matched any of the chars in \a chars.
4625 \exception std::length_error Thrown if \a chars_len was 'npos'.
4627 size_type find_last_not_of(const char* chars, size_type idx, size_type chars_len) const
4629 if (chars_len == npos)
4630 throw std::length_error("Length for char array can not be 'npos'");
4632 if (d_cplength > 0)
4634 if (idx >= d_cplength)
4635 idx = d_cplength - 1;
4637 const utf32* pt = &ptr()[idx];
4641 if (npos == find_codepoint(chars, chars_len, *pt--))
4642 return idx;
4644 } while (idx-- != 0);
4648 return npos;
4652 //////////////////////////////////////////////////////////////////////////
4653 // Substring
4654 //////////////////////////////////////////////////////////////////////////
4656 \brief
4657 Returns a substring of this String.
4659 \param idx
4660 Index of the first code point to use for the sub-string.
4662 \param len
4663 Maximum number of code points to use for the sub-string
4665 \return
4666 A String object containing the specified sub-string.
4668 \exception std::out_of_range Thrown if \a idx is invalid for this String.
4670 String substr(size_type idx = 0, size_type len = npos) const
4672 if (d_cplength < idx)
4673 throw std::out_of_range("Index is out of range for this CEGUI::String");
4675 return String(*this, idx, len);
4678 //////////////////////////////////////////////////////////////////////////
4679 // Iterator creation
4680 //////////////////////////////////////////////////////////////////////////
4682 \brief
4683 Return a forwards iterator that describes the beginning of the String
4685 \return
4686 iterator object that describes the beginning of the String.
4688 iterator begin(void)
4690 return iterator(ptr());
4694 \brief
4695 Return a constant forwards iterator that describes the beginning of the String
4697 \return
4698 const_iterator object that describes the beginning of the String.
4700 const_iterator begin(void) const
4702 return const_iterator(ptr());
4706 \brief
4707 Return a forwards iterator that describes the end of the String
4709 \return
4710 iterator object that describes the end of the String.
4712 iterator end(void)
4714 return iterator(&ptr()[d_cplength]);
4718 \brief
4719 Return a constant forwards iterator that describes the end of the String
4721 \return
4722 const_iterator object that describes the end of the String.
4724 const_iterator end(void) const
4726 return const_iterator(&ptr()[d_cplength]);
4730 \brief
4731 Return a reverse iterator that describes the beginning of the String
4733 \return
4734 reverse_iterator object that describes the beginning of the String (so is actually at the end)
4736 reverse_iterator rbegin(void)
4738 return reverse_iterator(end());
4742 \brief
4743 Return a constant reverse iterator that describes the beginning of the String
4745 \return
4746 const_reverse_iterator object that describes the beginning of the String (so is actually at the end)
4748 const_reverse_iterator rbegin(void) const
4750 return const_reverse_iterator(end());
4754 \brief
4755 Return a reverse iterator that describes the end of the String
4757 \return
4758 reverse_iterator object that describes the end of the String (so is actually at the beginning)
4760 reverse_iterator rend(void)
4762 return reverse_iterator(begin());
4766 \brief
4767 Return a constant reverse iterator that describes the end of the String
4769 \return
4770 const_reverse_iterator object that describes the end of the String (so is actually at the beginning)
4772 const_reverse_iterator rend(void) const
4774 return const_reverse_iterator(begin());
4777 private:
4778 /*************************************************************************
4779 Implementation Functions
4780 *************************************************************************/
4781 // string management
4783 // change size of allocated buffer so it is at least 'new_size'.
4784 // May or may not cause re-allocation and copy of buffer if size is larger
4785 // will never re-allocate to make size smaller. (see trim())
4786 bool grow(size_type new_size);
4788 // perform re-allocation to remove wasted space.
4789 void trim(void);
4791 // set the length of the string, and terminate it, according to the given value (will not re-allocate, use grow() first).
4792 void setlen(size_type len)
4794 d_cplength = len;
4795 ptr()[len] = (utf32)(0);
4798 // initialise string object
4799 void init(void)
4801 d_reserve = STR_QUICKBUFF_SIZE;
4802 d_encodedbuff = 0;
4803 d_encodedbufflen = 0;
4804 d_encodeddatlen = 0;
4805 setlen(0);
4808 // return true if the given pointer is inside the string data
4809 bool inside(utf32* inptr)
4811 if (inptr < ptr() || ptr() + d_cplength <= inptr)
4812 return false;
4813 else
4814 return true;
4817 // compute distance between two iterators, returning a 'safe' value
4818 size_type safe_iter_dif(const const_iterator& iter1, const const_iterator& iter2) const
4820 return (iter1.d_ptr == 0) ? 0 : (iter1 - iter2);
4823 // encoding functions
4824 // for all:
4825 // src_len is in code units, or 0 for null terminated string.
4826 // dest_len is in code units.
4827 // returns number of code units put into dest buffer.
4828 size_type encode(const utf32* src, utf8* dest, size_type dest_len, size_type src_len = 0) const
4830 // count length for null terminated source...
4831 if (src_len == 0)
4833 src_len = utf_length(src);
4836 size_type destCapacity = dest_len;
4838 // while there is data in the source buffer,
4839 for (uint idx = 0; idx < src_len; ++idx)
4841 utf32 cp = src[idx];
4843 // check there is enough destination buffer to receive this encoded unit (exit loop & return if not)
4844 if (destCapacity < encoded_size(cp))
4846 break;
4849 if (cp < 0x80)
4851 *dest++ = (utf8)cp;
4852 --destCapacity;
4854 else if (cp < 0x0800)
4856 *dest++ = (utf8)((cp >> 6) | 0xC0);
4857 *dest++ = (utf8)((cp & 0x3F) | 0x80);
4858 destCapacity -= 2;
4860 else if (cp < 0x10000)
4862 *dest++ = (utf8)((cp >> 12) | 0xE0);
4863 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4864 *dest++ = (utf8)((cp & 0x3F) | 0x80);
4865 destCapacity -= 3;
4867 else
4869 *dest++ = (utf8)((cp >> 18) | 0xF0);
4870 *dest++ = (utf8)(((cp >> 12) & 0x3F) | 0x80);
4871 *dest++ = (utf8)(((cp >> 6) & 0x3F) | 0x80);
4872 *dest++ = (utf8)((cp & 0x3F) | 0x80);
4873 destCapacity -= 4;
4878 return dest_len - destCapacity;
4881 size_type encode(const utf8* src, utf32* dest, size_type dest_len, size_type src_len = 0) const
4883 // count length for null terminated source...
4884 if (src_len == 0)
4886 src_len = utf_length(src);
4889 size_type destCapacity = dest_len;
4891 // while there is data in the source buffer, and space in the dest buffer
4892 for (uint idx = 0; ((idx < src_len) && (destCapacity > 0));)
4894 utf32 cp;
4895 utf8 cu = src[idx++];
4897 if (cu < 0x80)
4899 cp = (utf32)(cu);
4901 else if (cu < 0xE0)
4903 cp = ((cu & 0x1F) << 6);
4904 cp |= (src[idx++] & 0x3F);
4906 else if (cu < 0xF0)
4908 cp = ((cu & 0x0F) << 12);
4909 cp |= ((src[idx++] & 0x3F) << 6);
4910 cp |= (src[idx++] & 0x3F);
4912 else
4914 cp = ((cu & 0x07) << 18);
4915 cp |= ((src[idx++] & 0x3F) << 12);
4916 cp |= ((src[idx++] & 0x3F) << 6);
4917 cp |= (src[idx++] & 0x3F);
4920 *dest++ = cp;
4921 --destCapacity;
4924 return dest_len - destCapacity;
4927 // return the number of utf8 code units required to encode the given utf32 code point
4928 size_type encoded_size(utf32 code_point) const
4930 if (code_point < 0x80)
4931 return 1;
4932 else if (code_point < 0x0800)
4933 return 2;
4934 else if (code_point < 0x10000)
4935 return 3;
4936 else
4937 return 4;
4940 // return number of code units required to re-encode given null-terminated utf32 data as utf8. return does not include terminating null.
4941 size_type encoded_size(const utf32* buf) const
4943 return encoded_size(buf, utf_length(buf));
4946 // return number of code units required to re-encode given utf32 data as utf8. len is number of code units in 'buf'.
4947 size_type encoded_size(const utf32* buf, size_type len) const
4949 size_type count = 0;
4951 while (len--)
4953 count += encoded_size(*buf++);
4956 return count;
4959 // return number of utf32 code units required to re-encode given utf8 data as utf32. return does not include terminating null.
4960 size_type encoded_size(const utf8* buf) const
4962 return encoded_size(buf, utf_length(buf));
4965 // return number of utf32 code units required to re-encode given utf8 data as utf32. len is number of code units in 'buf'.
4966 size_type encoded_size(const utf8* buf, size_type len) const
4968 utf8 tcp;
4969 size_type count = 0;
4971 while (len--)
4973 tcp = *buf++;
4974 ++count;
4976 if (tcp < 0x80)
4979 else if (tcp < 0xE0)
4981 --len;
4982 ++buf;
4984 else if (tcp < 0xF0)
4986 len -= 2;
4987 buf += 2;
4989 else
4991 len -= 2;
4992 buf += 3;
4997 return count;
5000 // return number of code units in a null terminated string
5001 size_type utf_length(const utf8* utf8_str) const
5003 size_type cnt = 0;
5004 while (*utf8_str++)
5005 cnt++;
5007 return cnt;
5010 // return number of code units in a null terminated string
5011 size_type utf_length(const utf32* utf32_str) const
5013 size_type cnt = 0;
5014 while (*utf32_str++)
5015 cnt++;
5017 return cnt;
5020 // build an internal buffer with the string encoded as utf8 (remains valid until string is modified).
5021 utf8* build_utf8_buff(void) const;
5023 // compare two utf32 buffers
5024 int utf32_comp_utf32(const utf32* buf1, const utf32* buf2, size_type cp_count) const
5026 if (!cp_count)
5027 return 0;
5029 while ((--cp_count) && (*buf1 == *buf2))
5030 buf1++, buf2++;
5032 return *buf1 - *buf2;
5035 // compare utf32 buffer with char buffer (chars are taken to be code-points in the range 0x00-0xFF)
5036 int utf32_comp_char(const utf32* buf1, const char* buf2, size_type cp_count) const
5038 if (!cp_count)
5039 return 0;
5041 while ((--cp_count) && (*buf1 == static_cast<utf32>(static_cast<unsigned char>(*buf2))))
5042 buf1++, buf2++;
5044 return *buf1 - static_cast<utf32>(static_cast<unsigned char>(*buf2));
5047 // compare utf32 buffer with encoded utf8 data
5048 int utf32_comp_utf8(const utf32* buf1, const utf8* buf2, size_type cp_count) const
5050 if (!cp_count)
5051 return 0;
5053 utf32 cp;
5054 utf8 cu;
5058 cu = *buf2++;
5060 if (cu < 0x80)
5062 cp = (utf32)(cu);
5064 else if (cu < 0xE0)
5066 cp = ((cu & 0x1F) << 6);
5067 cp |= (*buf2++ & 0x3F);
5069 else if (cu < 0xF0)
5071 cp = ((cu & 0x0F) << 12);
5072 cp |= ((*buf2++ & 0x3F) << 6);
5073 cp |= (*buf2++ & 0x3F);
5075 else
5077 cp = ((cu & 0x07) << 18);
5078 cp |= ((*buf2++ & 0x3F) << 12);
5079 cp |= ((*buf2++ & 0x3F) << 6);
5080 cp |= (*buf2++ & 0x3F);
5083 } while ((*buf1++ == cp) && (--cp_count));
5085 return (*--buf1) - cp;
5088 // return index of first occurrence of 'code_point' in std::string 'str', or npos if none
5089 size_type find_codepoint(const std::string& str, utf32 code_point) const
5091 size_type idx = 0, sze = (size_type)str.size();
5093 while (idx != sze)
5095 if (code_point == static_cast<utf32>(static_cast<unsigned char>(str[idx])))
5096 return idx;
5098 ++idx;
5101 return npos;
5104 // return index of first occurrence of 'code_point' in utf8 encoded string 'str', or npos if none. len is in code points.
5105 size_type find_codepoint(const utf8* str, size_type len, utf32 code_point) const
5107 size_type idx = 0;
5109 utf32 cp;
5110 utf8 cu;
5112 while (idx != len) {
5113 cu = *str++;
5115 if (cu < 0x80)
5117 cp = (utf32)(cu);
5119 else if (cu < 0xE0)
5121 cp = ((cu & 0x1F) << 6);
5122 cp |= (*str++ & 0x3F);
5124 else if (cu < 0xF0)
5126 cp = ((cu & 0x0F) << 12);
5127 cp |= ((*str++ & 0x3F) << 6);
5128 cp |= (*str++ & 0x3F);
5130 else
5132 cp = ((cu & 0x07) << 18);
5133 cp |= ((*str++ & 0x3F) << 12);
5134 cp |= ((*str++ & 0x3F) << 6);
5135 cp |= (*str++ & 0x3F);
5138 if (code_point == cp)
5139 return idx;
5141 ++idx;
5144 return npos;
5148 // return index of first occurrence of 'code_point' in char array 'chars', or npos if none
5149 size_type find_codepoint(const char* chars, size_type chars_len, utf32 code_point) const
5151 for (size_type idx = 0; idx != chars_len; ++idx)
5153 if (code_point == static_cast<utf32>(static_cast<unsigned char>(chars[idx])))
5154 return idx;
5157 return npos;
5163 //////////////////////////////////////////////////////////////////////////
5164 // Comparison operators
5165 //////////////////////////////////////////////////////////////////////////
5167 \brief
5168 Return true if String \a str1 is equal to String \a str2
5170 bool CEGUIEXPORT operator==(const String& str1, const String& str2);
5173 \brief
5174 Return true if String \a str is equal to std::string \a std_str
5176 bool CEGUIEXPORT operator==(const String& str, const std::string& std_str);
5179 \brief
5180 Return true if String \a str is equal to std::string \a std_str
5182 bool CEGUIEXPORT operator==(const std::string& std_str, const String& str);
5185 \brief
5186 Return true if String \a str is equal to null-terminated utf8 data \a utf8_str
5188 bool CEGUIEXPORT operator==(const String& str, const utf8* utf8_str);
5191 \brief
5192 Return true if String \a str is equal to null-terminated utf8 data \a utf8_str
5194 bool CEGUIEXPORT operator==(const utf8* utf8_str, const String& str);
5197 \brief
5198 Return true if String \a str1 is not equal to String \a str2
5200 bool CEGUIEXPORT operator!=(const String& str1, const String& str2);
5203 \brief
5204 Return true if String \a str is not equal to std::string \a std_str
5206 bool CEGUIEXPORT operator!=(const String& str, const std::string& std_str);
5209 \brief
5210 Return true if String \a str is not equal to std::string \a std_str
5212 bool CEGUIEXPORT operator!=(const std::string& std_str, const String& str);
5215 \brief
5216 Return true if String \a str is not equal to null-terminated utf8 data \a utf8_str
5218 bool CEGUIEXPORT operator!=(const String& str, const utf8* utf8_str);
5221 \brief
5222 Return true if String \a str is not equal to null-terminated utf8 data \a utf8_str
5224 bool CEGUIEXPORT operator!=(const utf8* utf8_str, const String& str);
5227 \brief
5228 Return true if String \a str1 is lexicographically less than String \a str2
5230 bool CEGUIEXPORT operator<(const String& str1, const String& str2);
5233 \brief
5234 Return true if String \a str is lexicographically less than std::string \a std_str
5236 bool CEGUIEXPORT operator<(const String& str, const std::string& std_str);
5239 \brief
5240 Return true if String \a str is lexicographically less than std::string \a std_str
5242 bool CEGUIEXPORT operator<(const std::string& std_str, const String& str);
5245 \brief
5246 Return true if String \a str is lexicographically less than null-terminated utf8 data \a utf8_str
5248 bool CEGUIEXPORT operator<(const String& str, const utf8* utf8_str);
5251 \brief
5252 Return true if String \a str is lexicographically less than null-terminated utf8 data \a utf8_str
5254 bool CEGUIEXPORT operator<(const utf8* utf8_str, const String& str);
5257 \brief
5258 Return true if String \a str1 is lexicographically greater than String \a str2
5260 bool CEGUIEXPORT operator>(const String& str1, const String& str2);
5263 \brief
5264 Return true if String \a str is lexicographically greater than std::string \a std_str
5266 bool CEGUIEXPORT operator>(const String& str, const std::string& std_str);
5269 \brief
5270 Return true if String \a str is lexicographically greater than std::string \a std_str
5272 bool CEGUIEXPORT operator>(const std::string& std_str, const String& str);
5275 \brief
5276 Return true if String \a str is lexicographically greater than null-terminated utf8 data \a utf8_str
5278 bool CEGUIEXPORT operator>(const String& str, const utf8* utf8_str);
5281 \brief
5282 Return true if String \a str is lexicographically greater than null-terminated utf8 data \a utf8_str
5284 bool CEGUIEXPORT operator>(const utf8* utf8_str, const String& str);
5287 \brief
5288 Return true if String \a str1 is lexicographically less than or equal to String \a str2
5290 bool CEGUIEXPORT operator<=(const String& str1, const String& str2);
5293 \brief
5294 Return true if String \a str is lexicographically less than or equal to std::string \a std_str
5296 bool CEGUIEXPORT operator<=(const String& str, const std::string& std_str);
5299 \brief
5300 Return true if String \a str is lexicographically less than or equal to std::string \a std_str
5302 bool CEGUIEXPORT operator<=(const std::string& std_str, const String& str);
5305 \brief
5306 Return true if String \a str is lexicographically less than or equal to null-terminated utf8 data \a utf8_str
5308 bool CEGUIEXPORT operator<=(const String& str, const utf8* utf8_str);
5311 \brief
5312 Return true if String \a str is lexicographically less than or equal to null-terminated utf8 data \a utf8_str
5314 bool CEGUIEXPORT operator<=(const utf8* utf8_str, const String& str);
5317 \brief
5318 Return true if String \a str1 is lexicographically greater than or equal to String \a str2
5320 bool CEGUIEXPORT operator>=(const String& str1, const String& str2);
5323 \brief
5324 Return true if String \a str is lexicographically greater than or equal to std::string \a std_str
5326 bool CEGUIEXPORT operator>=(const String& str, const std::string& std_str);
5329 \brief
5330 Return true if String \a str is lexicographically greater than or equal to std::string \a std_str
5332 bool CEGUIEXPORT operator>=(const std::string& std_str, const String& str);
5335 \brief
5336 Return true if String \a str is lexicographically greater than or equal to null-terminated utf8 data \a utf8_str
5338 bool CEGUIEXPORT operator>=(const String& str, const utf8* utf8_str);
5341 \brief
5342 Return true if String \a str is lexicographically greater than or equal to null-terminated utf8 data \a utf8_str
5344 bool CEGUIEXPORT operator>=(const utf8* utf8_str, const String& str);
5347 \brief
5348 Return true if String \a str is equal to c-string \a c_str
5350 bool CEGUIEXPORT operator==(const String& str, const char* c_str);
5353 \brief
5354 Return true if c-string \a c_str is equal to String \a str
5356 bool CEGUIEXPORT operator==(const char* c_str, const String& str);
5359 \brief
5360 Return true if String \a str is not equal to c-string \a c_str
5362 bool CEGUIEXPORT operator!=(const String& str, const char* c_str);
5365 \brief
5366 Return true if c-string \a c_str is not equal to String \a str
5368 bool CEGUIEXPORT operator!=(const char* c_str, const String& str);
5371 \brief
5372 Return true if String \a str is lexicographically less than c-string \a c_str
5374 bool CEGUIEXPORT operator<(const String& str, const char* c_str);
5377 \brief
5378 Return true if c-string \a c_str is lexicographically less than String \a str
5380 bool CEGUIEXPORT operator<(const char* c_str, const String& str);
5383 \brief
5384 Return true if String \a str is lexicographically greater than c-string \a c_str
5386 bool CEGUIEXPORT operator>(const String& str, const char* c_str);
5389 \brief
5390 Return true if c-string \a c_str is lexicographically greater than String \a str
5392 bool CEGUIEXPORT operator>(const char* c_str, const String& str);
5395 \brief
5396 Return true if String \a str is lexicographically less than or equal to c-string \a c_str
5398 bool CEGUIEXPORT operator<=(const String& str, const char* c_str);
5401 \brief
5402 Return true if c-string \a c_str is lexicographically less than or equal to String \a str
5404 bool CEGUIEXPORT operator<=(const char* c_str, const String& str);
5407 \brief
5408 Return true if String \a str is lexicographically greater than or equal to c-string \a c_str
5410 bool CEGUIEXPORT operator>=(const String& str, const char* c_str);
5413 \brief
5414 Return true if c-string \a c_str is lexicographically greater than or equal to String \a str
5416 bool CEGUIEXPORT operator>=(const char* c_str, const String& str);
5418 //////////////////////////////////////////////////////////////////////////
5419 // Concatenation operator functions
5420 //////////////////////////////////////////////////////////////////////////
5422 \brief
5423 Return String object that is the concatenation of the given inputs
5425 \param str1
5426 String object describing first part of the new string
5428 \param str2
5429 String object describing the second part of the new string
5431 \return
5432 A String object that is the concatenation of \a str1 and \a str2
5434 \exception std::length_error Thrown if the resulting String would be too large.
5436 String CEGUIEXPORT operator+(const String& str1, const String& str2);
5439 \brief
5440 Return String object that is the concatenation of the given inputs
5442 \param str
5443 String object describing first part of the new string
5445 \param std_str
5446 std::string object describing the second part of the new string
5448 \return
5449 A String object that is the concatenation of \a str and \a std_str
5451 \exception std::length_error Thrown if the resulting String would be too large.
5453 String CEGUIEXPORT operator+(const String& str, const std::string& std_str);
5456 \brief
5457 Return String object that is the concatenation of the given inputs
5459 \param std_str
5460 std::string object describing the first part of the new string
5462 \param str
5463 String object describing the second part of the new string
5465 \return
5466 A String object that is the concatenation of \a std_str and \a str
5468 \exception std::length_error Thrown if the resulting String would be too large.
5470 String CEGUIEXPORT operator+(const std::string& std_str, const String& str);
5473 \brief
5474 Return String object that is the concatenation of the given inputs
5476 \param str
5477 String object describing first part of the new string
5479 \param utf8_str
5480 Buffer containing null-terminated utf8 encoded data describing the second part of the new string
5482 \return
5483 A String object that is the concatenation of \a str and \a utf8_str
5485 \exception std::length_error Thrown if the resulting String would be too large.
5487 String CEGUIEXPORT operator+(const String& str, const utf8* utf8_str);
5490 \brief
5491 Return String object that is the concatenation of the given inputs
5493 \param utf8_str
5494 Buffer containing null-terminated utf8 encoded data describing the first part of the new string
5496 \param str
5497 String object describing the second part of the new string
5499 \return
5500 A String object that is the concatenation of \a str and \a utf8_str
5502 \exception std::length_error Thrown if the resulting String would be too large.
5504 String CEGUIEXPORT operator+(const utf8* utf8_str, const String& str);
5507 \brief
5508 Return String object that is the concatenation of the given inputs
5510 \param str
5511 String object describing the first part of the new string
5513 \param code_point
5514 utf32 code point describing the second part of the new string
5516 \return
5517 A String object that is the concatenation of \a str and \a code_point
5519 \exception std::length_error Thrown if the resulting String would be too large.
5521 String CEGUIEXPORT operator+(const String& str, utf32 code_point);
5524 \brief
5525 Return String object that is the concatenation of the given inputs
5527 \param code_point
5528 utf32 code point describing the first part of the new string
5530 \param str
5531 String object describing the second part of the new string
5533 \return
5534 A String object that is the concatenation of \a code_point and \a str
5536 \exception std::length_error Thrown if the resulting String would be too large.
5538 String CEGUIEXPORT operator+(utf32 code_point, const String& str);
5541 \brief
5542 Return String object that is the concatenation of the given inputs
5544 \param str
5545 String object describing first part of the new string
5547 \param c_str
5548 c-string describing the second part of the new string
5550 \return
5551 A String object that is the concatenation of \a str and \a c_str
5553 \exception std::length_error Thrown if the resulting String would be too large.
5555 String CEGUIEXPORT operator+(const String& str, const char* c_str);
5558 \brief
5559 Return String object that is the concatenation of the given inputs
5561 \param c_str
5562 c-string describing the first part of the new string
5564 \param str
5565 String object describing the second part of the new string
5567 \return
5568 A String object that is the concatenation of \a c_str and \a str
5570 \exception std::length_error Thrown if the resulting String would be too large.
5572 String CEGUIEXPORT operator+(const char* c_str, const String& str);
5575 //////////////////////////////////////////////////////////////////////////
5576 // Output (stream) functions
5577 //////////////////////////////////////////////////////////////////////////
5578 CEGUIEXPORT std::ostream& operator<<(std::ostream& s, const String& str);
5581 //////////////////////////////////////////////////////////////////////////
5582 // Modifying operations
5583 //////////////////////////////////////////////////////////////////////////
5585 \brief
5586 Swap the contents for two String objects
5588 \param str1
5589 String object who's contents are to be swapped with \a str2
5591 \param str2
5592 String object who's contents are to be swapped with \a str1
5594 \return
5595 Nothing
5597 void CEGUIEXPORT swap(String& str1, String& str2);
5600 } // End of CEGUI namespace section
5603 #endif // end of guard _CEGUIString_h_