]> git.lizzy.rs Git - irrlicht.git/commitdiff
Replace core::string implementation with std::basic_string
authorsfan5 <sfan5@live.de>
Thu, 22 Dec 2022 22:55:35 +0000 (23:55 +0100)
committersfan5 <sfan5@live.de>
Fri, 23 Dec 2022 18:17:08 +0000 (19:17 +0100)
examples/AutomatedTest/main.cpp
examples/AutomatedTest/test_string.cpp
include/irrString.h
include/irrUString.h
source/Irrlicht/CLimitReadFile.cpp
source/Irrlicht/COGLESCoreExtensionHandler.h

index 6fac6f484014d470cc777f02aecbf6f4d9b0f639..e7241767e0210f1653943a0a3694dacc59753b0c 100644 (file)
@@ -37,8 +37,10 @@ void run_unit_tests() {
                test_irr_array();\r
                test_irr_string();\r
        } catch (const std::exception &e) {\r
+               std::cerr << e.what() << std::endl;\r
                test_fail++;\r
        }\r
+       std::cout << std::endl;\r
 }\r
 \r
 int main(int argc, char *argv[])\r
index bac22cfaeca4d9af7df74a7c6e07f3c9204be5dd..a9b35b1060940e2f1b04064f0232cbdb1b61d863 100644 (file)
@@ -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<const char*>(nullptr);
index 0742e0b869fdcd85e17d89f2368d73a4794d44ad..d62eeee0a67dba126238d5a32490efbce733e416 100644 (file)
@@ -6,12 +6,11 @@
 #define __IRR_STRING_H_INCLUDED__\r
 \r
 #include "irrTypes.h"\r
-#include "irrAllocator.h"\r
-#include "irrMath.h"\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <wchar.h>\r
+#include <string>\r
+#include <algorithm>\r
+#include <cstdio>\r
+#include <cstring>\r
+#include <cwchar>\r
 \r
 namespace irr\r
 {\r
@@ -34,11 +33,10 @@ outside the string class for explicit use.
 */\r
 \r
 // forward declarations\r
-template <typename T, typename TAlloc = irrAllocator<T> >\r
+template <typename T>\r
 class string;\r
 static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);\r
 static size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source, u32 sourceSize);\r
-//inline bool isdigit(s32 c);\r
 \r
 //! Returns a character converted to lower case\r
 static inline u32 locale_lower ( u32 x )\r
@@ -55,7 +53,7 @@ static inline u32 locale_upper ( u32 x )
 }\r
 \r
 \r
-template <typename T, typename TAlloc>\r
+template <typename T>\r
 class string\r
 {\r
 public:\r
@@ -64,24 +62,18 @@ public:
 \r
        //! Default constructor\r
        string()\r
-       : array(0), allocated(1), used(1)\r
-       {\r
-               array = allocator.allocate(1); // new T[1];\r
-               array[0] = 0;\r
-       }\r
+       {}\r
 \r
 \r
-       //! Constructor\r
-       string(const string<T,TAlloc>& other)\r
-       : array(0), allocated(0), used(0)\r
+       //! Copy constructor\r
+       string(const string<T>& other)\r
        {\r
                *this = other;\r
        }\r
 \r
        //! Constructor from other string types\r
-       template <class B, class A>\r
-       string(const string<B, A>& other)\r
-       : array(0), allocated(0), used(0)\r
+       template <class B>\r
+       string(const string<B>& other)\r
        {\r
                *this = other;\r
        }\r
@@ -89,198 +81,57 @@ public:
 \r
        //! Constructs a string from a float\r
        explicit string(const double number)\r
-       : array(0), allocated(0), used(0)\r
        {\r
-               c8 tmpbuf[255];\r
-               snprintf_irr(tmpbuf, 255, "%0.6f", number);\r
-               *this = tmpbuf;\r
+               c8 tmpbuf[32];\r
+               snprintf_irr(tmpbuf, sizeof(tmpbuf), "%0.6f", number);\r
+               str = tmpbuf;\r
        }\r
 \r
 \r
        //! Constructs a string from an int\r
        explicit string(int number)\r
-       : array(0), allocated(0), used(0)\r
        {\r
-               // store if negative and make positive\r
-\r
-               bool negative = false;\r
-               if (number < 0)\r
-               {\r
-                       number *= -1;\r
-                       negative = true;\r
-               }\r
-\r
-               // temporary buffer for 16 numbers\r
-\r
-               c8 tmpbuf[16]={0};\r
-               u32 idx = 15;\r
-\r
-               // special case '0'\r
-\r
-               if (!number)\r
-               {\r
-                       tmpbuf[14] = '0';\r
-                       *this = &tmpbuf[14];\r
-                       return;\r
-               }\r
-\r
-               // add numbers\r
-\r
-               while(number && idx)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = (c8)('0' + (number % 10));\r
-                       number /= 10;\r
-               }\r
-\r
-               // add sign\r
-\r
-               if (negative)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = '-';\r
-               }\r
-\r
-               *this = &tmpbuf[idx];\r
+               str = std::to_string(number);\r
        }\r
 \r
 \r
        //! Constructs a string from an unsigned int\r
        explicit string(unsigned int number)\r
-       : array(0), allocated(0), used(0)\r
        {\r
-               // temporary buffer for 16 numbers\r
-\r
-               c8 tmpbuf[16]={0};\r
-               u32 idx = 15;\r
-\r
-               // special case '0'\r
-\r
-               if (!number)\r
-               {\r
-                       tmpbuf[14] = '0';\r
-                       *this = &tmpbuf[14];\r
-                       return;\r
-               }\r
-\r
-               // add numbers\r
-\r
-               while(number && idx)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = (c8)('0' + (number % 10));\r
-                       number /= 10;\r
-               }\r
-\r
-               *this = &tmpbuf[idx];\r
+               str = std::to_string(number);\r
        }\r
 \r
 \r
        //! Constructs a string from a long\r
        explicit string(long number)\r
-       : array(0), allocated(0), used(0)\r
        {\r
-               // store if negative and make positive\r
-\r
-               bool negative = false;\r
-               if (number < 0)\r
-               {\r
-                       number *= -1;\r
-                       negative = true;\r
-               }\r
-\r
-               // temporary buffer for 16 numbers\r
-\r
-               c8 tmpbuf[16]={0};\r
-               u32 idx = 15;\r
-\r
-               // special case '0'\r
-\r
-               if (!number)\r
-               {\r
-                       tmpbuf[14] = '0';\r
-                       *this = &tmpbuf[14];\r
-                       return;\r
-               }\r
-\r
-               // add numbers\r
-\r
-               while(number && idx)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = (c8)('0' + (number % 10));\r
-                       number /= 10;\r
-               }\r
-\r
-               // add sign\r
-\r
-               if (negative)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = '-';\r
-               }\r
-\r
-               *this = &tmpbuf[idx];\r
+               str = std::to_string(number);\r
        }\r
 \r
 \r
        //! Constructs a string from an unsigned long\r
        explicit string(unsigned long number)\r
