aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------LICENSE1
-rw-r--r--examples/AutomatedTest/main.cpp14
-rw-r--r--examples/AutomatedTest/test_array.cpp2
-rw-r--r--examples/AutomatedTest/test_string.cpp195
-rw-r--r--include/IImage.h12
-rw-r--r--include/IVideoDriver.h2
-rw-r--r--include/SMaterialLayer.h17
-rw-r--r--include/irrAllocator.h113
-rw-r--r--include/irrString.h975
-rw-r--r--include/irrUString.h421
-rw-r--r--source/Irrlicht/CGUITabControl.cpp129
-rw-r--r--source/Irrlicht/CGUITabControl.h7
-rw-r--r--source/Irrlicht/CIrrDeviceSDL.cpp19
-rw-r--r--source/Irrlicht/CIrrDeviceSDL.h30
-rw-r--r--source/Irrlicht/CLimitReadFile.cpp1
-rw-r--r--source/Irrlicht/COGLESCoreExtensionHandler.h1
-rw-r--r--source/Irrlicht/COpenGLCoreTexture.h2
17 files changed, 776 insertions, 1165 deletions
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..0d6c781
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+doc/irrlicht-license.txt \ No newline at end of file
diff --git a/examples/AutomatedTest/main.cpp b/examples/AutomatedTest/main.cpp
index 2f80722..e724176 100644
--- a/examples/AutomatedTest/main.cpp
+++ b/examples/AutomatedTest/main.cpp
@@ -7,7 +7,8 @@ using namespace irr;
static IrrlichtDevice *device = nullptr;
static int test_fail = 0;
-extern void test_irr_array();
+void test_irr_array();
+void test_irr_string();
static video::E_DRIVER_TYPE chooseDriver(const char *arg_)
{
@@ -32,7 +33,14 @@ static inline void check(bool ok, const char *msg)
void run_unit_tests() {
std::cout << "Running unit tests:" << std::endl;
- test_irr_array();
+ try {
+ 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[])
@@ -99,7 +107,7 @@ int main(int argc, char *argv[])
while (device->run())
{
- if (device->getTimer()->getTime() >= 1300)
+ if (device->getTimer()->getTime() >= 1000)
{
device->getTimer()->setTime(0);
++n;
diff --git a/examples/AutomatedTest/test_array.cpp b/examples/AutomatedTest/test_array.cpp
index 5ec55ee..4c207ff 100644
--- a/examples/AutomatedTest/test_array.cpp
+++ b/examples/AutomatedTest/test_array.cpp
@@ -1,4 +1,4 @@
-#include "irrArray.h"
+#include <irrArray.h>
#include "test_helper.h"
using namespace irr;
diff --git a/examples/AutomatedTest/test_string.cpp b/examples/AutomatedTest/test_string.cpp
new file mode 100644
index 0000000..a9b35b1
--- /dev/null
+++ b/examples/AutomatedTest/test_string.cpp
@@ -0,0 +1,195 @@
+#include <irrString.h>
+#include <cstring>
+#include <clocale>
+#include <vector>
+#include "test_helper.h"
+
+using namespace irr;
+using namespace irr::core;
+
+#define CMPSTR(a, b) (!strcmp(a, b))
+#define UASSERTSTR(actual, expected) UASSERTCMP(CMPSTR, actual.c_str(), expected)
+
+static void test_basics()
+{
+ // ctor
+ stringc s;
+ UASSERTEQ(s.c_str()[0], '\0');
+ s = stringc(0.1234567);
+ UASSERTSTR(s, "0.123457");
+ s = stringc(0x1p+53);
+ UASSERTSTR(s, "9007199254740992.000000");
+ s = stringc(static_cast<int>(-102400));
+ UASSERTSTR(s, "-102400");
+ s = stringc(static_cast<unsigned int>(102400));
+ UASSERTSTR(s, "102400");
+ s = stringc(static_cast<long>(-1024000));
+ UASSERTSTR(s, "-1024000");
+ s = stringc(static_cast<unsigned long>(1024000));
+ UASSERTSTR(s, "1024000");
+ s = stringc("YESno", 3);
+ UASSERTSTR(s, "YES");
+ s = stringc(L"test", 4);
+ UASSERTSTR(s, "test");
+ s = stringc("Hello World!");
+ UASSERTSTR(s, "Hello World!");
+ // operator=
+ s = stringw(L"abcdef");
+ UASSERTSTR(s, "abcdef");
+ s = L"abcdef";
+ UASSERTSTR(s, "abcdef");
+ s = static_cast<const char*>(nullptr);
+ UASSERTSTR(s, "");
+ // operator+
+ s = s + stringc("foo");
+ UASSERTSTR(s, "foo");
+ s = s + L"bar";
+ UASSERTSTR(s, "foobar");
+ // the rest
+ s = "f";
+ UASSERTEQ(s[0], 'f');
+ const auto &sref = s;
+ UASSERTEQ(sref[0], 'f');
+ UASSERT(sref == "f");
+ UASSERT(sref == stringc("f"));
+ s = "a";
+ UASSERT(sref < stringc("aa"));
+ UASSERT(sref < stringc("b"));
+ UASSERT(stringc("Z") < sref);
+ UASSERT(!(sref < stringc("a")));
+ UASSERT(sref.lower_ignore_case("AA"));
+ UASSERT(sref.lower_ignore_case("B"));
+ UASSERT(!sref.lower_ignore_case("A"));
+ s = "dog";
+ UASSERT(sref != "cat");
+ UASSERT(sref != stringc("cat"));
+}
+
+static void test_methods()
+{
+ stringc s;
+ const auto &sref = s;
+ s = "irrlicht";
+ UASSERTEQ(sref.size(), 8);
+ UASSERT(!sref.empty());
+ s.clear();
+ UASSERTEQ(sref.size(), 0);
+ UASSERT(sref.empty());
+ UASSERT(sref[0] == 0);
+ s = "\tAz#`";
+ s.make_lower();
+ UASSERTSTR(s, "\taz#`");
+ s.make_upper();
+ UASSERTSTR(s, "\tAZ#`");
+ UASSERT(sref.equals_ignore_case("\taz#`"));
+ UASSERT(sref.equals_substring_ignore_case("Z#`", 2));
+ s = "irrlicht";
+ UASSERT(sref.equalsn(stringc("irr"), 3));
+ UASSERT(sref.equalsn("irr", 3));
+ s = "fo";
+ s.append('o');
+ UASSERTSTR(s, "foo");
+ s.append("bar", 1);
+ UASSERTSTR(s, "foob");
+ s.append("ar", 999999);
+ UASSERTSTR(s, "foobar");
+ s = "nyan";
+ s.append(stringc("cat"));
+ UASSERTSTR(s, "nyancat");
+ s.append(stringc("sam"), 1);
+ UASSERTSTR(s, "nyancats");
+ s = "fbar";
+ s.insert(1, "ooXX", 2);
+ UASSERTSTR(s, "foobar");
+ UASSERTEQ(sref.findFirst('o'), 1);
+ UASSERTEQ(sref.findFirst('X'), -1);
+ UASSERTEQ(sref.findFirstChar("abff", 2), 3);
+ UASSERTEQ(sref.findFirstCharNotInList("fobb", 2), 3);
+ UASSERTEQ(sref.findLast('o'), 2);
+ UASSERTEQ(sref.findLast('X'), -1);
+ UASSERTEQ(sref.findLastChar("abrr", 2), 4);
+ UASSERTEQ(sref.findLastCharNotInList("rabb", 2), 3);
+ UASSERTEQ(sref.findNext('o', 2), 2);
+ UASSERTEQ(sref.findLast('o', 1), 1);
+ s = "ob-oob";
+ UASSERTEQ(sref.find("ob", 1), 4);
+ UASSERTEQ(sref.find("ob"), 0);
+ UASSERTEQ(sref.find("?"), -1);
+ s = "HOMEOWNER";
+ stringc s2 = sref.subString(2, 4);
+ UASSERTSTR(s2, "MEOW");
+ s2 = sref.subString(2, 4, true);
+ UASSERTSTR(s2, "meow");
+ s = "land";
+ s.replace('l', 's');
+ UASSERTSTR(s, "sand");
+ s = ">dog<";
+ s.replace("dog", "cat");
+ UASSERTSTR(s, ">cat<");
+ s.replace("cat", "horse");
+ UASSERTSTR(s, ">horse<");
+ s.replace("horse", "gnu");
+ UASSERTSTR(s, ">gnu<");
+ s = " h e l p ";
+ s.remove(' ');
+ UASSERTSTR(s, "help");
+ s.remove("el");
+ UASSERTSTR(s, "hp");
+ s = "irrlicht";
+ s.removeChars("it");
+ UASSERTSTR(s, "rrlch");
+ s = "\r\nfoo bar ";
+ s.trim();
+ UASSERTSTR(s, "foo bar");
+ s = "foxo";
+ s.erase(2);
+ UASSERTSTR(s, "foo");
+ s = "a";
+ s.append('\0');
+ s.append('b');
+ UASSERTEQ(s.size(), 3);
+ s.validate();
+ UASSERTEQ(s.size(), 1);
+ UASSERTEQ(s.lastChar(), 'a');
+ std::vector<stringc> res;
+ s = "a,,b,c";
+ s.split(res, ",aa", 1, true, false);
+ UASSERTEQ(res.size(), 3);
+ UASSERTSTR(res[0], "a");
+ UASSERTSTR(res[2], "c");
+ res.clear();
+ s.split(res, ",", 1, false, true);
+ UASSERTEQ(res.size(), 7);
+ UASSERTSTR(res[0], "a");
+ UASSERTSTR(res[2], "");
+ for (int i = 0; i < 3; i++)
+ UASSERTSTR(res[2*i+1], ",");
+}
+
+static void test_conv()
+{
+ // assumes Unicode and UTF-8 locale
+ setlocale(LC_CTYPE, "");
+
+ stringw out;
+ multibyteToWString(out, "†††");
+ UASSERTEQ(out.size(), 3);
+ for (int i = 0; i < 3; i++)
+ UASSERTEQ(static_cast<u16>(out[i]), 0x2020);
+ stringc out2;
+ wStringToMultibyte(out2, L"†††");
+ UASSERTEQ(out2.size(), 9);
+ for (int i = 0; i < 3; i++) {
+ UASSERTEQ(static_cast<u8>(out2[3*i]), 0xe2);
+ UASSERTEQ(static_cast<u8>(out2[3*i+1]), 0x80);
+ UASSERTEQ(static_cast<u8>(out2[3*i+2]), 0xa0);
+ }
+}
+
+void test_irr_string()
+{
+ test_basics();
+ test_methods();
+ test_conv();
+ std::cout << " test_irr_string PASSED" << std::endl;
+}
diff --git a/include/IImage.h b/include/IImage.h
index 3d4d5fa..20d3d54 100644
--- a/include/IImage.h
+++ b/include/IImage.h
@@ -9,7 +9,6 @@
#include "position2d.h"
#include "rect.h"
#include "SColor.h"
-#include "irrAllocator.h"
#include <string.h>
namespace irr
@@ -44,7 +43,7 @@ public:
delete[] Data;
if (DeleteMipMapsMemory)
- Allocator.deallocate(MipMapsData);
+ delete[] MipMapsData;
}
//! Returns the color format
@@ -275,13 +274,13 @@ public:
will by copied internally.
\param deleteMemory Whether the memory is deallocated upon
destruction. */
- void setMipMapsData(void* data, bool ownForeignMemory, bool deleteMemory)
+ void setMipMapsData(void* data, bool ownForeignMemory)
{
if (data != MipMapsData)
{
if (DeleteMipMapsMemory)
{
- Allocator.deallocate(MipMapsData);
+ delete[] MipMapsData;
DeleteMipMapsMemory = false;
}
@@ -292,7 +291,7 @@ public:
{
MipMapsData = static_cast<u8*>(data);
- DeleteMipMapsMemory = deleteMemory;
+ DeleteMipMapsMemory = false;
}
else
{
@@ -311,7 +310,7 @@ public:
dataSize += getDataSizeFromFormat(Format, width, height);
} while (width != 1 || height != 1);
- MipMapsData = Allocator.allocate(dataSize);
+ MipMapsData = new u8[dataSize];
memcpy(MipMapsData, data, dataSize);
DeleteMipMapsMemory = true;
@@ -578,7 +577,6 @@ protected:
bool DeleteMemory;
bool DeleteMipMapsMemory;
- core::irrAllocator<u8> Allocator;
#if defined(IRRLICHT_sRGB)
int Format_sRGB;
#endif
diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h
index 848a9b0..a8cea13 100644
--- a/include/IVideoDriver.h
+++ b/include/IVideoDriver.h
@@ -331,7 +331,7 @@ namespace video
_IRR_DEPRECATED_ ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData)
{
if (image)
- image->setMipMapsData(mipmapData, false, true);
+ image->setMipMapsData(mipmapData, false);
return addTexture(name, image);
}
diff --git a/include/SMaterialLayer.h b/include/SMaterialLayer.h
index 2ef72c8..8f562de 100644
--- a/include/SMaterialLayer.h
+++ b/include/SMaterialLayer.h
@@ -6,7 +6,6 @@
#define __S_MATERIAL_LAYER_H_INCLUDED__
#include "matrix4.h"
-#include "irrAllocator.h"
namespace irr
{
@@ -69,8 +68,7 @@ namespace video
{
if ( TextureMatrix )
{
- MatrixAllocator.destruct(TextureMatrix);
- MatrixAllocator.deallocate(TextureMatrix);
+ delete TextureMatrix;
}
}
@@ -90,8 +88,7 @@ namespace video
*TextureMatrix = *other.TextureMatrix;
else
{
- MatrixAllocator.destruct(TextureMatrix);
- MatrixAllocator.deallocate(TextureMatrix);
+ delete TextureMatrix;
TextureMatrix = 0;
}
}
@@ -99,8 +96,7 @@ namespace video
{
if (other.TextureMatrix)
{
- TextureMatrix = MatrixAllocator.allocate(1);
- MatrixAllocator.construct(TextureMatrix,*other.TextureMatrix);
+ TextureMatrix = new core::matrix4(*other.TextureMatrix);
}
else
TextureMatrix = 0;
@@ -122,8 +118,7 @@ namespace video
{
if (!TextureMatrix)
{
- TextureMatrix = MatrixAllocator.allocate(1);
- MatrixAllocator.construct(TextureMatrix,core::IdentityMatrix);
+ TextureMatrix = new core::matrix4();
}
return *TextureMatrix;
}
@@ -146,8 +141,7 @@ namespace video
{
if (!TextureMatrix)
{
- TextureMatrix = MatrixAllocator.allocate(1);
- MatrixAllocator.construct(TextureMatrix,mat);
+ TextureMatrix = new core::matrix4(mat);
}
else
*TextureMatrix = mat;
@@ -216,7 +210,6 @@ namespace video
private:
friend class SMaterial;
- irr::core::irrAllocator<irr::core::matrix4> MatrixAllocator;
//! Texture Matrix
/** Do not access this element directly as the internal
diff --git a/include/irrAllocator.h b/include/irrAllocator.h
deleted file mode 100644
index ff6624b..0000000
--- a/include/irrAllocator.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
-
-#ifndef __IRR_ALLOCATOR_H_INCLUDED__
-#define __IRR_ALLOCATOR_H_INCLUDED__
-
-#include "irrTypes.h"
-#include <new>
-// necessary for older compilers
-#include <memory.h>
-
-namespace irr
-{
-namespace core
-{
-
-//! Very simple allocator implementation, containers using it can be used across dll boundaries
-template<typename T>
-class irrAllocator
-{
-public:
-
- //! Destructor
- virtual ~irrAllocator() {}
-
- //! Allocate memory for an array of objects
- T* allocate(size_t cnt)
- {
- return (T*)internal_new(cnt* sizeof(T));
- }
-
- //! Deallocate memory for an array of objects
- void deallocate(T* ptr)
- {
- internal_delete(ptr);
- }
-
- //! Construct an element
- void construct(T* ptr, const T&e)
- {
- new ((void*)ptr) T(e);
- }
-
- //! Destruct an element
- void destruct(T* ptr)
- {
- ptr->~T();
- }
-
-protected:
-
- virtual void* internal_new(size_t cnt)
- {
- return operator new(cnt);
- }
-
- virtual void internal_delete(void* ptr)
- {
- operator delete(ptr);
- }
-
-};
-
-
-//! Fast allocator, only to be used in containers inside the same memory heap.
-/** Containers using it are NOT able to be used it across dll boundaries. Use this
-when using in an internal class or function or when compiled into a static lib */
-template<typename T>
-class irrAllocatorFast
-{
-public:
-
- //! Allocate memory for an array of objects
- T* allocate(size_t cnt)
- {
- return (T*)operator new(cnt* sizeof(T));
- }
-
- //! Deallocate memory for an array of objects
- void deallocate(T* ptr)
- {
- operator delete(ptr);
- }
-
- //! Construct an element
- void construct(T* ptr, const T&e)
- {
- new ((void*)ptr) T(e);
- }
-
- //! Destruct an element
- void destruct(T* ptr)
- {
- ptr->~T();
- }
-};
-
-
-//! defines an allocation strategy (used only by irr::array so far)
-enum eAllocStrategy
-{
- ALLOC_STRATEGY_SAFE = 0, // increase size by 1
- ALLOC_STRATEGY_DOUBLE = 1, // double size when under 500 elements, beyond that increase by 1/4th size. Plus a small constant.
- ALLOC_STRATEGY_SQRT = 2 // not implemented
-};
-
-
-} // end namespace core
-} // end namespace irr
-
-#endif
-
diff --git a/include/irrString.h b/include/irrString.h
index d8757af..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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <wchar.h>
+#include <string>
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <cwchar>
namespace irr
{
@@ -34,11 +33,10 @@ outside the string class for explicit use.
*/
// forward declarations
-template <typename T, typename TAlloc = irrAllocator<T> >
+template <typename T>
class string;
static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
static size_t wStringToMultibyte(string<c8>& 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 <typename T, typename TAlloc>
+template <typename T>
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<T,TAlloc>& other)
- : array(0), allocated(0), used(0)
+ //! Copy constructor
+ string(const string<T>& other)
{
*this = other;
}
//! Constructor from other string types
- template <class B, class A>
- string(const string<B, A>& other)
- : array(0), allocated(0), used(0)
+ template <class B>
+ string(const string<B>& 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 <class B>
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<length; ++l)
- array[l] = (T)c[l];
-
- array[length] = 0;
+ str[l] = (T)c[l];
}
//! Constructor for Unicode and ASCII strings
template <class B>
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<T,TAlloc>& operator=(const string<T,TAlloc>& other)
+ string<T>& operator=(const string<T>& 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<used; ++i, ++p)
- array[i] = *p;
-
+ str = other.str;
return *this;
}
//! Assignment operator for other string types
- template <class B, class A>
- string<T,TAlloc>& operator=(const string<B,A>& other)
+ template <class B>
+ string<T>& operator=(const string<B>& other)
{
*this = other.c_str();
return *this;
@@ -325,137 +163,93 @@ public:
//! Assignment operator for strings, ASCII and Unicode
template <class B>
- string<T,TAlloc>& operator=(const B* const c)
+ string<T>& 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<len; ++l)
- array[l] = (T)c[l];
-
- if (oldArray != array)
- allocator.deallocate(oldArray); // delete [] oldArray;
+ str[l] = (T)c[l];
return *this;
}
//! Append operator for other strings
- string<T,TAlloc> operator+(const string<T,TAlloc>& other) const
+ string<T> operator+(const string<T>& other) const
{
- string<T,TAlloc> str(*this);
- str.append(other);
+ string<T> tmp(*this);
+ tmp.append(other);
- return str;
+ return tmp;
}
//! Append operator for strings, ASCII and Unicode
template <class B>
- string<T,TAlloc> operator+(const B* const c) const
+ string<T> operator+(const B* const c) const
{
- string<T,TAlloc> str(*this);
- str.append(c);
+ string<T> 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<T,TAlloc>& other) const
+ bool operator==(const string<T>& 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<T,TAlloc>& other) const
+ bool operator<(const string<T>& 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<T,TAlloc>& other) const
+ bool operator!=(const string<T>& 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<T,TAlloc>& make_lower()
+ string<T>& 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<T,TAlloc>& make_upper()
+ string<T>& 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<T,TAlloc>& other) const
+ bool equals_ignore_case(const string<T>& 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<T,TAlloc>&other, const s32 sourcePos = 0 ) const
+ bool equals_substring_ignore_case(const string<T>&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<T,TAlloc>& other) const
+ bool lower_ignore_case(const string<T>& 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<T,TAlloc>& other, u32 n) const
+ bool equalsn(const string<T>& 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<T,TAlloc>& append(T character)
+ string<T>& 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,54 +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<T,TAlloc>& append(const T* const other, u32 length=0xffffffff)
+ string<T>& 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<len; ++l)
- array[l+used] = *(other+l);
-
- used += len;
-
+ str.append(other, len);
return *this;
}
//! Appends a string to this string
/** \param other: String to append. */
- string<T,TAlloc>& append(const string<T,TAlloc>& other)
+ string<T>& append(const string<T>& 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<len; ++l)
- array[used+l] = other[l];
-
- used += len;
-
+ str.append(other.str);
return *this;
}
@@ -668,30 +433,12 @@ public:
//! Appends a string of the length l to this string.
/** \param other: other String to append to this string.
\param length: How much characters of the other string to add to this one. */
- string<T,TAlloc>& append(const string<T,TAlloc>& other, u32 length)
+ string<T>& append(const string<T>& 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<length; ++l)
- array[l+used] = other[l];
- used += length;
-
- // ensure proper termination
- array[used]=0;
- ++used;
-
+ else
+ str.append(other.c_str(), length);
return *this;
}
@@ -699,37 +446,24 @@ public:
//\param pos Insert the characters before this index
//\param s String to insert. Must be at least of size n
//\param n Number of characters from string s to use.
- string<T,TAlloc>& insert(u32 pos, const char* s, u32 n)
+ string<T>& 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<used-pos; ++i)
- {
- array[end-i] = array[end-(i+n)];
- }
- used += n;
-
- for (u32 i=0; i<n; ++i)
- {
- array[pos+i] = s[i];
- }
+ str.insert(pos, s, n);
}
return *this;
}
//! Reserves some memory.
- /** \param count: Amount of characters to reserve. */
+ /** \param count: Amount of characters to reserve, including
+ the trailing NUL. */
void reserve(u32 count)
{
- if (count < allocated)
+ if (count == 0)
return;
-
- reallocate(count);
+ str.reserve(count - 1);
}
@@ -739,11 +473,8 @@ public:
or -1 if not found. */
s32 findFirst(T c) const
{
- for (u32 i=0; i<used-1; ++i)
- if (array[i] == c)
- return i;
-
- return -1;
+ auto r = str.find(c);
+ return pos_from_stl(r);
}
//! finds first occurrence of a character of a list in string
@@ -758,12 +489,8 @@ public:
if (!c || !count)
return -1;
- for (u32 i=0; i<used-1; ++i)
- for (u32 j=0; j<count; ++j)
- if (array[i] == c[j])
- return i;
-
- return -1;
+ auto r = str.find_first_of(c, 0, count);
+ return pos_from_stl(r);
}
@@ -774,24 +501,13 @@ public:
this should be strlen(c)
\return Position where the character has been found,
or -1 if not found. */
- template <class B>
- 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<used-1; ++i)
- {
- u32 j;
- for (j=0; j<count; ++j)
- if (array[i] == c[j])
- break;
-
- if (j==count)
- return i;
- }
-
- return -1;
+ auto r = str.find_first_not_of(c, 0, count);
+ return pos_from_stl(r);
}
//! Finds last position of a character not in a given list.
@@ -801,24 +517,13 @@ public:
this should be strlen(c)
\return Position where the character has been found,
or -1 if not found. */
- template <class B>
- 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<count; ++j)
- if (array[i] == c[j])
- break;
-
- if (j==count)
- return i;
- }
-
- return -1;
+ auto r = str.find_last_not_of(c, npos, count);
+ return pos_from_stl(r);
}
//! finds next occurrence of character in string
@@ -828,11 +533,8 @@ public:
or -1 if not found. */
s32 findNext(T c, u32 startPos) const
{
- for (u32 i=startPos; i<used-1; ++i)
- if (array[i] == c)
- return i;
-
- return -1;
+ auto r = str.find(c, startPos);
+ return pos_from_stl(r);
}
@@ -843,12 +545,8 @@ public:
or -1 if not found. */
s32 findLast(T c, s32 start = -1) const
{
- start = core::clamp ( start < 0 ? (s32)(used) - 2 : start, 0, (s32)(used) - 2 );
- for (s32 i=start; i>=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
@@ -863,12 +561,8 @@ public:
if (!c || !count)
return -1;
- for (s32 i=(s32)used-2; i>=0; --i)
- for (u32 j=0; j<count; ++j)
- if (array[i] == c[j])
- return i;
-
- return -1;
+ auto r = str.find_last_of(c, npos, count);
+ return pos_from_stl(r);
}
@@ -877,29 +571,12 @@ public:
\param start: Start position of the search
\return Positions where the string has been found,
or -1 if not found. */
- template <class B>
- 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<used-len; ++i)
- {
- u32 j=0;
-
- while(str[j] && array[i+j] == str[j])
- ++j;
-
- if (!str[j])
- return i;
- }
+ auto r = str.find(other, start);
+ return pos_from_stl(r);
}
return -1;
@@ -916,36 +593,17 @@ public:
// or no proper substring length
if ((length <= 0) || (begin>=size()))
return string<T>("");
- // clamp length to maximal value
- if ((length+begin) > size())
- length = size()-begin;
-
- // accounting for null terminator.
- s32 substrAllocLength = length + 1;
- string<T> o;
- o.reserve(substrAllocLength);
-
- if ( !make_lower )
- {
- for (s32 i=0; i<length; ++i)
- o.array[i] = array[i+begin];
- }
- else
- {
- for (s32 i=0; i<length; ++i)
- o.array[i] = locale_lower ( array[i+begin] );
- }
-
- o.array[substrAllocLength - 1] = 0;
- o.used = length + 1;
+ string<T> 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<T,TAlloc>& operator += (T c)
+ string<T>& operator += (T c)
{
append(c);
return *this;
@@ -954,7 +612,7 @@ public:
//! Appends a char string to this string
/** \param c Char string to append. */
- string<T,TAlloc>& operator += (const T* const c)
+ string<T>& operator += (const T* const c)
{
append(c);
return *this;
@@ -963,7 +621,7 @@ public:
//! Appends a string to this string
/** \param other String to append. */
- string<T,TAlloc>& operator += (const string<T,TAlloc>& other)
+ string<T>& operator += (const string<T>& other)
{
append(other);
return *this;
@@ -972,54 +630,54 @@ public:
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const int i)
+ string<T>& operator += (const int i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const unsigned int i)
+ string<T>& operator += (const unsigned int i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const long i)
+ string<T>& operator += (const long i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const unsigned long i)
+ string<T>& operator += (const unsigned long i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const double i)
+ string<T>& operator += (const double i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
//! Appends a string representation of a number to this string
/** \param i Number to append. */
- string<T,TAlloc>& operator += (const float i)
+ string<T>& operator += (const float i)
{
- append(string<T,TAlloc>(i));
+ append(string<T>(i));
return *this;
}
@@ -1027,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<T,TAlloc>& replace(T toReplace, T replaceWith)
+ string<T>& replace(T toReplace, T replaceWith)
{
- for (u32 i=0; i<used-1; ++i)
- if (array[i] == toReplace)
- array[i] = replaceWith;
+ std::replace(str.begin(), str.end(), toReplace, replaceWith);
return *this;
}
@@ -1039,149 +695,42 @@ public:
//! Replaces all instances of a string with another one.
/** \param toReplace The string to replace.
\param replaceWith The string replacing the old one. */
- string<T,TAlloc>& replace(const string<T,TAlloc>& toReplace, const string<T,TAlloc>& replaceWith)
+ string<T>& replace(const string<T>& toReplace, const string<T>& 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<T,TAlloc>& remove(T c)
+ string<T>& remove(T c)
{
- u32 pos = 0;
- u32 found = 0;
- for (u32 i=0; i<used-1; ++i)
- {
- if (array[i] == c)
- {
- ++found;
- continue;
- }
-
- array[pos++] = array[i];
- }
- used -= found;
- array[used-1] = 0;
+ str.erase(std::remove(str.begin(), str.end(), c), str.end());
return *this;
}
//! Removes a string from the string.
/** \param toRemove: String to remove. */
- string<T,TAlloc>& remove(const string<T,TAlloc>& toRemove)
+ string<T>& remove(const string<T>& toRemove)
{
u32 size = toRemove.size();
if ( size == 0 )
return *this;
u32 pos = 0;
u32 found = 0;
- for (u32 i=0; i<used-1; ++i)
+ for (u32 i=0; i<str.size(); ++i)
{
u32 j = 0;
while (j < size)
{
- if (array[i + j] != toRemove[j])
+ if (str[i + j] != toRemove[j])
break;
++j;
}
@@ -1192,45 +741,22 @@ public:
continue;
}
- array[pos++] = array[i];
+ str[pos++] = str[i];
}
- used -= found;
- array[used-1] = 0;
+ str.resize(str.size() - found);
return *this;
}
//! Removes characters from a string.
/** \param characters: Characters to remove. */
- string<T,TAlloc>& removeChars(const string<T,TAlloc> & characters)
+ string<T>& removeChars(const string<T> & characters)
{
if (characters.size() == 0)
return *this;
- u32 pos = 0;
- u32 found = 0;
- for (u32 i=0; i<used-1; ++i)
- {
- // Don't use characters.findFirst as it finds the \0,
- // causing used to become incorrect.
- bool docontinue = false;
- for (u32 j=0; j<characters.size(); ++j)
- {
- if (characters[j] == array[i])
- {
- ++found;
- docontinue = true;
- break;
- }
- }
- if (docontinue)
- continue;
-
- array[pos++] = array[i];
- }
- used -= found;
- array[used-1] = 0;
-
+ for (u32 i = 0; i < characters.size(); i++)
+ remove(characters[i]);
return *this;
}
@@ -1238,92 +764,35 @@ public:
//! Trims the string.
/** Removes the specified characters (by default, Latin-1 whitespace)
from the beginning and the end of the string. */
- string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r")
+ string<T>& trim(const string<T> & 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));
}
- //! 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<T,TAlloc>& 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;
- }
-
//! 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<T,TAlloc>& erase(u32 index)
+ string<T>& erase(u32 index)
{
- _IRR_DEBUG_BREAK_IF(index>=used) // access violation
-
- for (u32 i=index+1; i<used; ++i)
- array[i-1] = array[i];
-
- --used;
+ str.erase(str.begin() + index);
return *this;
}
//! verify the existing string.
- string<T,TAlloc>& validate()
+ string<T>& validate()
{
- // terminate on existing null
- for (u32 i=0; i<allocated; ++i)
- {
- if (array[i] == 0)
- {
- used = i + 1;
- return *this;
- }
- }
-
- // terminate
- if ( allocated > 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;
}
@@ -1331,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).
@@ -1362,19 +831,19 @@ public:
const u32 oldSize=ret.size();
u32 tokenStartIdx = 0;
- for (u32 i=0; i<used; ++i)
+ for (u32 i=0; i<size()+1; ++i)
{
for (u32 j=0; j<countDelimiters; ++j)
{
- if (array[i] == delimiter[j])
+ if (str[i] == delimiter[j])
{
if (i - tokenStartIdx > 0)
- ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i - tokenStartIdx));
+ ret.push_back(string<T>(&str[tokenStartIdx], i - tokenStartIdx));
else if ( !ignoreEmptyTokens )
- ret.push_back(string<T,TAlloc>());
+ ret.push_back(string<T>());
if ( keepSeparators )
{
- ret.push_back(string<T,TAlloc>(&array[i], 1));
+ ret.push_back(string<T>(&str[i], 1));
}
tokenStartIdx = i+1;
@@ -1382,10 +851,10 @@ public:
}
}
}
- if ((used - 1) > tokenStartIdx)
- ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], (used - 1) - tokenStartIdx));
- else if ( !ignoreEmptyTokens )
- ret.push_back(string<T,TAlloc>());
+ if (size() > tokenStartIdx)
+ ret.push_back(string<T>(&str[tokenStartIdx], size() - tokenStartIdx));
+ else if (!ignoreEmptyTokens)
+ ret.push_back(string<T>());
return ret.size()-oldSize;
}
@@ -1395,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<T> stl_type;
- const u32 amount = used < new_size ? used : new_size;
- for (u32 i=0; i<amount; ++i)
- array[i] = old_array[i];
+ //! Private constructor
+ string(stl_type &&str) : str(str)
+ {}
- if (allocated < used)
- used = allocated;
+ //! strlen wrapper
+ template <typename U>
+ 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 <typename U>
+ 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;
};
@@ -1456,19 +947,18 @@ static size_t multibyteToWString(string<wchar_t>& 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
{
@@ -1503,19 +993,18 @@ static size_t wStringToMultibyte(string<c8>& 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..a50d497 100644
--- a/include/irrUString.h
+++ b/include/irrUString.h
@@ -54,7 +54,6 @@
#include <ostream>
#include "irrTypes.h"
-#include "irrAllocator.h"
#include "irrArray.h"
#include "irrMath.h"
#include "irrString.h"
@@ -227,7 +226,6 @@ inline EUTF_ENCODE determineUnicodeBOM(const char* data)
//! UTF-16 string class.
-template <typename TAlloc = irrAllocator<uchar16_t> >
class ustring16
{
public:
@@ -240,7 +238,7 @@ public:
class _ustring16_iterator_access
{
public:
- _ustring16_iterator_access(const ustring16<TAlloc>* s, u32 p) : ref(s), pos(p) {}
+ _ustring16_iterator_access(const ustring16* s, u32 p) : ref(s), pos(p) {}
//! Allow the class to be interpreted as a single UTF-32 character.
operator uchar32_t() const
@@ -395,7 +393,7 @@ public:
//! Sets a uchar32_t at our current position.
void _set(uchar32_t c)
{
- ustring16<TAlloc>* ref2 = const_cast<ustring16<TAlloc>*>(ref);
+ ustring16* ref2 = const_cast<ustring16*>(ref);
const uchar16_t* a = ref2->c_str();
if (c > 0xFFFF)
{
@@ -424,10 +422,10 @@ public:
}
}
- const ustring16<TAlloc>* ref;
+ const ustring16* ref;
u32 pos;
};
- typedef typename ustring16<TAlloc>::_ustring16_iterator_access access;
+ typedef typename ustring16::_ustring16_iterator_access access;
//! Iterator to iterate through a UTF-16 string.
@@ -453,8 +451,8 @@ public:
//! Constructors.
_ustring16_const_iterator(const _Iter& i) : ref(i.ref), pos(i.pos) {}
- _ustring16_const_iterator(const ustring16<TAlloc>& s) : ref(&s), pos(0) {}
- _ustring16_const_iterator(const ustring16<TAlloc>& s, const u32 p) : ref(&s), pos(0)
+ _ustring16_const_iterator(const ustring16& s) : ref(&s), pos(0) {}
+ _ustring16_const_iterator(const ustring16& s, const u32 p) : ref(&s), pos(0)
{
if (ref->size_raw() == 0 || p == 0)
return;
@@ -705,7 +703,7 @@ public:
}
protected:
- const ustring16<TAlloc>* ref;
+ const ustring16* ref;
u32 pos;
};
@@ -730,8 +728,8 @@ public:
//! Constructors.
_ustring16_iterator(const _Iter& i) : _ustring16_const_iterator(i) {}
- _ustring16_iterator(const ustring16<TAlloc>& s) : _ustring16_const_iterator(s) {}
- _ustring16_iterator(const ustring16<TAlloc>& s, const u32 p) : _ustring16_const_iterator(s, p) {}
+ _ustring16_iterator(const ustring16& s) : _ustring16_const_iterator(s) {}
+ _ustring16_iterator(const ustring16& s, const u32 p) : _ustring16_const_iterator(s, p) {}
//! Accesses the full character at the iterator's position.
reference operator*() const
@@ -778,8 +776,8 @@ public:
}
};
- typedef typename ustring16<TAlloc>::_ustring16_iterator iterator;
- typedef typename ustring16<TAlloc>::_ustring16_const_iterator const_iterator;
+ typedef typename ustring16::_ustring16_iterator iterator;
+ typedef typename ustring16::_ustring16_const_iterator const_iterator;
///----------------------///
/// end iterator classes ///
@@ -794,13 +792,13 @@ public:
#else
encoding = unicode::EUTFE_UTF16_LE;
#endif
- array = allocator.allocate(1); // new u16[1];
+ array = new uchar16_t[1];
array[0] = 0x0;
}
//! Constructor
- ustring16(const ustring16<TAlloc>& other)
+ ustring16(const ustring16& other)
: array(0), allocated(0), used(0)
{
#if __BYTE_ORDER == __BIG_ENDIAN
@@ -813,8 +811,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
@@ -993,10 +991,9 @@ public:
//! Constructor for moving a ustring16
- ustring16(ustring16<TAlloc>&& other)
+ ustring16(ustring16&& other)
: array(other.array), encoding(other.encoding), allocated(other.allocated), used(other.used)
{
- //std::cout << "MOVE constructor" << std::endl;
other.array = 0;
other.allocated = 0;
other.used = 0;
@@ -1005,12 +1002,12 @@ public:
//! Destructor
~ustring16()
{
- allocator.deallocate(array); // delete [] array;
+ delete [] array;
}
//! Assignment operator
- ustring16& operator=(const ustring16<TAlloc>& other)
+ ustring16& operator=(const ustring16& other)
{
if (this == &other)
return *this;
@@ -1018,9 +1015,9 @@ public:
used = other.size_raw();
if (used >= allocated)
{
- allocator.deallocate(array); // delete [] array;
+ delete [] array;
allocated = used + 1;
- array = allocator.allocate(used + 1); //new u16[used];
+ array = new uchar16_t[used + 1];
}
const uchar16_t* p = other.c_str();
@@ -1036,12 +1033,11 @@ public:
}
//! Move assignment operator
- ustring16& operator=(ustring16<TAlloc>&& other)
+ ustring16& operator=(ustring16&& other)
{
if (this != &other)
{
- //std::cout << "MOVE operator=" << std::endl;
- allocator.deallocate(array);
+ delete [] array;
array = other.array;
allocated = other.allocated;
@@ -1054,8 +1050,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& operator=(const string<B>& other)
{
*this = other.c_str();
return *this;
@@ -1063,54 +1059,51 @@ public:
//! Assignment operator for UTF-8 strings
- ustring16<TAlloc>& operator=(const uchar8_t* const c)
+ ustring16& operator=(const uchar8_t* const c)
{
if (!array)
{
- array = allocator.allocate(1); //new u16[1];
+ array = new uchar16_t[1];
allocated = 1;
}
used = 0;
array[used] = 0x0;
if (!c) return *this;
- //! Append our string now.
append(c);
return *this;
}
//! Assignment operator for UTF-16 strings
- ustring16<TAlloc>& operator=(const uchar16_t* const c)
+ ustring16& operator=(const uchar16_t* const c)
{
if (!array)
{
- array = allocator.allocate(1); //new u16[1];
+ array = new uchar16_t[1];
allocated = 1;
}
used = 0;
array[used] = 0x0;
if (!c) return *this;
- //! Append our string now.
append(c);
return *this;
}
//! Assignment operator for UTF-32 strings
- ustring16<TAlloc>& operator=(const uchar32_t* const c)
+ ustring16& operator=(const uchar32_t* const c)
{
if (!array)
{
- array = allocator.allocate(1); //new u16[1];
+ array = new uchar16_t[1];
allocated = 1;
}
used = 0;
array[used] = 0x0;
if (!c) return *this;
- //! Append our string now.
append(c);
return *this;
}
@@ -1120,7 +1113,7 @@ public:
/** Note that this assumes that a correct unicode string is stored in the wchar_t string.
Since wchar_t changes depending on its platform, it could either be a UTF-8, -16, or -32 string.
This function assumes you are storing the correct unicode encoding inside the wchar_t string. **/
- ustring16<TAlloc>& operator=(const wchar_t* const c)
+ ustring16& operator=(const wchar_t* const c)
{
if (sizeof(wchar_t) == 4)
*this = reinterpret_cast<const uchar32_t* const>(c);
@@ -1136,7 +1129,7 @@ public:
//! Assignment operator for other strings.
/** Note that this assumes that a correct unicode string is stored in the string. **/
template <class B>
- ustring16<TAlloc>& operator=(const B* const c)
+ ustring16& operator=(const B* const c)
{
if (sizeof(B) == 4)
*this = reinterpret_cast<const uchar32_t* const>(c);
@@ -1183,7 +1176,7 @@ public:
//! Equality operator
- bool operator ==(const ustring16<TAlloc>& other) const
+ bool operator ==(const ustring16& other) const
{
for(u32 i=0; array[i] && other.array[i]; ++i)
if (array[i] != other.array[i])
@@ -1194,7 +1187,7 @@ public:
//! Is smaller comparator
- bool operator <(const ustring16<TAlloc>& other) const
+ bool operator <(const ustring16& other) const
{
for(u32 i=0; array[i] && other.array[i]; ++i)
{
@@ -1215,7 +1208,7 @@ public:
//! Inequality operator
- bool operator !=(const ustring16<TAlloc>& other) const
+ bool operator !=(const ustring16& other) const
{
return !(*this == other);
}
@@ -1256,7 +1249,7 @@ public:
//! \param other Other string to compare to.
//! \param n Number of characters to compare.
//! \return True if the n first characters of both strings are equal.
- bool equalsn(const ustring16<TAlloc>& other, u32 n) const
+ bool equalsn(const ustring16& other, u32 n) const
{
u32 i;
const uchar16_t* oa = other.c_str();
@@ -1292,7 +1285,7 @@ public:
//! Appends a character to this ustring16
//! \param character The character to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(uchar32_t character)
+ ustring16& append(uchar32_t character)
{
if (used + 2 >= allocated)
reallocate(used + 2);
@@ -1323,7 +1316,7 @@ public:
//! \param other The UTF-8 string to append.
//! \param length The length of the string to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(const uchar8_t* const other, u32 length=0xffffffff)
+ ustring16& append(const uchar8_t* const other, u32 length=0xffffffff)
{
if (!other)
return *this;
@@ -1499,7 +1492,7 @@ public:
//! \param other The UTF-16 string to append.
//! \param length The length of the string to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(const uchar16_t* const other, u32 length=0xffffffff)
+ ustring16& append(const uchar16_t* const other, u32 length=0xffffffff)
{
if (!other)
return *this;
@@ -1564,7 +1557,7 @@ public:
//! \param other The UTF-32 string to append.
//! \param length The length of the string to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(const uchar32_t* const other, u32 length=0xffffffff)
+ ustring16& append(const uchar32_t* const other, u32 length=0xffffffff)
{
if (!other)
return *this;
@@ -1640,7 +1633,7 @@ public:
//! Appends a ustring16 to this ustring16
//! \param other The string to append to this one.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(const ustring16<TAlloc>& other)
+ ustring16& append(const ustring16& other)
{
const uchar16_t* oa = other.c_str();
@@ -1663,7 +1656,7 @@ public:
//! \param other The string to append to this one.
//! \param length How many characters of the other string to add to this one.
//! \return A reference to our current string.
- ustring16<TAlloc>& append(const ustring16<TAlloc>& other, u32 length)
+ ustring16& append(const ustring16& other, u32 length)
{
if (other.size() == 0)
return *this;
@@ -1883,7 +1876,7 @@ public:
//! \param str The string to find.
//! \param start The start position of the search.
//! \return Positions where the ustring16 has been found, or -1 if not found.
- s32 find(const ustring16<TAlloc>& str, const u32 start = 0) const
+ s32 find(const ustring16& str, const u32 start = 0) const
{
u32 my_size = size();
u32 their_size = str.size();
@@ -1921,7 +1914,7 @@ public:
//! \param str The string to find.
//! \param start The start position of the search.
//! \return Positions where the string has been found, or -1 if not found.
- s32 find_raw(const ustring16<TAlloc>& str, const u32 start = 0) const
+ s32 find_raw(const ustring16& str, const u32 start = 0) const
{
const uchar16_t* data = str.c_str();
if (data && *data)
@@ -1954,18 +1947,18 @@ public:
//! \param begin: Start of substring.
//! \param length: Length of substring.
//! \return A reference to our current string.
- ustring16<TAlloc> subString(u32 begin, s32 length) const
+ ustring16 subString(u32 begin, s32 length) const
{
u32 len = size();
// if start after ustring16
// or no proper substring length
if ((length <= 0) || (begin>=len))
- return ustring16<TAlloc>("");
+ return ustring16("");
// clamp length to maximal value
if ((length+begin) > len)
length = len-begin;
- ustring16<TAlloc> o;
+ ustring16 o;
o.reserve((length+1) * 2);
const_iterator i(*this, begin);
@@ -1983,7 +1976,7 @@ public:
//! Appends a character to this ustring16.
//! \param c Character to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (char c)
+ ustring16& operator += (char c)
{
append((uchar32_t)c);
return *this;
@@ -1993,7 +1986,7 @@ public:
//! Appends a character to this ustring16.
//! \param c Character to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (uchar32_t c)
+ ustring16& operator += (uchar32_t c)
{
append(c);
return *this;
@@ -2003,7 +1996,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (short c)
+ ustring16& operator += (short c)
{
append(core::stringc(c));
return *this;
@@ -2013,7 +2006,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (unsigned short c)
+ ustring16& operator += (unsigned short c)
{
append(core::stringc(c));
return *this;
@@ -2023,7 +2016,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (int c)
+ ustring16& operator += (int c)
{
append(core::stringc(c));
return *this;
@@ -2033,7 +2026,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (unsigned int c)
+ ustring16& operator += (unsigned int c)
{
append(core::stringc(c));
return *this;
@@ -2043,7 +2036,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (long c)
+ ustring16& operator += (long c)
{
append(core::stringc(c));
return *this;
@@ -2053,7 +2046,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (unsigned long c)
+ ustring16& operator += (unsigned long c)
{
append(core::stringc(c));
return *this;
@@ -2063,7 +2056,7 @@ public:
//! Appends a number to this ustring16.
//! \param c Number to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (double c)
+ ustring16& operator += (double c)
{
append(core::stringc(c));
return *this;
@@ -2073,7 +2066,7 @@ public:
//! Appends a char ustring16 to this ustring16.
//! \param c Char ustring16 to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (const uchar16_t* const c)
+ ustring16& operator += (const uchar16_t* const c)
{
append(c);
return *this;
@@ -2083,7 +2076,7 @@ public:
//! Appends a ustring16 to this ustring16.
//! \param other ustring16 to append.
//! \return A reference to our current string.
- ustring16<TAlloc>& operator += (const ustring16<TAlloc>& other)
+ ustring16& operator += (const ustring16& other)
{
append(other);
return *this;
@@ -2094,12 +2087,12 @@ public:
//! \param toReplace Character to replace.
//! \param replaceWith Character replacing the old one.
//! \return A reference to our current string.
- ustring16<TAlloc>& replace(uchar32_t toReplace, uchar32_t replaceWith)
+ ustring16& replace(uchar32_t toReplace, uchar32_t replaceWith)
{
iterator i(*this, 0);
while (!i.atEnd())
{
- typename ustring16<TAlloc>::access a = *i;
+ typename ustring16::access a = *i;
if ((uchar32_t)a == toReplace)
a = replaceWith;
++i;
@@ -2112,7 +2105,7 @@ public:
//! \param toReplace The string to replace.
//! \param replaceWith The string replacing the old one.
//! \return A reference to our current string.
- ustring16<TAlloc>& replace(const ustring16<TAlloc>& toReplace, const ustring16<TAlloc>& replaceWith)
+ ustring16& replace(const ustring16& toReplace, const ustring16& replaceWith)
{
if (toReplace.size() == 0)
return *this;
@@ -2223,7 +2216,7 @@ public:
//! Removes characters from a ustring16..
//! \param c The character to remove.
//! \return A reference to our current string.
- ustring16<TAlloc>& remove(uchar32_t c)
+ ustring16& remove(uchar32_t c)
{
u32 pos = 0;
u32 found = 0;
@@ -2259,7 +2252,7 @@ public:
//! Removes a ustring16 from the ustring16.
//! \param toRemove The string to remove.
//! \return A reference to our current string.
- ustring16<TAlloc>& remove(const ustring16<TAlloc>& toRemove)
+ ustring16& remove(const ustring16& toRemove)
{
u32 size = toRemove.size_raw();
if (size == 0) return *this;
@@ -2294,7 +2287,7 @@ public:
//! Removes characters from the ustring16.
//! \param characters The characters to remove.
//! \return A reference to our current string.
- ustring16<TAlloc>& removeChars(const ustring16<TAlloc>& characters)
+ ustring16& removeChars(const ustring16& characters)
{
if (characters.size_raw() == 0)
return *this;
@@ -2344,7 +2337,7 @@ public:
//! Removes the specified characters (by default, Latin-1 whitespace) from the begining and the end of the ustring16.
//! \param whitespace The characters that are to be considered as whitespace.
//! \return A reference to our current string.
- ustring16<TAlloc>& trim(const ustring16<TAlloc>& whitespace = " \t\n\r")
+ ustring16& trim(const ustring16& whitespace = " \t\n\r")
{
core::array<uchar32_t> utf32white = whitespace.toUTF32();
@@ -2363,7 +2356,7 @@ public:
//! May be slow, because all elements following after the erased element have to be copied.
//! \param index Index of element to be erased.
//! \return A reference to our current string.
- ustring16<TAlloc>& erase(u32 index)
+ ustring16& erase(u32 index)
{
_IRR_DEBUG_BREAK_IF(index>used) // access violation
@@ -2384,7 +2377,7 @@ public:
//! Validate the existing ustring16, checking for valid surrogate pairs and checking for proper termination.
//! \return A reference to our current string.
- ustring16<TAlloc>& validate()
+ ustring16& validate()
{
// Validate all unicode characters.
for (u32 i=0; i<allocated; ++i)
@@ -2485,7 +2478,7 @@ public:
{
if ((!ignoreEmptyTokens || pos - lastpos != 0) &&
!lastWasSeparator)
- ret.push_back(ustring16<TAlloc>(&array[lastpospos], pos - lastpos));
+ ret.push_back(ustring16(&array[lastpospos], pos - lastpos));
foundSeparator = true;
lastpos = (keepSeparators ? pos : pos + 1);
lastpospos = (keepSeparators ? i.getPos() : i.getPos() + 1);
@@ -2498,7 +2491,7 @@ public:
}
u32 s = size() + 1;
if (s > lastpos)
- ret.push_back(ustring16<TAlloc>(&array[lastpospos], s - lastpos));
+ ret.push_back(ustring16(&array[lastpospos], s - lastpos));
return ret.size()-oldSize;
}
@@ -2521,7 +2514,7 @@ public:
\return The number of resulting substrings
*/
template<class container>
- u32 split(container& ret, const ustring16<TAlloc>& c, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
+ u32 split(container& ret, const ustring16& c, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
{
core::array<uchar32_t> v = c.toUTF32();
return split(ret, v.pointer(), v.size(), ignoreEmptyTokens, keepSeparators);
@@ -2548,7 +2541,7 @@ public:
//! \param c The character to insert.
//! \param pos The position to insert the character.
//! \return A reference to our current string.
- ustring16<TAlloc>& insert(uchar32_t c, u32 pos)
+ ustring16& insert(uchar32_t c, u32 pos)
{
u8 len = (c > 0xFFFF ? 2 : 1);
@@ -2583,7 +2576,7 @@ public:
//! \param c The string to insert.
//! \param pos The position to insert the string.
//! \return A reference to our current string.
- ustring16<TAlloc>& insert(const ustring16<TAlloc>& c, u32 pos)
+ ustring16& insert(const ustring16& c, u32 pos)
{
u32 len = c.size_raw();
if (len == 0) return *this;
@@ -2613,7 +2606,7 @@ public:
//! \param c The character to insert.
//! \param pos The position to insert the character.
//! \return A reference to our current string.
- ustring16<TAlloc>& insert_raw(uchar16_t c, u32 pos)
+ ustring16& insert_raw(uchar16_t c, u32 pos)
{
if (used + 1 >= allocated)
reallocate(used + 1);
@@ -2632,7 +2625,7 @@ public:
//! Removes a character from string.
//! \param pos Position of the character to remove.
//! \return A reference to our current string.
- ustring16<TAlloc>& erase_raw(u32 pos)
+ ustring16& erase_raw(u32 pos)
{
for (u32 i=pos; i<=used; ++i)
{
@@ -2648,7 +2641,7 @@ public:
//! \param c The new character.
//! \param pos The position of the character to replace.
//! \return A reference to our current string.
- ustring16<TAlloc>& replace_raw(uchar16_t c, u32 pos)
+ ustring16& replace_raw(uchar16_t c, u32 pos)
{
array[pos] = c;
return *this;
@@ -3023,7 +3016,7 @@ public:
//! \param data The data stream to load from.
//! \param data_size The length of the data string.
//! \return A reference to our current string.
- ustring16<TAlloc>& loadDataStream(const char* data, size_t data_size)
+ ustring16& loadDataStream(const char* data, size_t data_size)
{
// Clear our string.
*this = "";
@@ -3079,7 +3072,7 @@ private:
{
uchar16_t* old_array = array;
- array = allocator.allocate(new_size + 1); //new u16[new_size];
+ array = new uchar16_t[new_size + 1];
allocated = new_size + 1;
if (old_array == 0) return;
@@ -3092,7 +3085,7 @@ private:
array[used] = 0;
- allocator.deallocate(old_array); // delete [] old_array;
+ delete [] old_array;
}
//--- member variables
@@ -3101,308 +3094,281 @@ private:
unicode::EUTF_ENCODE encoding;
u32 allocated;
u32 used;
- TAlloc allocator;
- //irrAllocator<uchar16_t> allocator;
};
-typedef ustring16<irrAllocator<uchar16_t> > ustring;
+typedef ustring16 ustring;
+/* these cause ambigous overloads errors and don't seem to be actually in use */
+#if 0
//! Appends two ustring16s.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const ustring16& left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a null-terminated unicode string.
-template <typename TAlloc, class B>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const B* const right)
+template <class B>
+inline ustring16 operator+(const ustring16& left, const B* const right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a null-terminated unicode string.
-template <class B, typename TAlloc>
-inline ustring16<TAlloc> operator+(const B* const left, const ustring16<TAlloc>& right)
+template <class B>
+inline ustring16 operator+(const B* const left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! 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 B>
+inline ustring16 operator+(const ustring16& left, const string<B>& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! 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 B>
+inline ustring16 operator+(const string<B>& left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a std::basic_string.
-template <typename TAlloc, typename B, typename A, typename BAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const std::basic_string<B, A, BAlloc>& right)
+template <typename B, typename A, typename BAlloc>
+inline ustring16 operator+(const ustring16& left, const std::basic_string<B, A, BAlloc>& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a std::basic_string.
-template <typename TAlloc, typename B, typename A, typename BAlloc>
-inline ustring16<TAlloc> operator+(const std::basic_string<B, A, BAlloc>& left, const ustring16<TAlloc>& right)
+template <typename B, typename A, typename BAlloc>
+inline ustring16 operator+(const std::basic_string<B, A, BAlloc>& left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a char.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const char right)
+inline ustring16 operator+(const ustring16& left, const char right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a char.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const char left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const char left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a uchar32_t.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const uchar32_t right)
+inline ustring16 operator+(const ustring16& left, const uchar32_t right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a uchar32_t.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const uchar32_t left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const uchar32_t left, const ustring16& right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += right;
return ret;
}
//! Appends a ustring16 and a short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const short right)
+inline ustring16 operator+(const ustring16& left, const short right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and a short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const short left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const short left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and an unsigned short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const unsigned short right)
+inline ustring16 operator+(const ustring16& left, const unsigned short right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and an unsigned short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned short left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const unsigned short left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and an int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const int right)
+inline ustring16 operator+(const ustring16& left, const int right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and an int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const int left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const int left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and an unsigned int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const unsigned int right)
+inline ustring16 operator+(const ustring16& left, const unsigned int right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and an unsigned int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned int left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const unsigned int left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and a long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const long right)
+inline ustring16 operator+(const ustring16& left, const long right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and a long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const long left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const long left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and an unsigned long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const unsigned long right)
+inline ustring16 operator+(const ustring16& left, const unsigned long right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and an unsigned long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned long left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const unsigned long left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and a float.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const float right)
+inline ustring16 operator+(const ustring16& left, const float right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and a float.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const float left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const float left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends a ustring16 and a double.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const ustring16<TAlloc>& left, const double right)
+inline ustring16 operator+(const ustring16& left, const double right)
{
- ustring16<TAlloc> ret(left);
+ ustring16 ret(left);
ret += core::stringc(right);
return ret;
}
//! Appends a ustring16 and a double.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const double left, const ustring16<TAlloc>& right)
+inline ustring16 operator+(const double left, const ustring16& right)
{
- ustring16<TAlloc> ret((core::stringc(left)));
+ ustring16 ret((core::stringc(left)));
ret += right;
return ret;
}
//! Appends two ustring16s.
-template <typename TAlloc>
-inline ustring16<TAlloc>&& operator+(const ustring16<TAlloc>& left, ustring16<TAlloc>&& right)
+inline ustring16&& operator+(const ustring16& left, ustring16&& right)
{
- //std::cout << "MOVE operator+(&, &&)" << std::endl;
right.insert(left, 0);
return std::move(right);
}
//! Appends two ustring16s.
-template <typename TAlloc>
-inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, const ustring16<TAlloc>& right)
+inline ustring16&& operator+(ustring16&& left, const ustring16& right)
{
- //std::cout << "MOVE operator+(&&, &)" << std::endl;
left.append(right);
return std::move(left);
}
//! Appends two ustring16s.
-template <typename TAlloc>
-inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, ustring16<TAlloc>&& right)
+inline ustring16&& operator+(ustring16&& left, ustring16&& right)
{
- //std::cout << "MOVE operator+(&&, &&)" << std::endl;
if ((right.size_raw() <= left.capacity() - left.size_raw()) ||
(right.capacity() - right.size_raw() < left.size_raw()))
{
@@ -3418,68 +3384,61 @@ inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, ustring16<TAlloc>
//! Appends a ustring16 and a null-terminated unicode string.
-template <typename TAlloc, class B>
-inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, const B* const right)
+template <class B>
+inline ustring16&& operator+(ustring16&& left, const B* const right)
{
- //std::cout << "MOVE operator+(&&, B*)" << std::endl;
left.append(right);
return std::move(left);
}
//! Appends a ustring16 and a null-terminated unicode string.
-template <class B, typename TAlloc>
-inline ustring16<TAlloc>&& operator+(const B* const left, ustring16<TAlloc>&& right)
+template <class B>
+inline ustring16&& operator+(const B* const left, ustring16&& right)
{
- //std::cout << "MOVE operator+(B*, &&)" << std::endl;
right.insert(left, 0);
return std::move(right);
}
//! 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 B>
+inline ustring16&& operator+(const string<B>& left, ustring16&& right)
{
- //std::cout << "MOVE operator+(&, &&)" << std::endl;
right.insert(left, 0);
return std::move(right);
}
//! 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 B>
+inline ustring16&& operator+(ustring16&& left, const string<B>& right)
{
- //std::cout << "MOVE operator+(&&, &)" << std::endl;
left.append(right);
return std::move(left);
}
//! Appends a ustring16 and a std::basic_string.
-template <typename TAlloc, typename B, typename A, typename BAlloc>
-inline ustring16<TAlloc>&& operator+(const std::basic_string<B, A, BAlloc>& left, ustring16<TAlloc>&& right)
+template <typename B, typename A, typename BAlloc>
+inline ustring16&& operator+(const std::basic_string<B, A, BAlloc>& left, ustring16&& right)
{
- //std::cout << "MOVE operator+(&, &&)" << std::endl;
- right.insert(core::ustring16<TAlloc>(left), 0);
+ right.insert(core::ustring16(left), 0);
return std::move(right);
}
//! Appends a ustring16 and a std::basic_string.
-template <typename TAlloc, typename B, typename A, typename BAlloc>
-inline ustring16<TAlloc>&& operator+(ustring16<TAlloc>&& left, const std::basic_string<B, A, BAlloc>& right)
+template <typename B, typename A, typename BAlloc>
+inline ustring16&& operator+(ustring16&& left, const std::basic_string<B, A, BAlloc>& right)
{
- //std::cout << "MOVE operator+(&&, &)" << std::endl;
left.append(right);
return std::move(left);
}
//! Appends a ustring16 and a char.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const char right)
+inline ustring16 operator+(ustring16&& left, const char right)
{
left.append((uchar32_t)right);
return std::move(left);
@@ -3487,8 +3446,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const char right)
//! Appends a ustring16 and a char.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const char left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const char left, ustring16&& right)
{
right.insert((uchar32_t)left, 0);
return std::move(right);
@@ -3496,8 +3454,7 @@ inline ustring16<TAlloc> operator+(const char left, ustring16<TAlloc>&& right)
//! Appends a ustring16 and a uchar32_t.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const uchar32_t right)
+inline ustring16 operator+(ustring16&& left, const uchar32_t right)
{
left.append(right);
return std::move(left);
@@ -3505,8 +3462,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const uchar32_t rig
//! Appends a ustring16 and a uchar32_t.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const uchar32_t left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const uchar32_t left, ustring16&& right)
{
right.insert(left, 0);
return std::move(right);
@@ -3514,8 +3470,7 @@ inline ustring16<TAlloc> operator+(const uchar32_t left, ustring16<TAlloc>&& rig
//! Appends a ustring16 and a short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const short right)
+inline ustring16 operator+(ustring16&& left, const short right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3523,8 +3478,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const short right)
//! Appends a ustring16 and a short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const short left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const short left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3532,8 +3486,7 @@ inline ustring16<TAlloc> operator+(const short left, ustring16<TAlloc>&& right)
//! Appends a ustring16 and an unsigned short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned short right)
+inline ustring16 operator+(ustring16&& left, const unsigned short right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3541,8 +3494,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned shor
//! Appends a ustring16 and an unsigned short.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned short left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const unsigned short left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3550,8 +3502,7 @@ inline ustring16<TAlloc> operator+(const unsigned short left, ustring16<TAlloc>&
//! Appends a ustring16 and an int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const int right)
+inline ustring16 operator+(ustring16&& left, const int right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3559,8 +3510,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const int right)
//! Appends a ustring16 and an int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const int left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const int left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3568,8 +3518,7 @@ inline ustring16<TAlloc> operator+(const int left, ustring16<TAlloc>&& right)
//! Appends a ustring16 and an unsigned int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned int right)
+inline ustring16 operator+(ustring16&& left, const unsigned int right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3577,8 +3526,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned int
//! Appends a ustring16 and an unsigned int.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned int left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const unsigned int left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3586,8 +3534,7 @@ inline ustring16<TAlloc> operator+(const unsigned int left, ustring16<TAlloc>&&
//! Appends a ustring16 and a long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const long right)
+inline ustring16 operator+(ustring16&& left, const long right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3595,8 +3542,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const long right)
//! Appends a ustring16 and a long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const long left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const long left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3604,8 +3550,7 @@ inline ustring16<TAlloc> operator+(const long left, ustring16<TAlloc>&& right)
//! Appends a ustring16 and an unsigned long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned long right)
+inline ustring16 operator+(ustring16&& left, const unsigned long right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3613,8 +3558,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const unsigned long
//! Appends a ustring16 and an unsigned long.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const unsigned long left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const unsigned long left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3622,8 +3566,7 @@ inline ustring16<TAlloc> operator+(const unsigned long left, ustring16<TAlloc>&&
//! Appends a ustring16 and a float.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const float right)
+inline ustring16 operator+(ustring16&& left, const float right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3631,8 +3574,7 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const float right)
//! Appends a ustring16 and a float.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const float left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const float left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
@@ -3640,8 +3582,7 @@ inline ustring16<TAlloc> operator+(const float left, ustring16<TAlloc>&& right)
//! Appends a ustring16 and a double.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const double right)
+inline ustring16 operator+(ustring16&& left, const double right)
{
left.append(core::stringc(right));
return std::move(left);
@@ -3649,25 +3590,23 @@ inline ustring16<TAlloc> operator+(ustring16<TAlloc>&& left, const double right)
//! Appends a ustring16 and a double.
-template <typename TAlloc>
-inline ustring16<TAlloc> operator+(const double left, ustring16<TAlloc>&& right)
+inline ustring16 operator+(const double left, ustring16&& right)
{
right.insert(core::stringc(left), 0);
return std::move(right);
}
+#endif
//! Writes a ustring16 to an ostream.
-template <typename TAlloc>
-inline std::ostream& operator<<(std::ostream& out, const ustring16<TAlloc>& in)
+inline std::ostream& operator<<(std::ostream& out, const ustring16& in)
{
out << in.toUTF8_s().c_str();
return out;
}
//! Writes a ustring16 to a wostream.
-template <typename TAlloc>
-inline std::wostream& operator<<(std::wostream& out, const ustring16<TAlloc>& in)
+inline std::wostream& operator<<(std::wostream& out, const ustring16& in)
{
out << in.toWCHAR_s().c_str();
return out;
diff --git a/source/Irrlicht/CGUITabControl.cpp b/source/Irrlicht/CGUITabControl.cpp
index 04f36f9..30a31c3 100644
--- a/source/Irrlicht/CGUITabControl.cpp
+++ b/source/Irrlicht/CGUITabControl.cpp
@@ -454,7 +454,7 @@ void CGUITabControl::scrollRight()
recalculateScrollBar();
}
-s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl) const
+s32 CGUITabControl::calcTabWidth(IGUIFont* font, const wchar_t* text) const
{
if ( !font )
return 0;
@@ -463,26 +463,11 @@ s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, b
if ( TabMaxWidth > 0 && len > TabMaxWidth )
len = TabMaxWidth;
- // check if we miss the place to draw the tab-button
- if ( withScrollControl && ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
- {
- s32 tabMinWidth = font->getDimension(L"A").Width;
- if ( TabExtraWidth > 0 && TabExtraWidth > tabMinWidth )
- tabMinWidth = TabExtraWidth;
-
- if ( ScrollControl && pos+tabMinWidth <= UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
- {
- len = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;
- }
- }
return len;
}
-bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl)
+bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl, s32 *pos_rightmost)
{
- if ( startIndex >= (s32)Tabs.size() )
- startIndex -= 1;
-
if ( startIndex < 0 )
startIndex = 0;
@@ -492,17 +477,18 @@ bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl)
IGUIFont* font = skin->getFont();
- core::rect<s32> frameRect(AbsoluteRect);
-
if (Tabs.empty())
return false;
if (!font)
return false;
- s32 pos = frameRect.UpperLeftCorner.X + 2;
+ s32 pos = AbsoluteRect.UpperLeftCorner.X + 2;
+ const s32 pos_right = withScrollControl ?
+ UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 :
+ AbsoluteRect.LowerRightCorner.X;
- for (s32 i=startIndex; i<(s32)Tabs.size(); ++i)
+ for (s32 i = startIndex; i < (s32)Tabs.size(); ++i)
{
// get Text
const wchar_t* text = 0;
@@ -511,26 +497,71 @@ bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl)
text = Tabs[i]->getText();
// get text length
- s32 len = calcTabWidth(pos, font, text, false); // always without withScrollControl here or len would be shortened
-
- frameRect.LowerRightCorner.X += len;
-
- frameRect.UpperLeftCorner.X = pos;
- frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;
+ s32 len = calcTabWidth(font, text); // always without withScrollControl here or len would be shortened
pos += len;
}
- if ( withScrollControl && pos > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2)
- return true;
-
- if ( !withScrollControl && pos > AbsoluteRect.LowerRightCorner.X )
+ if (pos > pos_right)
return true;
}
+ if (pos_rightmost)
+ *pos_rightmost = pos;
return false;
}
+s32 CGUITabControl::calculateScrollIndexFromActive()
+{
+ if (!ScrollControl || Tabs.empty())
+ return 0;
+
+ IGUISkin *skin = Environment->getSkin();
+ if (!skin)
+ return false;
+
+ IGUIFont *font = skin->getFont();
+ if (!font)
+ return false;
+
+ const s32 pos_left = AbsoluteRect.UpperLeftCorner.X + 2;
+ const s32 pos_right = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2;
+
+ // Move from center to the left border left until it is reached
+ s32 pos_cl = (pos_left + pos_right) / 2;
+ s32 i = ActiveTabIndex;
+ for (; i > 0; --i) {
+ if (!Tabs[i])
+ continue;
+
+ s32 len = calcTabWidth(font, Tabs[i]->getText());
+ if (i == ActiveTabIndex)
+ len /= 2;
+ if (pos_cl - len < pos_left)
+ break;
+
+ pos_cl -= len;
+ }
+ if (i == 0)
+ return i;
+
+ // Is scrolling to right still possible?
+ s32 pos_rr = 0;
+ if (needScrollControl(i, true, &pos_rr))
+ return i; // Yes? -> OK
+
+ // No? -> Decrease "i" more. Append tabs until scrolling becomes necessary
+ for (--i; i > 0; --i) {
+ if (!Tabs[i])
+ continue;
+
+ pos_rr += calcTabWidth(font, Tabs[i]->getText());
+ if (pos_rr > pos_right)
+ break;
+ }
+ return i + 1;
+}
+
core::rect<s32> CGUITabControl::calcTabPos()
{
core::rect<s32> r;
@@ -613,7 +644,7 @@ void CGUITabControl::draw()
IGUITab *activeTab = 0;
// Draw all tab-buttons except the active one
- for (u32 i=CurrentScrollTabIndex; i<Tabs.size(); ++i)
+ for (u32 i = CurrentScrollTabIndex; i < Tabs.size() && !needRightScroll; ++i)
{
// get Text
const wchar_t* text = 0;
@@ -621,11 +652,13 @@ void CGUITabControl::draw()
text = Tabs[i]->getText();
// get text length
- s32 len = calcTabWidth(pos, font, text, true);
- if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
- {
- needRightScroll = true;
- break;
+ s32 len = calcTabWidth(font, text);
+ if (ScrollControl) {
+ s32 space = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;
+ if (space < len) {
+ needRightScroll = true;
+ len = space;
+ }
}
frameRect.LowerRightCorner.X += len;
@@ -794,6 +827,7 @@ s32 CGUITabControl::getTabExtraWidth() const
void CGUITabControl::recalculateScrollBar()
{
+ // Down: to right, Up: to left
if (!UpButton || !DownButton)
return;
@@ -894,7 +928,8 @@ s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const
if (!frameRect.isPointInside(p))
return -1;
- for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i)
+ bool abort = false;
+ for (s32 i = CurrentScrollTabIndex; i < (s32)Tabs.size() && !abort; ++i)
{
// get Text
const wchar_t* text = 0;
@@ -902,9 +937,15 @@ s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const
text = Tabs[i]->getText();
// get text length
- s32 len = calcTabWidth(pos, font, text, true);
- if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 )
- return -1;
+ s32 len = calcTabWidth(font, text);
+ if (ScrollControl) {
+ // TODO: merge this with draw() ?
+ s32 space = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos;
+ if (space < len) {
+ abort = true;
+ len = space;
+ }
+ }
frameRect.UpperLeftCorner.X = pos;
frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len;
@@ -915,6 +956,7 @@ s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const
{
return i;
}
+
}
return -1;
}
@@ -948,6 +990,11 @@ bool CGUITabControl::setActiveTab(s32 idx)
Parent->OnEvent(event);
}
+ if (ScrollControl) {
+ CurrentScrollTabIndex = calculateScrollIndexFromActive();
+ recalculateScrollBar();
+ }
+
return true;
}
diff --git a/source/Irrlicht/CGUITabControl.h b/source/Irrlicht/CGUITabControl.h
index ffc31f2..d5e8315 100644
--- a/source/Irrlicht/CGUITabControl.h
+++ b/source/Irrlicht/CGUITabControl.h
@@ -153,8 +153,11 @@ namespace gui
void scrollLeft();
void scrollRight();
- bool needScrollControl( s32 startIndex=0, bool withScrollControl=false );
- s32 calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl ) const;
+ //! Indicates whether the tabs overflow in X direction
+ bool needScrollControl( s32 startIndex=0, bool withScrollControl=false, s32 *pos_rightmost=nullptr );
+ //! Left index calculation based on the selected tab
+ s32 calculateScrollIndexFromActive();
+ s32 calcTabWidth(IGUIFont* font, const wchar_t* text) const;
core::rect<s32> calcTabPos();
void setVisibleTab(s32 idx);
void removeTabButNotChild(s32 idx);
diff --git a/source/Irrlicht/CIrrDeviceSDL.cpp b/source/Irrlicht/CIrrDeviceSDL.cpp
index 84a6d64..12574d5 100644
--- a/source/Irrlicht/CIrrDeviceSDL.cpp
+++ b/source/Irrlicht/CIrrDeviceSDL.cpp
@@ -1197,6 +1197,25 @@ void CIrrDeviceSDL::createKeyMap()
KeyMap.sort();
}
+void CIrrDeviceSDL::CCursorControl::initCursors()
+{
+ Cursors.reserve(gui::ECI_COUNT);
+
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW)); // ECI_NORMAL
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR)); // ECI_CROSS
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND)); // ECI_HAND
+ Cursors.emplace_back(nullptr); // ECI_HELP
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM)); // ECI_IBEAM
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO)); // ECI_NO
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT)); // ECI_WAIT
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL)); // ECI_SIZEALL
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW)); // ECI_SIZENESW
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE)); // ECI_SIZENWSE
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS)); // ECI_SIZENS
+ Cursors.emplace_back(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE)); // ECI_SIZEWE
+ Cursors.emplace_back(nullptr); // ECI_UP
+}
+
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
diff --git a/source/Irrlicht/CIrrDeviceSDL.h b/source/Irrlicht/CIrrDeviceSDL.h
index e858399..ab809dd 100644
--- a/source/Irrlicht/CIrrDeviceSDL.h
+++ b/source/Irrlicht/CIrrDeviceSDL.h
@@ -23,6 +23,8 @@
#include <SDL.h>
#include <SDL_syswm.h>
+#include <memory>
+
namespace irr
{
@@ -104,6 +106,7 @@ namespace irr
CCursorControl(CIrrDeviceSDL* dev)
: Device(dev), IsVisible(true)
{
+ initCursors();
}
//! Changes the visible state of the mouse cursor.
@@ -186,6 +189,22 @@ namespace irr
}
}
+ void setActiveIcon(gui::ECURSOR_ICON iconId) override
+ {
+ ActiveIcon = iconId;
+ if (iconId > Cursors.size() || !Cursors[iconId]) {
+ iconId = gui::ECI_NORMAL;
+ if (iconId > Cursors.size() || !Cursors[iconId])
+ return;
+ }
+ SDL_SetCursor(Cursors[iconId].get());
+ }
+
+ gui::ECURSOR_ICON getActiveIcon() const override
+ {
+ return ActiveIcon;
+ }
+
private:
void updateCursorPos()
@@ -222,9 +241,20 @@ namespace irr
#endif
}
+ void initCursors();
+
CIrrDeviceSDL* Device;
core::position2d<s32> CursorPos;
bool IsVisible;
+
+ struct CursorDeleter {
+ void operator()(SDL_Cursor *ptr) {
+ if (ptr)
+ SDL_FreeCursor(ptr);
+ }
+ };
+ std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;
+ gui::ECURSOR_ICON ActiveIcon;
};
private:
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
diff --git a/source/Irrlicht/COpenGLCoreTexture.h b/source/Irrlicht/COpenGLCoreTexture.h
index 19ab06b..8897c58 100644
--- a/source/Irrlicht/COpenGLCoreTexture.h
+++ b/source/Irrlicht/COpenGLCoreTexture.h
@@ -82,7 +82,7 @@ public:
{
if ( OriginalSize == Size && OriginalColorFormat == ColorFormat )
{
- Images[i]->setMipMapsData( images[i]->getMipMapsData(), false, true);
+ Images[i]->setMipMapsData( images[i]->getMipMapsData(), false);
}
else
{