From 07fd32da5062ab219218b3d1cae6d79103ad2c3b Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 22 Dec 2022 23:55:35 +0100 Subject: [PATCH] Replace core::string implementation with std::basic_string --- examples/AutomatedTest/main.cpp | 2 + examples/AutomatedTest/test_string.cpp | 5 - include/irrString.h | 978 +++++-------------- include/irrUString.h | 24 +- source/Irrlicht/CLimitReadFile.cpp | 1 + source/Irrlicht/COGLESCoreExtensionHandler.h | 1 + 6 files changed, 248 insertions(+), 763 deletions(-) diff --git a/examples/AutomatedTest/main.cpp b/examples/AutomatedTest/main.cpp index 6fac6f4..e724176 100644 --- a/examples/AutomatedTest/main.cpp +++ b/examples/AutomatedTest/main.cpp @@ -37,8 +37,10 @@ void run_unit_tests() { test_irr_array(); test_irr_string(); } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; test_fail++; } + std::cout << std::endl; } int main(int argc, char *argv[]) diff --git a/examples/AutomatedTest/test_string.cpp b/examples/AutomatedTest/test_string.cpp index bac22cf..a9b35b1 100644 --- a/examples/AutomatedTest/test_string.cpp +++ b/examples/AutomatedTest/test_string.cpp @@ -36,11 +36,6 @@ static void test_basics() // operator= s = stringw(L"abcdef"); UASSERTSTR(s, "abcdef"); - s = stringc("test"); - s = s.c_str(); - UASSERTSTR(s, "test"); - s = s.c_str() + 1; - UASSERTSTR(s, "est"); s = L"abcdef"; UASSERTSTR(s, "abcdef"); s = static_cast(nullptr); diff --git a/include/irrString.h b/include/irrString.h index 0742e0b..d62eeee 100644 --- a/include/irrString.h +++ b/include/irrString.h @@ -6,12 +6,11 @@ #define __IRR_STRING_H_INCLUDED__ #include "irrTypes.h" -#include "irrAllocator.h" -#include "irrMath.h" -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace irr { @@ -34,11 +33,10 @@ outside the string class for explicit use. */ // forward declarations -template > +template class string; static size_t multibyteToWString(string& destination, const char* source, u32 sourceSize); static size_t wStringToMultibyte(string& destination, const wchar_t* source, u32 sourceSize); -//inline bool isdigit(s32 c); //! Returns a character converted to lower case static inline u32 locale_lower ( u32 x ) @@ -55,7 +53,7 @@ static inline u32 locale_upper ( u32 x ) } -template +template class string { public: @@ -64,24 +62,18 @@ public: //! Default constructor string() - : array(0), allocated(1), used(1) - { - array = allocator.allocate(1); // new T[1]; - array[0] = 0; - } + {} - //! Constructor - string(const string& other) - : array(0), allocated(0), used(0) + //! Copy constructor + string(const string& other) { *this = other; } //! Constructor from other string types - template - string(const string& other) - : array(0), allocated(0), used(0) + template + string(const string& other) { *this = other; } @@ -89,198 +81,57 @@ public: //! Constructs a string from a float explicit string(const double number) - : array(0), allocated(0), used(0) { - c8 tmpbuf[255]; - snprintf_irr(tmpbuf, 255, "%0.6f", number); - *this = tmpbuf; + c8 tmpbuf[32]; + snprintf_irr(tmpbuf, sizeof(tmpbuf), "%0.6f", number); + str = tmpbuf; } //! Constructs a string from an int explicit string(int number) - : array(0), allocated(0), used(0) { - // store if negative and make positive - - bool negative = false; - if (number < 0) - { - number *= -1; - negative = true; - } - - // temporary buffer for 16 numbers - - c8 tmpbuf[16]={0}; - u32 idx = 15; - - // special case '0' - - if (!number) - { - tmpbuf[14] = '0'; - *this = &tmpbuf[14]; - return; - } - - // add numbers - - while(number && idx) - { - --idx; - tmpbuf[idx] = (c8)('0' + (number % 10)); - number /= 10; - } - - // add sign - - if (negative) - { - --idx; - tmpbuf[idx] = '-'; - } - - *this = &tmpbuf[idx]; + str = std::to_string(number); } //! Constructs a string from an unsigned int explicit string(unsigned int number) - : array(0), allocated(0), used(0) { - // temporary buffer for 16 numbers - - c8 tmpbuf[16]={0}; - u32 idx = 15; - - // special case '0' - - if (!number) - { - tmpbuf[14] = '0'; - *this = &tmpbuf[14]; - return; - } - - // add numbers - - while(number && idx) - { - --idx; - tmpbuf[idx] = (c8)('0' + (number % 10)); - number /= 10; - } - - *this = &tmpbuf[idx]; + str = std::to_string(number); } //! Constructs a string from a long explicit string(long number) - : array(0), allocated(0), used(0) { - // store if negative and make positive - - bool negative = false; - if (number < 0) - { - number *= -1; - negative = true; - } - - // temporary buffer for 16 numbers - - c8 tmpbuf[16]={0}; - u32 idx = 15; - - // special case '0' - - if (!number) - { - tmpbuf[14] = '0'; - *this = &tmpbuf[14]; - return; - } - - // add numbers - - while(number && idx) - { - --idx; - tmpbuf[idx] = (c8)('0' + (number % 10)); - number /= 10; - } - - // add sign - - if (negative) - { - --idx; - tmpbuf[idx] = '-'; - } - - *this = &tmpbuf[idx]; + str = std::to_string(number); } //! Constructs a string from an unsigned long explicit string(unsigned long number) - : array(0), allocated(0), used(0) { - // temporary buffer for 16 numbers - - c8 tmpbuf[16]={0}; - u32 idx = 15; - - // special case '0' - - if (!number) - { - tmpbuf[14] = '0'; - *this = &tmpbuf[14]; - return; - } - - // add numbers - - while(number && idx) - { - --idx; - tmpbuf[idx] = (c8)('0' + (number % 10)); - number /= 10; - } - - *this = &tmpbuf[idx]; + str = std::to_string(number); } //! Constructor for copying a string from a pointer with a given length template string(const B* const c, u32 length) - : array(0), allocated(0), used(0) { if (!c) - { - // correctly init the string to an empty one - *this=""; return; - } - - allocated = used = length+1; - array = allocator.allocate(used); // new T[used]; + str.resize(length); for (u32 l = 0; l string(const B* const c) - : array(0), allocated(0), used(0) { *this = c; } @@ -288,35 +139,22 @@ public: //! Destructor ~string() - { - allocator.deallocate(array); // delete [] array; - } + {} //! Assignment operator - string& operator=(const string& other) + string& operator=(const string& other) { if (this == &other) return *this; - used = other.size()+1; - if (used>allocated) - { - allocator.deallocate(array); // delete [] array; - allocated = used; - array = allocator.allocate(used); //new T[used]; - } - - const T* p = other.c_str(); - for (u32 i=0; i - string& operator=(const string& other) + template + string& operator=(const string& other) { *this = other.c_str(); return *this; @@ -325,137 +163,93 @@ public: //! Assignment operator for strings, ASCII and Unicode template - string& operator=(const B* const c) + string& operator=(const B* const c) { if (!c) { - if (!array) - { - array = allocator.allocate(1); //new T[1]; - allocated = 1; - } - used = 1; - array[0] = 0x0; + clear(); return *this; } - if ((void*)c == (void*)array) - return *this; - - u32 len = 0; - const B* p = c; - do - { - ++len; - } while(*p++); - - // we'll keep the old string for a while, because the new - // string could be a part of the current string. - T* oldArray = array; - - used = len; - if (used>allocated) - { - allocated = used; - array = allocator.allocate(used); //new T[used]; - } + // no longer allowed! + _IRR_DEBUG_BREAK_IF((void*)c == (void*)c_str()); + u32 len = calclen(c); + str.resize(len); for (u32 l = 0; l operator+(const string& other) const + string operator+(const string& other) const { - string str(*this); - str.append(other); + string tmp(*this); + tmp.append(other); - return str; + return tmp; } //! Append operator for strings, ASCII and Unicode template - string operator+(const B* const c) const + string operator+(const B* const c) const { - string str(*this); - str.append(c); + string tmp(*this); + tmp.append(c); - return str; + return tmp; } //! Direct access operator T& operator [](const u32 index) { - _IRR_DEBUG_BREAK_IF(index>=used) // bad index - return array[index]; + return str[index]; } //! Direct access operator const T& operator [](const u32 index) const { - _IRR_DEBUG_BREAK_IF(index>=used) // bad index - return array[index]; + return str[index]; } //! Equality operator - bool operator==(const T* const str) const + bool operator==(const T* const other) const { - if (!str) + if (!other) return false; - - u32 i; - for (i=0; array[i] && str[i]; ++i) - if (array[i] != str[i]) - return false; - - return (!array[i] && !str[i]); + return !cmp(c_str(), other); } //! Equality operator - bool operator==(const string& other) const + bool operator==(const string& other) const { - for (u32 i=0; array[i] && other.array[i]; ++i) - if (array[i] != other.array[i]) - return false; - - return used == other.used; + return str == other.str; } //! Is smaller comparator - bool operator<(const string& other) const + bool operator<(const string& other) const { - for (u32 i=0; array[i] && other.array[i]; ++i) - { - const s32 diff = array[i] - other.array[i]; - if (diff) - return (diff < 0); - } - - return (used < other.used); + return str < other.str; } //! Inequality operator - bool operator!=(const T* const str) const + bool operator!=(const T* const other) const { - return !(*this == str); + return !(*this == other); } //! Inequality operator - bool operator!=(const string& other) const + bool operator!=(const string& other) const { return !(*this == other); } @@ -466,48 +260,50 @@ public: the trailing NUL. */ u32 size() const { - return used-1; + return str.size(); } //! Informs if the string is empty or not. //! \return True if the string is empty, false if not. bool empty() const { - return (size() == 0); + return str.empty(); } void clear(bool releaseMemory=true) { - if ( releaseMemory ) - { - reallocate(1); + if (releaseMemory) { + stl_type empty; + std::swap(str, empty); + } else { + str.clear(); } - array[0] = 0; - used = 1; } //! Returns character string /** \return pointer to C-style NUL terminated string. */ const T* c_str() const { - return array; + return str.c_str(); } //! Makes the string lower case. - string& make_lower() + string& make_lower() { - for (u32 i=0; array[i]; ++i) - array[i] = locale_lower ( array[i] ); + std::transform(str.begin(), str.end(), str.begin(), [](const T& c) { + return locale_lower(c); + }); return *this; } //! Makes the string upper case. - string& make_upper() + string& make_upper() { - for (u32 i=0; array[i]; ++i) - array[i] = locale_upper ( array[i] ); + std::transform(str.begin(), str.end(), str.begin(), [](const T& c) { + return locale_upper(c); + }); return *this; } @@ -515,27 +311,29 @@ public: //! Compares the strings ignoring case. /** \param other: Other string to compare. \return True if the strings are equal ignoring case. */ - bool equals_ignore_case(const string& other) const + bool equals_ignore_case(const string& other) const { + const T* array = c_str(); for(u32 i=0; array[i] && other[i]; ++i) - if (locale_lower( array[i]) != locale_lower(other[i])) + if (locale_lower(array[i]) != locale_lower(other[i])) return false; - return used == other.used; + return size() == other.size(); } //! Compares the strings ignoring case. /** \param other: Other string to compare. \param sourcePos: where to start to compare in the string \return True if the strings are equal ignoring case. */ - bool equals_substring_ignore_case(const string&other, const s32 sourcePos = 0 ) const + bool equals_substring_ignore_case(const string&other, const u32 sourcePos = 0 ) const { - if ( (u32) sourcePos >= used ) + if ( sourcePos >= size() + 1 ) return false; + const T* array = c_str(); u32 i; - for( i=0; array[sourcePos + i] && other[i]; ++i) - if (locale_lower( array[sourcePos + i]) != locale_lower(other[i])) + for(i=0; array[sourcePos + i] && other[i]; ++i) + if (locale_lower(array[sourcePos + i]) != locale_lower(other[i])) return false; return array[sourcePos + i] == 0 && other[i] == 0; @@ -545,16 +343,17 @@ public: //! Compares the strings ignoring case. /** \param other: Other string to compare. \return True if this string is smaller ignoring case. */ - bool lower_ignore_case(const string& other) const + bool lower_ignore_case(const string& other) const { - for(u32 i=0; array[i] && other.array[i]; ++i) + const T* array = c_str(); + for(u32 i=0; array[i] && other[i]; ++i) { - s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] ); + s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other[i] ); if ( diff ) return diff < 0; } - return used < other.used; + return size() < other.size(); } @@ -562,8 +361,9 @@ public: /** \param other Other string to compare. \param n Number of characters to compare \return True if the n first characters of both strings are equal. */ - bool equalsn(const string& other, u32 n) const + bool equalsn(const string& other, u32 n) const { + const T* array = c_str(); u32 i; for(i=0; i < n && array[i] && other[i]; ++i) if (array[i] != other[i]) @@ -571,7 +371,7 @@ public: // if one (or both) of the strings was smaller then they // are only equal if they have the same length - return (i == n) || (used == other.used); + return (i == n) || (size() == other.size()); } @@ -579,33 +379,27 @@ public: /** \param str Other string to compare. \param n Number of characters to compare \return True if the n first characters of both strings are equal. */ - bool equalsn(const T* const str, u32 n) const + bool equalsn(const T* const other, u32 n) const { - if (!str) + if (!other) return false; + const T* array = c_str(); u32 i; - for(i=0; i < n && array[i] && str[i]; ++i) - if (array[i] != str[i]) + for(i=0; i < n && array[i] && other[i]; ++i) + if (array[i] != other[i]) return false; // if one (or both) of the strings was smaller then they // are only equal if they have the same length - return (i == n) || (array[i] == 0 && str[i] == 0); + return (i == n) || (array[i] == 0 && other[i] == 0); } //! Appends a character to this string /** \param character: Character to append. */ - string& append(T character) + string& append(T character) { - if (used + 1 > allocated) - reallocate(used + 1); - - ++used; - - array[used-2] = character; - array[used-1] = 0; - + str.append(1, character); return *this; } @@ -613,55 +407,25 @@ public: //! Appends a char string to this string /** \param other: Char string to append. */ /** \param length: The length of the string to append. */ - string& append(const T* const other, u32 length=0xffffffff) + string& append(const T* const other, u32 length=0xffffffff) { if (!other) return *this; - u32 len = 0; - const T* p = other; - while(*p) - { - ++len; - ++p; - } + u32 len = calclen(other); if (len > length) len = length; - if (used + len > allocated) - reallocate(used + len); - - --used; - ++len; - - for (u32 l=0; l& append(const string& other) + string& append(const string& other) { - if (other.size() == 0) - return *this; - - --used; - const u32 len = other.size()+1; - - if (used + len > allocated) - reallocate(used + len); - - for (u32 l=0; l& append(const string& other, u32 length) + string& append(const string& other, u32 length) { - if (other.size() == 0) - return *this; - if (other.size() < length) - { append(other); - return *this; - } - - if (used + length > allocated) - reallocate(used + length); - - --used; - - for (u32 l=0; l& insert(u32 pos, const char* s, u32 n) + string& insert(u32 pos, const T* s, u32 n) { - if ( pos < used ) + if ( pos < size()+1 ) { - reserve(used+n); - - // move stuff behind insert point - const u32 end = used+n-1; - for (u32 i=0; i - s32 findFirstCharNotInList(const B* const c, u32 count=1) const + s32 findFirstCharNotInList(const T* const c, u32 count=1) const { if (!c || !count) return -1; - for (u32 i=0; i - s32 findLastCharNotInList(const B* const c, u32 count=1) const + s32 findLastCharNotInList(const T* const c, u32 count=1) const { if (!c || !count) return -1; - for (s32 i=(s32)(used-2); i>=0; --i) - { - u32 j; - for (j=0; j=0; --i) - if (array[i] == c) - return i; - - return -1; + auto r = str.rfind(c, pos_to_stl(start)); + return pos_from_stl(r); } //! finds last occurrence of a character of a list in string @@ -864,12 +561,8 @@ public: if (!c || !count) return -1; - for (s32 i=(s32)used-2; i>=0; --i) - for (u32 j=0; j - s32 find(const B* const str, const u32 start = 0) const + s32 find(const T* const other, const u32 start = 0) const { - if (str && *str) + if (other && *other) { - u32 len = 0; - - while (str[len]) - ++len; - - if (len > used-1) - return -1; - - for (u32 i=start; i=size())) return string(""); - // clamp length to maximal value - if ((length+begin) > size()) - length = size()-begin; - - // accounting for null terminator. - s32 substrAllocLength = length + 1; - string o; - o.reserve(substrAllocLength); - - if ( !make_lower ) - { - for (s32 i=0; i o = str.substr(begin, length); + if (make_lower) + o.make_lower(); return o; } //! Appends a character to this string /** \param c Character to append. */ - string& operator += (T c) + string& operator += (T c) { append(c); return *this; @@ -955,7 +612,7 @@ public: //! Appends a char string to this string /** \param c Char string to append. */ - string& operator += (const T* const c) + string& operator += (const T* const c) { append(c); return *this; @@ -964,7 +621,7 @@ public: //! Appends a string to this string /** \param other String to append. */ - string& operator += (const string& other) + string& operator += (const string& other) { append(other); return *this; @@ -973,54 +630,54 @@ public: //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const int i) + string& operator += (const int i) { - append(string(i)); + append(string(i)); return *this; } //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const unsigned int i) + string& operator += (const unsigned int i) { - append(string(i)); + append(string(i)); return *this; } //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const long i) + string& operator += (const long i) { - append(string(i)); + append(string(i)); return *this; } //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const unsigned long i) + string& operator += (const unsigned long i) { - append(string(i)); + append(string(i)); return *this; } //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const double i) + string& operator += (const double i) { - append(string(i)); + append(string(i)); return *this; } //! Appends a string representation of a number to this string /** \param i Number to append. */ - string& operator += (const float i) + string& operator += (const float i) { - append(string(i)); + append(string(i)); return *this; } @@ -1028,11 +685,9 @@ public: //! Replaces all characters of a special type with another one /** \param toReplace Character to replace. \param replaceWith Character replacing the old one. */ - string& replace(T toReplace, T replaceWith) + string& replace(T toReplace, T replaceWith) { - for (u32 i=0; i& replace(const string& toReplace, const string& replaceWith) + string& replace(const string& toReplace, const string& replaceWith) { - if (toReplace.size() == 0) - return *this; - - const T* other = toReplace.c_str(); - const T* replace = replaceWith.c_str(); - const u32 other_size = toReplace.size(); - const u32 replace_size = replaceWith.size(); - - // Determine the delta. The algorithm will change depending on the delta. - s32 delta = replace_size - other_size; - - // A character for character replace. The string will not shrink or grow. - if (delta == 0) - { - s32 pos = 0; - while ((pos = find(other, pos)) != -1) - { - for (u32 i = 0; i < replace_size; ++i) - array[pos + i] = replace[i]; - ++pos; - } - return *this; - } - - // We are going to be removing some characters. The string will shrink. - if (delta < 0) - { - u32 i = 0; - for (u32 pos = 0; pos < used; ++i, ++pos) - { - // Is this potentially a match? - if (array[pos] == *other) - { - // Check to see if we have a match. - u32 j; - for (j = 0; j < other_size; ++j) - { - if (array[pos + j] != other[j]) - break; - } - - // If we have a match, replace characters. - if (j == other_size) - { - for (j = 0; j < replace_size; ++j) - array[i + j] = replace[j]; - i += replace_size - 1; - pos += other_size - 1; - continue; - } - } - - // No match found, just copy characters. - array[i] = array[pos]; - } - array[i-1] = 0; - used = i; - - return *this; - } - - // We are going to be adding characters, so the string size will increase. - // Count the number of times toReplace exists in the string so we can allocate the new size. - u32 find_count = 0; - s32 pos = 0; - while ((pos = find(other, pos)) != -1) - { - ++find_count; - ++pos; - } - - // Re-allocate the string now, if needed. - u32 len = delta * find_count; - if (used + len > allocated) - reallocate(used + len); - - // Start replacing. - pos = 0; - while ((pos = find(other, pos)) != -1) - { - T* start = array + pos + other_size - 1; - T* ptr = array + used - 1; - T* end = array + delta + used -1; - - // Shift characters to make room for the string. - while (ptr != start) - { - *end = *ptr; - --ptr; - --end; - } - - // Add the new string now. - for (u32 i = 0; i < replace_size; ++i) - array[pos + i] = replace[i]; - - pos += replace_size; - used += delta; - } + size_type pos = 0; + while ((pos = str.find(toReplace.str, pos)) != npos) { + str.replace(pos, toReplace.size(), replaceWith.str); + pos += replaceWith.size(); + } return *this; } - //! Removes characters from a string. + //! Removes a character from a string. /** \param c: Character to remove. */ - string& remove(T c) + string& remove(T c) { - u32 pos = 0; - u32 found = 0; - for (u32 i=0; i& remove(const string& toRemove) + string& remove(const string& toRemove) { u32 size = toRemove.size(); if ( size == 0 ) return *this; u32 pos = 0; u32 found = 0; - for (u32 i=0; i& removeChars(const string & characters) + string& removeChars(const string & characters) { if (characters.size() == 0) return *this; - u32 pos = 0; - u32 found = 0; - for (u32 i=0; i& trim(const string & whitespace = " \t\n\r") + string& trim(const string & whitespace = " \t\n\r") { // find start and end of the substring without the specified characters - const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used); + const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.size()); if (begin == -1) return (*this=""); - const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used); + const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.size()); return (*this = subString(begin, (end +1) - begin)); } -#if 0 - //! Erase 0's at the end when a string ends with a floating point number - /** After generating strings from floats we often end up with strings - ending up with lots of zeros which don't add any value. Erase 'em all. - Examples: "0.100000" becomes "0.1" - "10.000000" becomes "10" - "foo 3.140000" becomes "foo 3.14" - "no_num.000" stays "no_num.000" - "1." stays "1." - */ - string& eraseTrailingFloatZeros(char decimalPoint='.') - { - s32 i=findLastCharNotInList("0", 1); - if ( i > 0 && (u32)i < used-2 ) // non 0 must be found and not last char (also used is at least 2 when i > 0) - { - u32 eraseStart=i+1; - u32 dot=0; - if( core::isdigit(array[i]) ) - { - while( --i>0 && core::isdigit(array[i]) ); - if ( array[i] == decimalPoint ) - dot = i; - } - else if ( array[i] == decimalPoint ) - { - dot = i; - eraseStart = i; - } - if ( dot > 0 && core::isdigit(array[dot-1]) ) - { - array[eraseStart] = 0; - used = eraseStart+1; - } - } - return *this; - } -#endif - //! Erases a character from the string. /** May be slow, because all elements following after the erased element have to be copied. \param index: Index of element to be erased. */ - string& erase(u32 index) + string& erase(u32 index) { - _IRR_DEBUG_BREAK_IF(index>=used) // access violation - - for (u32 i=index+1; i& validate() + string& validate() { - // terminate on existing null - for (u32 i=0; i 0 ) - { - used = allocated; - array[used-1] = 0; - } - else - { - used = 0; - } + // truncate to existing null + u32 len = calclen(c_str()); + if (len != size()) + str.resize(len); return *this; } @@ -1334,7 +800,7 @@ public: //! gets the last char of a string or null T lastChar() const { - return used > 1 ? array[used-2] : 0; + return !str.empty() ? str.back() : 0; } //! Split string into parts (tokens). @@ -1365,19 +831,19 @@ public: const u32 oldSize=ret.size(); u32 tokenStartIdx = 0; - for (u32 i=0; i 0) - ret.push_back(string(&array[tokenStartIdx], i - tokenStartIdx)); + ret.push_back(string(&str[tokenStartIdx], i - tokenStartIdx)); else if ( !ignoreEmptyTokens ) - ret.push_back(string()); + ret.push_back(string()); if ( keepSeparators ) { - ret.push_back(string(&array[i], 1)); + ret.push_back(string(&str[i], 1)); } tokenStartIdx = i+1; @@ -1385,10 +851,10 @@ public: } } } - if ((used - 1) > tokenStartIdx) - ret.push_back(string(&array[tokenStartIdx], (used - 1) - tokenStartIdx)); - else if ( !ignoreEmptyTokens ) - ret.push_back(string()); + if (size() > tokenStartIdx) + ret.push_back(string(&str[tokenStartIdx], size() - tokenStartIdx)); + else if (!ignoreEmptyTokens) + ret.push_back(string()); return ret.size()-oldSize; } @@ -1398,30 +864,52 @@ public: private: - //! Reallocate the array, make it bigger or smaller - void reallocate(u32 new_size) - { - T* old_array = array; - - array = allocator.allocate(new_size); //new T[new_size]; - allocated = new_size; + typedef std::basic_string stl_type; - const u32 amount = used < new_size ? used : new_size; - for (u32 i=0; i + static inline u32 calclen(const U* p) { + u32 len = 0; + while (*p++) + len++; + return len; + } + static inline u32 calclen(const char* p) { + return strlen(p); + } + static inline u32 calclen(const wchar_t* p) { + return wcslen(p); + } - allocator.deallocate(old_array); // delete [] old_array; + //! strcmp wrapper + template + static inline int cmp(const U* p, const U* p2) { + while (*p && *p == *p2) + p++, p2++; + return (int)*p - (int)*p2; + } + static inline int cmp(const char* p, const char* p2) { + return strcmp(p, p2); } + static inline int cmp(const wchar_t* p, const wchar_t* p2) { + return wcscmp(p, p2); + } + + typedef typename stl_type::size_type size_type; + static const size_type npos = stl_type::npos; - //--- member variables + static inline s32 pos_from_stl(size_type pos) { + return pos == npos ? -1 : (s32)pos; + } + static inline size_type pos_to_stl(s32 pos) { + return pos == -1 ? npos : (size_type)pos; + } - T* array; - u32 allocated; - u32 used; - TAlloc allocator; + stl_type str; }; @@ -1459,19 +947,18 @@ static size_t multibyteToWString(string& destination, const char* sourc { if ( sourceSize ) { - destination.reserve(sourceSize+1); + destination.str.resize(sourceSize+1); #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4996) // 'mbstowcs': This function or variable may be unsafe. Consider using mbstowcs_s instead. #endif - const size_t written = mbstowcs(destination.array, source, (size_t)sourceSize); + const size_t written = mbstowcs(&destination[0], source, (size_t)sourceSize); #if defined(_MSC_VER) #pragma warning(pop) #endif if ( written != (size_t)-1 ) { - destination.used = (u32)written+1; - destination.array[destination.used-1] = 0; + destination.str.resize(written); } else { @@ -1506,19 +993,18 @@ static size_t wStringToMultibyte(string& destination, const wchar_t* source, { if ( sourceSize ) { - destination.reserve(sizeof(wchar_t)*sourceSize+1); + destination.str.resize(sizeof(wchar_t)*sourceSize+1); #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead. #endif - const size_t written = wcstombs(destination.array, source, destination.allocated-1); + const size_t written = wcstombs(&destination[0], source, destination.size()); #if defined(_MSC_VER) #pragma warning(pop) #endif if ( written != (size_t)-1 ) { - destination.used = (u32)written+1; - destination.array[destination.used-1] = 0; + destination.str.resize(written); } else { diff --git a/include/irrUString.h b/include/irrUString.h index 49cc670..3e20ff8 100644 --- a/include/irrUString.h +++ b/include/irrUString.h @@ -813,8 +813,8 @@ public: //! Constructor from other string types - template - ustring16(const string& other) + template + ustring16(const string& other) : array(0), allocated(0), used(0) { #if __BYTE_ORDER == __BIG_ENDIAN @@ -1054,8 +1054,8 @@ public: } //! Assignment operator for other string types - template - ustring16& operator=(const string& other) + template + ustring16& operator=(const string& other) { *this = other.c_str(); return *this; @@ -3139,8 +3139,8 @@ inline ustring16 operator+(const B* const left, const ustring16& //! Appends a ustring16 and an Irrlicht string. -template -inline ustring16 operator+(const ustring16& left, const string& right) +template +inline ustring16 operator+(const ustring16& left, const string& right) { ustring16 ret(left); ret += right; @@ -3149,8 +3149,8 @@ inline ustring16 operator+(const ustring16& left, const string -inline ustring16 operator+(const string& left, const ustring16& right) +template +inline ustring16 operator+(const string& left, const ustring16& right) { ustring16 ret(left); ret += right; @@ -3438,8 +3438,8 @@ inline ustring16&& operator+(const B* const left, ustring16&& ri //! Appends a ustring16 and an Irrlicht string. -template -inline ustring16&& operator+(const string& left, ustring16&& right) +template +inline ustring16&& operator+(const string& left, ustring16&& right) { //std::cout << "MOVE operator+(&, &&)" << std::endl; right.insert(left, 0); @@ -3448,8 +3448,8 @@ inline ustring16&& operator+(const string& left, ustring16 -inline ustring16&& operator+(ustring16&& left, const string& right) +template +inline ustring16&& operator+(ustring16&& left, const string& right) { //std::cout << "MOVE operator+(&&, &)" << std::endl; left.append(right); diff --git a/source/Irrlicht/CLimitReadFile.cpp b/source/Irrlicht/CLimitReadFile.cpp index f65b700..5374755 100644 --- a/source/Irrlicht/CLimitReadFile.cpp +++ b/source/Irrlicht/CLimitReadFile.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in irrlicht.h #include "CLimitReadFile.h" +#include "irrMath.h" #include "irrString.h" namespace irr diff --git a/source/Irrlicht/COGLESCoreExtensionHandler.h b/source/Irrlicht/COGLESCoreExtensionHandler.h index 57f156d..a557844 100644 --- a/source/Irrlicht/COGLESCoreExtensionHandler.h +++ b/source/Irrlicht/COGLESCoreExtensionHandler.h @@ -11,6 +11,7 @@ // (this is also the reason why this file is header-only as correct OGL ES headers have to be included first) #if defined(_IRR_COMPILE_WITH_OGLES2_) || defined(_IRR_COMPILE_WITH_OGLES1_) +#include "irrMath.h" #include "COpenGLCoreFeature.h" namespace irr -- 2.44.0