-       : array(0), allocated(0), used(0)\r
        {\r
-               // temporary buffer for 16 numbers\r
-\r
-               c8 tmpbuf[16]={0};\r
-               u32 idx = 15;\r
-\r
-               // special case '0'\r
-\r
-               if (!number)\r
-               {\r
-                       tmpbuf[14] = '0';\r
-                       *this = &tmpbuf[14];\r
-                       return;\r
-               }\r
-\r
-               // add numbers\r
-\r
-               while(number && idx)\r
-               {\r
-                       --idx;\r
-                       tmpbuf[idx] = (c8)('0' + (number % 10));\r
-                       number /= 10;\r
-               }\r
-\r
-               *this = &tmpbuf[idx];\r
+               str = std::to_string(number);\r
        }\r
 \r
 \r
        //! Constructor for copying a string from a pointer with a given length\r
        template <class B>\r
        string(const B* const c, u32 length)\r
-       : array(0), allocated(0), used(0)\r
        {\r
                if (!c)\r
-               {\r
-                       // correctly init the string to an empty one\r
-                       *this="";\r
                        return;\r
-               }\r
-\r
-               allocated = used = length+1;\r
-               array = allocator.allocate(used); // new T[used];\r
 \r
+               str.resize(length);\r
                for (u32 l = 0; l<length; ++l)\r
-                       array[l] = (T)c[l];\r
-\r
-               array[length] = 0;\r
+                       str[l] = (T)c[l];\r
        }\r
 \r
 \r
        //! Constructor for Unicode and ASCII strings\r
        template <class B>\r
        string(const B* const c)\r
-       : array(0), allocated(0), used(0)\r
        {\r
                *this = c;\r
        }\r
@@ -288,35 +139,22 @@ public:
 \r
        //! Destructor\r
        ~string()\r
-       {\r
-               allocator.deallocate(array); // delete [] array;\r
-       }\r
+       {}\r
 \r
 \r
        //! Assignment operator\r
-       string<T,TAlloc>& operator=(const string<T,TAlloc>& other)\r
+       string<T>& operator=(const string<T>& other)\r
        {\r
                if (this == &other)\r
                        return *this;\r
 \r
-               used = other.size()+1;\r
-               if (used>allocated)\r
-               {\r
-                       allocator.deallocate(array); // delete [] array;\r
-                       allocated = used;\r
-                       array = allocator.allocate(used); //new T[used];\r
-               }\r
-\r
-               const T* p = other.c_str();\r
-               for (u32 i=0; i<used; ++i, ++p)\r
-                       array[i] = *p;\r
-\r
+               str = other.str;\r
                return *this;\r
        }\r
 \r
        //! Assignment operator for other string types\r
-       template <class B, class A>\r
-       string<T,TAlloc>& operator=(const string<B,A>& other)\r
+       template <class B>\r
+       string<T>& operator=(const string<B>& other)\r
        {\r
                *this = other.c_str();\r
                return *this;\r
@@ -325,137 +163,93 @@ public:
 \r
        //! Assignment operator for strings, ASCII and Unicode\r
        template <class B>\r
-       string<T,TAlloc>& operator=(const B* const c)\r
+       string<T>& operator=(const B* const c)\r
        {\r
                if (!c)\r
                {\r
-                       if (!array)\r
-                       {\r
-                               array = allocator.allocate(1); //new T[1];\r
-                               allocated = 1;\r
-                       }\r
-                       used = 1;\r
-                       array[0] = 0x0;\r
+                       clear();\r
                        return *this;\r
                }\r
 \r
-               if ((void*)c == (void*)array)\r
-                       return *this;\r
-\r
-               u32 len = 0;\r
-               const B* p = c;\r
-               do\r
-               {\r
-                       ++len;\r
-               } while(*p++);\r
-\r
-               // we'll keep the old string for a while, because the new\r
-               // string could be a part of the current string.\r
-               T* oldArray = array;\r
-\r
-               used = len;\r
-               if (used>allocated)\r
-               {\r
-                       allocated = used;\r
-                       array = allocator.allocate(used); //new T[used];\r
-               }\r
+               // no longer allowed!\r
+               _IRR_DEBUG_BREAK_IF((void*)c == (void*)c_str());\r
 \r
+               u32 len = calclen(c);\r
+               str.resize(len);\r
                for (u32 l = 0; l<len; ++l)\r
-                       array[l] = (T)c[l];\r
-\r
-               if (oldArray != array)\r
-                       allocator.deallocate(oldArray); // delete [] oldArray;\r
+                       str[l] = (T)c[l];\r
 \r
                return *this;\r
        }\r
 \r
 \r
        //! Append operator for other strings\r
-       string<T,TAlloc> operator+(const string<T,TAlloc>& other) const\r
+       string<T> operator+(const string<T>& other) const\r
        {\r
-               string<T,TAlloc> str(*this);\r
-               str.append(other);\r
+               string<T> tmp(*this);\r
+               tmp.append(other);\r
 \r
-               return str;\r
+               return tmp;\r
        }\r
 \r
 \r
        //! Append operator for strings, ASCII and Unicode\r
        template <class B>\r
-       string<T,TAlloc> operator+(const B* const c) const\r
+       string<T> operator+(const B* const c) const\r
        {\r
-               string<T,TAlloc> str(*this);\r
-               str.append(c);\r
+               string<T> tmp(*this);\r
+               tmp.append(c);\r
 \r
-               return str;\r
+               return tmp;\r
        }\r
 \r
 \r
        //! Direct access operator\r
        T& operator [](const u32 index)\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // bad index\r
-               return array[index];\r
+               return str[index];\r
        }\r
 \r
 \r
        //! Direct access operator\r
        const T& operator [](const u32 index) const\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // bad index\r
-               return array[index];\r
+               return str[index];\r
        }\r
 \r
 \r
        //! Equality operator\r
-       bool operator==(const T* const str) const\r
+       bool operator==(const T* const other) const\r
        {\r
-               if (!str)\r
+               if (!other)\r
                        return false;\r
-\r
-               u32 i;\r
-               for (i=0; array[i] && str[i]; ++i)\r
-                       if (array[i] != str[i])\r
-                               return false;\r
-\r
-               return (!array[i] && !str[i]);\r
+               return !cmp(c_str(), other);\r
        }\r
 \r
 \r
        //! Equality operator\r
-       bool operator==(const string<T,TAlloc>& other) const\r
+       bool operator==(const string<T>& other) const\r
        {\r
-               for (u32 i=0; array[i] && other.array[i]; ++i)\r
-                       if (array[i] != other.array[i])\r
-                               return false;\r
-\r
-               return used == other.used;\r
+               return str == other.str;\r
        }\r
 \r
 \r
        //! Is smaller comparator\r
-       bool operator<(const string<T,TAlloc>& other) const\r
+       bool operator<(const string<T>& other) const\r
        {\r
-               for (u32 i=0; array[i] && other.array[i]; ++i)\r
-               {\r
-                       const s32 diff = array[i] - other.array[i];\r
-                       if (diff)\r
-                               return (diff < 0);\r
-               }\r
-\r
-               return (used < other.used);\r
+               return str < other.str;\r
        }\r
 \r
 \r
        //! Inequality operator\r
-       bool operator!=(const T* const str) const\r
+       bool operator!=(const T* const other) const\r
        {\r
-               return !(*this == str);\r
+               return !(*this == other);\r
        }\r
 \r
 \r
        //! Inequality operator\r
-       bool operator!=(const string<T,TAlloc>& other) const\r
+       bool operator!=(const string<T>& other) const\r
        {\r
                return !(*this == other);\r
        }\r
@@ -466,48 +260,50 @@ public:
        the trailing NUL. */\r
        u32 size() const\r
        {\r
-               return used-1;\r
+               return str.size();\r
        }\r
 \r
        //! Informs if the string is empty or not.\r
        //! \return True if the string is empty, false if not.\r
        bool empty() const\r
        {\r
-               return (size() == 0);\r
+               return str.empty();\r
        }\r
 \r
        void clear(bool releaseMemory=true)\r
        {\r
-               if ( releaseMemory )\r
-               {\r
-                       reallocate(1);\r
+               if (releaseMemory) {\r
+                       stl_type empty;\r
+                       std::swap(str, empty);\r
+               } else {\r
+                       str.clear();\r
                }\r
-               array[0] = 0;\r
-               used = 1;\r
        }\r
 \r
        //! Returns character string\r
        /** \return pointer to C-style NUL terminated string. */\r
        const T* c_str() const\r
        {\r
-               return array;\r
+               return str.c_str();\r
        }\r
 \r
 \r
        //! Makes the string lower case.\r
-       string<T,TAlloc>& make_lower()\r
+       string<T>& make_lower()\r
        {\r
-               for (u32 i=0; array[i]; ++i)\r
-                       array[i] = locale_lower ( array[i] );\r
+               std::transform(str.begin(), str.end(), str.begin(), [](const T& c) {\r
+                       return locale_lower(c);\r
+               });\r
                return *this;\r
        }\r
 \r
 \r
        //! Makes the string upper case.\r
-       string<T,TAlloc>& make_upper()\r
+       string<T>& make_upper()\r
        {\r
-               for (u32 i=0; array[i]; ++i)\r
-                       array[i] = locale_upper ( array[i] );\r
+               std::transform(str.begin(), str.end(), str.begin(), [](const T& c) {\r
+                       return locale_upper(c);\r
+               });\r
                return *this;\r
        }\r
 \r
@@ -515,27 +311,29 @@ public:
        //! Compares the strings ignoring case.\r
        /** \param other: Other string to compare.\r
        \return True if the strings are equal ignoring case. */\r
-       bool equals_ignore_case(const string<T,TAlloc>& other) const\r
+       bool equals_ignore_case(const string<T>& other) const\r
        {\r
+               const T* array = c_str();\r
                for(u32 i=0; array[i] && other[i]; ++i)\r
-                       if (locale_lower( array[i]) != locale_lower(other[i]))\r
+                       if (locale_lower(array[i]) != locale_lower(other[i]))\r
                                return false;\r
 \r
-               return used == other.used;\r
+               return size() == other.size();\r
        }\r
 \r
        //! Compares the strings ignoring case.\r
        /** \param other: Other string to compare.\r
                \param sourcePos: where to start to compare in the string\r
        \return True if the strings are equal ignoring case. */\r
-       bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const\r
+       bool equals_substring_ignore_case(const string<T>&other, const u32 sourcePos = 0 ) const\r
        {\r
-               if ( (u32) sourcePos >= used )\r
+               if ( sourcePos >= size() + 1 )\r
                        return false;\r
 \r
+               const T* array = c_str();\r
                u32 i;\r
-               for( i=0; array[sourcePos + i] && other[i]; ++i)\r
-                       if (locale_lower( array[sourcePos + i]) != locale_lower(other[i]))\r
+               for(i=0; array[sourcePos + i] && other[i]; ++i)\r
+                       if (locale_lower(array[sourcePos + i]) != locale_lower(other[i]))\r
                                return false;\r
 \r
                return array[sourcePos + i] == 0 && other[i] == 0;\r
@@ -545,16 +343,17 @@ public:
        //! Compares the strings ignoring case.\r
        /** \param other: Other string to compare.\r
        \return True if this string is smaller ignoring case. */\r
-       bool lower_ignore_case(const string<T,TAlloc>& other) const\r
+       bool lower_ignore_case(const string<T>& other) const\r
        {\r
-               for(u32 i=0; array[i] && other.array[i]; ++i)\r
+               const T* array = c_str();\r
+               for(u32 i=0; array[i] && other[i]; ++i)\r
                {\r
-                       s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] );\r
+                       s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other[i] );\r
                        if ( diff )\r
                                return diff < 0;\r
                }\r
 \r
-               return used < other.used;\r
+               return size() < other.size();\r
        }\r
 \r
 \r
@@ -562,8 +361,9 @@ public:
        /** \param other Other string to compare.\r
        \param n Number of characters to compare\r
        \return True if the n first characters of both strings are equal. */\r
-       bool equalsn(const string<T,TAlloc>& other, u32 n) const\r
+       bool equalsn(const string<T>& other, u32 n) const\r
        {\r
+               const T* array = c_str();\r
                u32 i;\r
                for(i=0; i < n && array[i] && other[i]; ++i)\r
                        if (array[i] != other[i])\r
@@ -571,7 +371,7 @@ public:
 \r
                // if one (or both) of the strings was smaller then they\r
                // are only equal if they have the same length\r
-               return (i == n) || (used == other.used);\r
+               return (i == n) || (size() == other.size());\r
        }\r
 \r
 \r
@@ -579,33 +379,27 @@ public:
        /** \param str Other string to compare.\r
        \param n Number of characters to compare\r
        \return True if the n first characters of both strings are equal. */\r
-       bool equalsn(const T* const str, u32 n) const\r
+       bool equalsn(const T* const other, u32 n) const\r
        {\r
-               if (!str)\r
+               if (!other)\r
                        return false;\r
+               const T* array = c_str();\r
                u32 i;\r
-               for(i=0; i < n && array[i] && str[i]; ++i)\r
-                       if (array[i] != str[i])\r
+               for(i=0; i < n && array[i] && other[i]; ++i)\r
+                       if (array[i] != other[i])\r
                                return false;\r
 \r
                // if one (or both) of the strings was smaller then they\r
                // are only equal if they have the same length\r
-               return (i == n) || (array[i] == 0 && str[i] == 0);\r
+               return (i == n) || (array[i] == 0 && other[i] == 0);\r
        }\r
 \r
 \r
        //! Appends a character to this string\r
        /** \param character: Character to append. */\r
-       string<T,TAlloc>& append(T character)\r
+       string<T>& append(T character)\r
        {\r
-               if (used + 1 > allocated)\r
-                       reallocate(used + 1);\r
-\r
-               ++used;\r
-\r
-               array[used-2] = character;\r
-               array[used-1] = 0;\r
-\r
+               str.append(1, character);\r
                return *this;\r
        }\r
 \r
@@ -613,55 +407,25 @@ public:
        //! Appends a char string to this string\r
        /** \param other: Char string to append. */\r
        /** \param length: The length of the string to append. */\r
-       string<T,TAlloc>& append(const T* const other, u32 length=0xffffffff)\r
+       string<T>& append(const T* const other, u32 length=0xffffffff)\r
        {\r
                if (!other)\r
                        return *this;\r
 \r
-               u32 len = 0;\r
-               const T* p = other;\r
-               while(*p)\r
-               {\r
-                       ++len;\r
-                       ++p;\r
-               }\r
+               u32 len = calclen(other);\r
                if (len > length)\r
                        len = length;\r
 \r
-               if (used + len > allocated)\r
-                       reallocate(used + len);\r
-\r
-               --used;\r
-               ++len;\r
-\r
-               for (u32 l=0; l<len; ++l)\r
-                       array[l+used] = *(other+l);\r
-\r
-               used += len;\r
-               array[used-1] = 0;\r
-\r
+               str.append(other, len);\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string to this string\r
        /** \param other: String to append. */\r
-       string<T,TAlloc>& append(const string<T,TAlloc>& other)\r
+       string<T>& append(const string<T>& other)\r
        {\r
-               if (other.size() == 0)\r
-                       return *this;\r
-\r
-               --used;\r
-               const u32 len = other.size()+1;\r
-\r
-               if (used + len > allocated)\r
-                       reallocate(used + len);\r
-\r
-               for (u32 l=0; l<len; ++l)\r
-                       array[used+l] = other[l];\r
-\r
-               used += len;\r
-\r
+               str.append(other.str);\r
                return *this;\r
        }\r
 \r
@@ -669,30 +433,12 @@ public:
        //! Appends a string of the length l to this string.\r
        /** \param other: other String to append to this string.\r
        \param length: How much characters of the other string to add to this one. */\r
-       string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length)\r
+       string<T>& append(const string<T>& other, u32 length)\r
        {\r
-               if (other.size() == 0)\r
-                       return *this;\r
-\r
                if (other.size() < length)\r
-               {\r
                        append(other);\r
-                       return *this;\r
-               }\r
-\r
-               if (used + length > allocated)\r
-                       reallocate(used + length);\r
-\r
-               --used;\r
-\r
-               for (u32 l=0; l<length; ++l)\r
-                       array[l+used] = other[l];\r
-               used += length;\r
-\r
-               // ensure proper termination\r
-               array[used]=0;\r
-               ++used;\r
-\r
+               else\r
+                       str.append(other.c_str(), length);\r
                return *this;\r
        }\r
 \r
@@ -700,37 +446,24 @@ public:
        //\param pos Insert the characters before this index\r
        //\param s String to insert. Must be at least of size n\r
        //\param n Number of characters from string s to use.\r
-       string<T,TAlloc>& insert(u32 pos, const char* s, u32 n)\r
+       string<T>& insert(u32 pos, const T* s, u32 n)\r
        {\r
-               if ( pos < used )\r
+               if ( pos < size()+1 )\r
                {\r
-                       reserve(used+n);\r
-\r
-                       // move stuff behind insert point\r
-                       const u32 end = used+n-1;\r
-                       for (u32 i=0; i<used-pos; ++i)\r
-                       {\r
-                               array[end-i] = array[end-(i+n)];\r
-                       }\r
-                       used += n;\r
-\r
-                       for (u32 i=0; i<n; ++i)\r
-                       {\r
-                               array[pos+i] = s[i];\r
-                       }\r
+                       str.insert(pos, s, n);\r
                }\r
 \r
                return *this;\r
        }\r
 \r
        //! Reserves some memory.\r
-       /** \param count: Amount of characters to reserve. */\r
+       /** \param count: Amount of characters to reserve, including\r
+       the trailing NUL. */\r
        void reserve(u32 count)\r
        {\r
-               if (count < allocated)\r
+               if (count == 0)\r
                        return;\r
-\r
-               reallocate(count);\r
+               str.reserve(count - 1);\r
        }\r
 \r
 \r
@@ -740,11 +473,8 @@ public:
        or -1 if not found. */\r
        s32 findFirst(T c) const\r
        {\r
-               for (u32 i=0; i<used-1; ++i)\r
-                       if (array[i] == c)\r
-                               return i;\r
-\r
-               return -1;\r
+               auto r = str.find(c);\r
+               return pos_from_stl(r);\r
        }\r
 \r
        //! finds first occurrence of a character of a list in string\r
@@ -759,12 +489,8 @@ public:
                if (!c || !count)\r
                        return -1;\r
 \r
-               for (u32 i=0; i<used-1; ++i)\r
-                       for (u32 j=0; j<count; ++j)\r
-                               if (array[i] == c[j])\r
-                                       return i;\r
-\r
-               return -1;\r
+               auto r = str.find_first_of(c, 0, count);\r
+               return pos_from_stl(r);\r
        }\r
 \r
 \r
@@ -775,24 +501,13 @@ public:
        this should be strlen(c)\r
        \return Position where the character has been found,\r
        or -1 if not found. */\r
-       template <class B>\r
-       s32 findFirstCharNotInList(const B* const c, u32 count=1) const\r
+       s32 findFirstCharNotInList(const T* const c, u32 count=1) const\r
        {\r
                if (!c || !count)\r
                        return -1;\r
 \r
-               for (u32 i=0; i<used-1; ++i)\r
-               {\r
-                       u32 j;\r
-                       for (j=0; j<count; ++j)\r
-                               if (array[i] == c[j])\r
-                                       break;\r
-\r
-                       if (j==count)\r
-                               return i;\r
-               }\r
-\r
-               return -1;\r
+               auto r = str.find_first_not_of(c, 0, count);\r
+               return pos_from_stl(r);\r
        }\r
 \r
        //! Finds last position of a character not in a given list.\r
@@ -802,24 +517,13 @@ public:
        this should be strlen(c)\r
        \return Position where the character has been found,\r
        or -1 if not found. */\r
-       template <class B>\r
-       s32 findLastCharNotInList(const B* const c, u32 count=1) const\r
+       s32 findLastCharNotInList(const T* const c, u32 count=1) const\r
        {\r
                if (!c || !count)\r
                        return -1;\r
 \r
-               for (s32 i=(s32)(used-2); i>=0; --i)\r
-               {\r
-                       u32 j;\r
-                       for (j=0; j<count; ++j)\r
-                               if (array[i] == c[j])\r
-                                       break;\r
-\r
-                       if (j==count)\r
-                               return i;\r
-               }\r
-\r
-               return -1;\r
+               auto r = str.find_last_not_of(c, npos, count);\r
+               return pos_from_stl(r);\r
        }\r
 \r
        //! finds next occurrence of character in string\r
@@ -829,11 +533,8 @@ public:
        or -1 if not found. */\r
        s32 findNext(T c, u32 startPos) const\r
        {\r
-               for (u32 i=startPos; i<used-1; ++i)\r
-                       if (array[i] == c)\r
-                               return i;\r
-\r
-               return -1;\r
+               auto r = str.find(c, startPos);\r
+               return pos_from_stl(r);\r
        }\r
 \r
 \r
@@ -844,12 +545,8 @@ public:
        or -1 if not found. */\r
        s32 findLast(T c, s32 start = -1) const\r
        {\r
-               start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 );\r
-               for (s32 i=start; i>=0; --i)\r
-                       if (array[i] == c)\r
-                               return i;\r
-\r
-               return -1;\r
+               auto r = str.rfind(c, pos_to_stl(start));\r
+               return pos_from_stl(r);\r
        }\r
 \r
        //! finds last occurrence of a character of a list in string\r
@@ -864,12 +561,8 @@ public:
                if (!c || !count)\r
                        return -1;\r
 \r
-               for (s32 i=(s32)used-2; i>=0; --i)\r
-                       for (u32 j=0; j<count; ++j)\r
-                               if (array[i] == c[j])\r
-                                       return i;\r
-\r
-               return -1;\r
+               auto r = str.find_last_of(c, npos, count);\r
+               return pos_from_stl(r);\r
        }\r
 \r
 \r
@@ -878,29 +571,12 @@ public:
        \param start: Start position of the search\r
        \return Positions where the string has been found,\r
        or -1 if not found. */\r
-       template <class B>\r
-       s32 find(const B* const str, const u32 start = 0) const\r
+       s32 find(const T* const other, const u32 start = 0) const\r
        {\r
-               if (str && *str)\r
+               if (other && *other)\r
                {\r
-                       u32 len = 0;\r
-\r
-                       while (str[len])\r
-                               ++len;\r
-\r
-                       if (len > used-1)\r
-                               return -1;\r
-\r
-                       for (u32 i=start; i<used-len; ++i)\r
-                       {\r
-                               u32 j=0;\r
-\r
-                               while(str[j] && array[i+j] == str[j])\r
-                                       ++j;\r
-\r
-                               if (!str[j])\r
-                                       return i;\r
-                       }\r
+                       auto r = str.find(other, start);\r
+                       return pos_from_stl(r);\r
                }\r
 \r
                return -1;\r
@@ -917,36 +593,17 @@ public:
                // or no proper substring length\r
                if ((length <= 0) || (begin>=size()))\r
                        return string<T>("");\r
-               // clamp length to maximal value\r
-               if ((length+begin) > size())\r
-                       length = size()-begin;\r
-\r
-               // accounting for null terminator.\r
-               s32 substrAllocLength = length + 1;\r
-               string<T> o;\r
-               o.reserve(substrAllocLength);\r
-\r
-               if ( !make_lower )\r
-               {\r
-                       for (s32 i=0; i<length; ++i)\r
-                               o.array[i] = array[i+begin];\r
-               }\r
-               else\r
-               {\r
-                       for (s32 i=0; i<length; ++i)\r
-                               o.array[i] = locale_lower ( array[i+begin] );\r
-               }\r
-\r
-               o.array[substrAllocLength - 1] = 0;\r
-               o.used = length + 1;\r
 \r
+               string<T> o = str.substr(begin, length);\r
+               if (make_lower)\r
+                       o.make_lower();\r
                return o;\r
        }\r
 \r
 \r
        //! Appends a character to this string\r
        /** \param c Character to append. */\r
-       string<T,TAlloc>& operator += (T c)\r
+       string<T>& operator += (T c)\r
        {\r
                append(c);\r
                return *this;\r
@@ -955,7 +612,7 @@ public:
 \r
        //! Appends a char string to this string\r
        /** \param c Char string to append. */\r
-       string<T,TAlloc>& operator += (const T* const c)\r
+       string<T>& operator += (const T* const c)\r
        {\r
                append(c);\r
                return *this;\r
@@ -964,7 +621,7 @@ public:
 \r
        //! Appends a string to this string\r
        /** \param other String to append. */\r
-       string<T,TAlloc>& operator += (const string<T,TAlloc>& other)\r
+       string<T>& operator += (const string<T>& other)\r
        {\r
                append(other);\r
                return *this;\r
@@ -973,54 +630,54 @@ public:
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const int i)\r
+       string<T>& operator += (const int i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const unsigned int i)\r
+       string<T>& operator += (const unsigned int i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const long i)\r
+       string<T>& operator += (const long i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const unsigned long i)\r
+       string<T>& operator += (const unsigned long i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const double i)\r
+       string<T>& operator += (const double i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
 \r
        //! Appends a string representation of a number to this string\r
        /** \param i Number to append. */\r
-       string<T,TAlloc>& operator += (const float i)\r
+       string<T>& operator += (const float i)\r
        {\r
-               append(string<T,TAlloc>(i));\r
+               append(string<T>(i));\r
                return *this;\r
        }\r
 \r
@@ -1028,11 +685,9 @@ public:
        //! Replaces all characters of a special type with another one\r
        /** \param toReplace Character to replace.\r
        \param replaceWith Character replacing the old one. */\r
-       string<T,TAlloc>& replace(T toReplace, T replaceWith)\r
+       string<T>& replace(T toReplace, T replaceWith)\r
        {\r
-               for (u32 i=0; i<used-1; ++i)\r
-                       if (array[i] == toReplace)\r
-                               array[i] = replaceWith;\r
+               std::replace(str.begin(), str.end(), toReplace, replaceWith);\r
                return *this;\r
        }\r
 \r
@@ -1040,149 +695,42 @@ public:
        //! Replaces all instances of a string with another one.\r
        /** \param toReplace The string to replace.\r
        \param replaceWith The string replacing the old one. */\r
-       string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith)\r
+       string<T>& replace(const string<T>& toReplace, const string<T>& replaceWith)\r
        {\r
-               if (toReplace.size() == 0)\r
-                       return *this;\r
-\r
-               const T* other = toReplace.c_str();\r
-               const T* replace = replaceWith.c_str();\r
-               const u32 other_size = toReplace.size();\r
-               const u32 replace_size = replaceWith.size();\r
-\r
-               // Determine the delta.  The algorithm will change depending on the delta.\r
-               s32 delta = replace_size - other_size;\r
-\r
-               // A character for character replace.  The string will not shrink or grow.\r
-               if (delta == 0)\r
-               {\r
-                       s32 pos = 0;\r
-                       while ((pos = find(other, pos)) != -1)\r
-                       {\r
-                               for (u32 i = 0; i < replace_size; ++i)\r
-                                       array[pos + i] = replace[i];\r
-                               ++pos;\r
-                       }\r
-                       return *this;\r
-               }\r
-\r
-               // We are going to be removing some characters.  The string will shrink.\r
-               if (delta < 0)\r
-               {\r
-                       u32 i = 0;\r
-                       for (u32 pos = 0; pos < used; ++i, ++pos)\r
-                       {\r
-                               // Is this potentially a match?\r
-                               if (array[pos] == *other)\r
-                               {\r
-                                       // Check to see if we have a match.\r
-                                       u32 j;\r
-                                       for (j = 0; j < other_size; ++j)\r
-                                       {\r
-                                               if (array[pos + j] != other[j])\r
-                                                       break;\r
-                                       }\r
-\r
-                                       // If we have a match, replace characters.\r
-                                       if (j == other_size)\r
-                                       {\r
-                                               for (j = 0; j < replace_size; ++j)\r
-                                                       array[i + j] = replace[j];\r
-                                               i += replace_size - 1;\r
-                                               pos += other_size - 1;\r
-                                               continue;\r
-                                       }\r
-                               }\r
-\r
-                               // No match found, just copy characters.\r
-                               array[i] = array[pos];\r
-                       }\r
-                       array[i-1] = 0;\r
-                       used = i;\r
-\r
-                       return *this;\r
-               }\r
-\r
-               // We are going to be adding characters, so the string size will increase.\r
-               // Count the number of times toReplace exists in the string so we can allocate the new size.\r
-               u32 find_count = 0;\r
-               s32 pos = 0;\r
-               while ((pos = find(other, pos)) != -1)\r
-               {\r
-                       ++find_count;\r
-                       ++pos;\r
-               }\r
-\r
-               // Re-allocate the string now, if needed.\r
-               u32 len = delta * find_count;\r
-               if (used + len > allocated)\r
-                       reallocate(used + len);\r
-\r
-               // Start replacing.\r
-               pos = 0;\r
-               while ((pos = find(other, pos)) != -1)\r
-               {\r
-                       T* start = array + pos + other_size - 1;\r
-                       T* ptr   = array + used - 1;\r
-                       T* end   = array + delta + used -1;\r
-\r
-                       // Shift characters to make room for the string.\r
-                       while (ptr != start)\r
-                       {\r
-                               *end = *ptr;\r
-                               --ptr;\r
-                               --end;\r
-                       }\r
-\r
-                       // Add the new string now.\r
-                       for (u32 i = 0; i < replace_size; ++i)\r
-                               array[pos + i] = replace[i];\r
-\r
-                       pos += replace_size;\r
-                       used += delta;\r
-               }\r
+               size_type pos = 0;\r
+           while ((pos = str.find(toReplace.str, pos)) != npos) {\r
+                str.replace(pos, toReplace.size(), replaceWith.str);\r
+                pos += replaceWith.size();\r
+           }\r
 \r
                return *this;\r
        }\r
 \r
 \r
-       //! Removes characters from a string.\r
+       //! Removes a character from a string.\r
        /** \param c: Character to remove. */\r
-       string<T,TAlloc>& remove(T c)\r
+       string<T>& remove(T c)\r
        {\r
-               u32 pos = 0;\r
-               u32 found = 0;\r
-               for (u32 i=0; i<used-1; ++i)\r
-               {\r
-                       if (array[i] == c)\r
-                       {\r
-                               ++found;\r
-                               continue;\r
-                       }\r
-\r
-                       array[pos++] = array[i];\r
-               }\r
-               used -= found;\r
-               array[used-1] = 0;\r
+               str.erase(std::remove(str.begin(), str.end(), c), str.end());\r
                return *this;\r
        }\r
 \r
 \r
        //! Removes a string from the string.\r
        /** \param toRemove: String to remove. */\r
-       string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove)\r
+       string<T>& remove(const string<T>& toRemove)\r
        {\r
                u32 size = toRemove.size();\r
                if ( size == 0 )\r
                        return *this;\r
                u32 pos = 0;\r
                u32 found = 0;\r
-               for (u32 i=0; i<used-1; ++i)\r
+               for (u32 i=0; i<str.size(); ++i)\r
                {\r
                        u32 j = 0;\r
                        while (j < size)\r
                        {\r
-                               if (array[i + j] != toRemove[j])\r
+                               if (str[i + j] != toRemove[j])\r
                                        break;\r
                                ++j;\r
                        }\r
@@ -1193,45 +741,22 @@ public:
                                continue;\r
                        }\r
 \r
-                       array[pos++] = array[i];\r
+                       str[pos++] = str[i];\r
                }\r
-               used -= found;\r
-               array[used-1] = 0;\r
+               str.resize(str.size() - found);\r
                return *this;\r
        }\r
 \r
 \r
        //! Removes characters from a string.\r
        /** \param characters: Characters to remove. */\r
-       string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters)\r
+       string<T>& removeChars(const string<T> & characters)\r
        {\r
                if (characters.size() == 0)\r
                        return *this;\r
 \r
-               u32 pos = 0;\r
-               u32 found = 0;\r
-               for (u32 i=0; i<used-1; ++i)\r
-               {\r
-                       // Don't use characters.findFirst as it finds the \0,\r
-                       // causing used to become incorrect.\r
-                       bool docontinue = false;\r
-                       for (u32 j=0; j<characters.size(); ++j)\r
-                       {\r
-                               if (characters[j] == array[i])\r
-                               {\r
-                                       ++found;\r
-                                       docontinue = true;\r
-                                       break;\r
-                               }\r
-                       }\r
-                       if (docontinue)\r
-                               continue;\r
-\r
-                       array[pos++] = array[i];\r
-               }\r
-               used -= found;\r
-               array[used-1] = 0;\r
-\r
+               for (u32 i = 0; i < characters.size(); i++)\r
+                       remove(characters[i]);\r
                return *this;\r
        }\r
 \r
@@ -1239,94 +764,35 @@ public:
        //! Trims the string.\r
        /** Removes the specified characters (by default, Latin-1 whitespace)\r
        from the beginning and the end of the string. */\r
-       string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r")\r
+       string<T>& trim(const string<T> & whitespace = " \t\n\r")\r
        {\r
                // find start and end of the substring without the specified characters\r
-               const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used);\r
+               const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.size());\r
                if (begin == -1)\r
                        return (*this="");\r
 \r
-               const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used);\r
+               const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.size());\r
 \r
                return (*this = subString(begin, (end +1) - begin));\r
        }\r
 \r
-#if 0\r
-       //! Erase 0's at the end when a string ends with a floating point number\r
-       /** After generating strings from floats we often end up with strings\r
-               ending up with lots of zeros which don't add any value. Erase 'em all.\r
-               Examples: "0.100000" becomes "0.1"\r
-                     "10.000000" becomes "10"\r
-                                 "foo 3.140000" becomes "foo 3.14"\r
-                                 "no_num.000" stays "no_num.000"\r
-                                 "1." stays "1."\r
-       */\r
-       string<T,TAlloc>& eraseTrailingFloatZeros(char decimalPoint='.')\r
-       {\r
-               s32 i=findLastCharNotInList("0", 1);\r
-               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)\r
-               {\r
-                       u32 eraseStart=i+1;\r
-                       u32 dot=0;\r
-                       if( core::isdigit(array[i]) )\r
-                       {\r
-                               while( --i>0 && core::isdigit(array[i]) );\r
-                               if ( array[i] == decimalPoint )\r
-                                       dot = i;\r
-                       }\r
-                       else if ( array[i] == decimalPoint )\r
-                       {\r
-                               dot = i;\r
-                               eraseStart = i;\r
-                       }\r
-                       if ( dot > 0 && core::isdigit(array[dot-1]) )\r
-                       {\r
-                               array[eraseStart] = 0;\r
-                               used = eraseStart+1;\r
-                       }\r
-               }\r
-               return *this;\r
-       }\r
-#endif\r
-\r
        //! Erases a character from the string.\r
        /** May be slow, because all elements\r
        following after the erased element have to be copied.\r
        \param index: Index of element to be erased. */\r
-       string<T,TAlloc>& erase(u32 index)\r
+       string<T>& erase(u32 index)\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // access violation\r
-\r
-               for (u32 i=index+1; i<used; ++i)\r
-                       array[i-1] = array[i];\r
-\r
-               --used;\r
+               str.erase(str.begin() + index);\r
                return *this;\r
        }\r
 \r
        //! verify the existing string.\r
-       string<T,TAlloc>& validate()\r
+       string<T>& validate()\r
        {\r
-               // terminate on existing null\r
-               for (u32 i=0; i<allocated; ++i)\r
-               {\r
-                       if (array[i] == 0)\r
-                       {\r
-                               used = i + 1;\r
-                               return *this;\r
-                       }\r
-               }\r
-\r
-               // terminate\r
-               if ( allocated > 0 )\r
-               {\r
-                       used = allocated;\r
-                       array[used-1] = 0;\r
-               }\r
-               else\r
-               {\r
-                       used = 0;\r
-               }\r
+               // truncate to existing null\r
+               u32 len = calclen(c_str());\r
+               if (len != size())\r
+                       str.resize(len);\r
 \r
                return *this;\r
        }\r
@@ -1334,7 +800,7 @@ public:
        //! gets the last char of a string or null\r
        T lastChar() const\r
        {\r
-               return used > 1 ? array[used-2] : 0;\r
+               return !str.empty() ? str.back() : 0;\r
        }\r
 \r
        //! Split string into parts (tokens).\r
@@ -1365,19 +831,19 @@ public:
                const u32 oldSize=ret.size();\r
 \r
                u32 tokenStartIdx = 0;\r
-               for (u32 i=0; i<used; ++i)\r
+               for (u32 i=0; i<size()+1; ++i)\r
                {\r
                        for (u32 j=0; j<countDelimiters; ++j)\r
                        {\r
-                               if (array[i] == delimiter[j])\r
+                               if (str[i] == delimiter[j])\r
                                {\r
                                        if (i - tokenStartIdx > 0)\r
-                                               ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i - tokenStartIdx));\r
+                                               ret.push_back(string<T>(&str[tokenStartIdx], i - tokenStartIdx));\r
                                        else if ( !ignoreEmptyTokens )\r
-                                               ret.push_back(string<T,TAlloc>());\r
+                                               ret.push_back(string<T>());\r
                                        if ( keepSeparators )\r
                                        {\r
-                                               ret.push_back(string<T,TAlloc>(&array[i], 1));\r
+                                               ret.push_back(string<T>(&str[i], 1));\r
                                        }\r
 \r
                                        tokenStartIdx = i+1;\r
@@ -1385,10 +851,10 @@ public:
                                }\r
                        }\r
                }\r
-               if ((used - 1) > tokenStartIdx)\r
-                       ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], (used - 1) - tokenStartIdx));\r
-                else if ( !ignoreEmptyTokens )\r
-                ret.push_back(string<T,TAlloc>());\r
+               if (size() > tokenStartIdx)\r
+                       ret.push_back(string<T>(&str[tokenStartIdx], size() - tokenStartIdx));\r
+               else if (!ignoreEmptyTokens)\r
+                       ret.push_back(string<T>());\r
 \r
                return ret.size()-oldSize;\r
        }\r
@@ -1398,30 +864,52 @@ public:
 \r
 private:\r
 \r
-       //! Reallocate the array, make it bigger or smaller\r
-       void reallocate(u32 new_size)\r
-       {\r
-               T* old_array = array;\r
-\r
-               array = allocator.allocate(new_size); //new T[new_size];\r
-               allocated = new_size;\r
+       typedef std::basic_string<T> stl_type;\r
 \r
-               const u32 amount = used < new_size ? used : new_size;\r
-               for (u32 i=0; i<amount; ++i)\r
-                       array[i] = old_array[i];\r
+       //! Private constructor\r
+       string(stl_type &&str) : str(str)\r
+       {}\r
 \r
-               if (allocated < used)\r
-                       used = allocated;\r
+       //! strlen wrapper\r
+       template <typename U>\r
+       static inline u32 calclen(const U* p) {\r
+               u32 len = 0;\r
+               while (*p++)\r
+                       len++;\r
+               return len;\r
+       }\r
+       static inline u32 calclen(const char* p) {\r
+               return strlen(p);\r
+       }\r
+       static inline u32 calclen(const wchar_t* p) {\r
+               return wcslen(p);\r
+       }\r
 \r
-               allocator.deallocate(old_array); // delete [] old_array;\r
+       //! strcmp wrapper\r
+       template <typename U>\r
+       static inline int cmp(const U* p, const U* p2) {\r
+               while (*p && *p == *p2)\r
+                       p++, p2++;\r
+               return (int)*p - (int)*p2;\r
+       }\r
+       static inline int cmp(const char* p, const char* p2) {\r
+               return strcmp(p, p2);\r
        }\r
+       static inline int cmp(const wchar_t* p, const wchar_t* p2) {\r
+               return wcscmp(p, p2);\r
+       }\r
+\r
+       typedef typename stl_type::size_type size_type;\r
+       static const size_type npos = stl_type::npos;\r
 \r
-       //--- member variables\r
+       static inline s32 pos_from_stl(size_type pos) {\r
+               return pos == npos ? -1 : (s32)pos;\r
+       }\r
+       static inline size_type pos_to_stl(s32 pos) {\r
+               return pos == -1 ? npos : (size_type)pos;\r
+       }\r
 \r
-       T* array;\r
-       u32 allocated;\r
-       u32 used;\r
-       TAlloc allocator;\r
+       stl_type str;\r
 };\r
 \r
 \r
@@ -1459,19 +947,18 @@ static size_t multibyteToWString(string<wchar_t>& destination, const char* sourc
 {\r
        if ( sourceSize )\r
        {\r
-               destination.reserve(sourceSize+1);\r
+               destination.str.resize(sourceSize+1);\r
 #if defined(_MSC_VER)\r
 #pragma warning(push)\r
 #pragma warning(disable: 4996) // 'mbstowcs': This function or variable may be unsafe. Consider using mbstowcs_s instead.\r
 #endif\r
-               const size_t written = mbstowcs(destination.array, source, (size_t)sourceSize);\r
+               const size_t written = mbstowcs(&destination[0], source, (size_t)sourceSize);\r
 #if defined(_MSC_VER)\r
 #pragma warning(pop)\r
 #endif\r
                if ( written != (size_t)-1 )\r
                {\r
-                       destination.used = (u32)written+1;\r
-                       destination.array[destination.used-1] = 0;\r
+                       destination.str.resize(written);\r
                }\r
                else\r
                {\r
@@ -1506,19 +993,18 @@ static size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source,
 {\r
        if ( sourceSize )\r
        {\r
-               destination.reserve(sizeof(wchar_t)*sourceSize+1);\r
+               destination.str.resize(sizeof(wchar_t)*sourceSize+1);\r
 #if defined(_MSC_VER)\r
 #pragma warning(push)\r
 #pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead.\r
 #endif\r
-               const size_t written = wcstombs(destination.array, source, destination.allocated-1);\r
+               const size_t written = wcstombs(&destination[0], source, destination.size());\r
 #if defined(_MSC_VER)\r
 #pragma warning(pop)\r
 #endif\r
                if ( written != (size_t)-1 )\r
                {\r
-                       destination.used = (u32)written+1;\r
-                       destination.array[destination.used-1] = 0;\r
+                       destination.str.resize(written);\r
                }\r
                else\r
                {\r
index 49cc67044baaa228d46d0b545b426b999a055fc5..3e20ff8b29d90b361e658c592f4cf24b162f1135 100644 (file)
@@ -813,8 +813,8 @@ public:
 
 
        //! Constructor from other string types
-       template <class B, class A>
-       ustring16(const string<B, A>& other)
+       template <class B>
+       ustring16(const string<B>& other)
        : array(0), allocated(0), used(0)
        {
 #if __BYTE_ORDER == __BIG_ENDIAN
@@ -1054,8 +1054,8 @@ public:
        }
 
        //! Assignment operator for other string types
-       template <class B, class A>
-       ustring16<TAlloc>& operator=(const string<B, A>& other)
+       template <class B>
+       ustring16<TAlloc>& operator=(const string<B>& other)
        {
                *this = other.c_str();
                return *this;
@@ -3139,8 +3139,8 @@ inline ustring16<TAlloc> operator+(const B* const left, const ustring16<TAlloc>&
 
 
 //! Appends a ustring16 and an Irrlicht string.
-template <typename TAlloc, typename B, typename BAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const string<B, BAlloc>& right)
+template <typename TAlloc, typename B>
+inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const string<B>& right)
 {
        ustring16<TAlloc> ret(left);
        ret += right;
@@ -3149,8 +3149,8 @@ inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const string<B
 
 
 //! Appends a ustring16 and an Irrlicht string.
-template <typename TAlloc, typename B, typename BAlloc>
-inline ustring16<TAlloc> operator+(const string<B, BAlloc>& left, const ustring16<TAlloc>& right)
+template <typename TAlloc, typename B>
+inline ustring16<TAlloc> operator+(const string<B>& left, const ustring16<TAlloc>& right)
 {
        ustring16<TAlloc> ret(left);
        ret += right;
@@ -3438,8 +3438,8 @@ inline ustring16<TAlloc>&& operator+(const B* const left, ustring16<TAlloc>&& ri
 
 
 //! Appends a ustring16 and an Irrlicht string.
-template <typename TAlloc, typename B, typename BAlloc>
-inline ustring16<TAlloc>&& operator+(const string<B, BAlloc>& left, ustring16<TAlloc>&& right)
+template <typename TAlloc, typename B>
+inline ustring16<TAlloc>&& operator+(const string<B>& left, ustring16<TAlloc>&& right)
 {
        //std::cout << "MOVE operator+(&, &&)" << std::endl;
        right.insert(left, 0);
@@ -3448,8 +3448,8 @@ inline ustring16<TAlloc>&& operator+(const string<B, BAlloc>& left, ustring16<TA
 
 
 //! Appends a ustring16 and an Irrlicht string.
-template <typename TAlloc, typename B, typename BAlloc>
-inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, const string<B, BAlloc>& right)
+template <typename TAlloc, typename B>
+inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, const string<B>& right)
 {
        //std::cout << "MOVE operator+(&&, &)" << std::endl;
        left.append(right);
index f65b7004c6146fea58b0539132858f05cafd5aec..537475510504a82aa540874ed26efd0d40a78156 100644 (file)
@@ -3,6 +3,7 @@
 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
 \r
 #include "CLimitReadFile.h"\r
+#include "irrMath.h"\r
 #include "irrString.h"\r
 \r
 namespace irr\r
index 57f156d745269333dd4c6936deeefce13e42f806..a557844740902b18735d7f6d68e621ef928ff19f 100644 (file)
@@ -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)\r
 #if defined(_IRR_COMPILE_WITH_OGLES2_) || defined(_IRR_COMPILE_WITH_OGLES1_)\r
 \r
+#include "irrMath.h"\r
 #include "COpenGLCoreFeature.h"\r
 \r
 namespace irr\r