Panagiotis Christopoulos Charitos 11 лет назад
Родитель
Сommit
f69932c5a6

+ 12 - 6
include/anki/math/Axisang.h

@@ -21,15 +21,18 @@ public:
 	/// @name Constructors
 	/// @{
 	explicit TAxisang()
-		: m_ang(0.0), m_axis(0.0)
+	:	m_ang(0.0), 
+		m_axis(0.0)
 	{}
 	
 	TAxisang(const TAxisang& b)
-		: m_ang(b.ang), m_axis(b.axis)
+	:	m_ang(b.ang), 
+		m_axis(b.axis)
 	{}
 
 	explicit TAxisang(const T rad, const TVec3<T>& axis)
-		: m_ang(rad), m_axis(axis)
+	:	m_ang(rad), 
+		m_axis(axis)
 	{}
 
 	explicit TAxisang(const TQuat<T>& q)
@@ -186,10 +189,13 @@ public:
 
 	/// @name Other
 	/// @{
-	std::string toString() const
+	template<template <typename> class TAlloc>
+	BasicString<TAlloc> toString(
+		typename BasicString<TAlloc>::Allocator& alloc) const
 	{
-		std::string s = "axis: " + m_axis.toString() 
-			+ ", angle: " + std::to_string(m_ang);
+		BasicString<TAlloc> s(alloc);
+		s += "axis: " + m_axis.toString(alloc) 
+			+ ", angle: " + BasicString<TAlloc>::toString(m_ang, alloc);
 		return s;
 	}
 	/// @}

+ 8 - 4
include/anki/math/Euler.h

@@ -156,10 +156,14 @@ public:
 
 	/// @name Other
 	/// @{
-	String toString() const
-	{
-		String s = std::to_string(x()) + " " + std::to_string(y())
-			+ " " + std::to_string(z());
+	template<template <typename> class TAlloc>
+	BasicString<TAlloc> toString(
+		typename BasicString<TAlloc>::Allocator& alloc) const
+	{
+		BasicString<TAlloc> s(alloc);
+		s = BasicString<TAlloc>::toString(x(), alloc) + CString(" ") 
+			+ BasicString<TAlloc>::toString(y(), alloc) + CString(" ") 
+			+ BasicString<TAlloc>::toString(z(), alloc);
 		return s;
 	}
 	/// @}

+ 7 - 4
include/anki/math/Mat.h

@@ -749,17 +749,20 @@ public:
 		*this = getZero();
 	}
 
-	String toString() const
+	template<template <typename> class TAlloc>
+	BasicString<TAlloc> toString(
+		typename BasicString<TAlloc>::Allocator& alloc) const
 	{
 		const TMat& m = *this;
-		String s;
+		BasicString<TAlloc> s(alloc);
 		for(U j = 0; j < J; j++)
 		{
 			for(U i = 0; i < I; i++)
 			{
-				s += std::to_string(m(j, i)) + " ";
+				s += BasicString<TAlloc>::toString(m(j, i), alloc) 
+					+ CString(" ");
 			}
-			s += "\n";
+			s += CString("\n");
 		}
 		return s;
 	}

+ 9 - 9
include/anki/math/Quat.h

@@ -33,39 +33,39 @@ public:
 	/// @name Constructors
 	/// @{
 	explicit TQuat()
-		: Base()
+	:	Base()
 	{}
 
 	TQuat(const TQuat& b)
-		: Base(b)
+	:	Base(b)
 	{}
 
 	explicit TQuat(const T x_, const T y_, const T z_, const T w_)
-		: Base(x_, y_, z_, w_)
+	:	Base(x_, y_, z_, w_)
 	{}
 
 	explicit TQuat(const T f)
-		: Base(f)
+	:	Base(f)
 	{}
 
 	explicit TQuat(const T arr[])
-		: Base(arr)
+	:	Base(arr)
 	{}
 
 	explicit TQuat(const typename Base::Simd& simd)
-		: Base(simd)
+	:	Base(simd)
 	{}
 
 	explicit TQuat(const TVec2<T>& v, const T z_, const T w_)
-		: Base(v, z_, w_)
+	:	Base(v, z_, w_)
 	{}
 
 	explicit TQuat(const TVec3<T>& v, const T w_)
-		: Base(v, w_)
+	:	Base(v, w_)
 	{}
 
 	explicit TQuat(const TVec4<T>& v)
-		: Base(v)
+	:	Base(v)
 	{}
 
 	explicit TQuat(const TMat3<T>& m3)

+ 8 - 5
include/anki/math/Transform.h

@@ -183,11 +183,14 @@ public:
 		return out;
 	}
 
-	std::string toString() const
-	{
-		return "t: " + m_origin.toString() 
-			+ "\n\nr: " + m_rotation.toString() 
-			+ "\ns: " + std::to_string(m_scale);
+	template<template <typename> class TAlloc>
+	BasicString<TAlloc> toString(
+		typename BasicString<TAlloc>::Allocator& alloc) const
+	{
+		BasicString<TAlloc> out(alloc);
+		out = BasicString<TAlloc>("t: ", alloc) + m_origin.toString(alloc) 
+			+ CString("\n\nr: ") + m_rotation.toString(alloc) 
+			+ CString("\ns: ") + BasicString<TAlloc>::toString(m_scale, alloc);
 	}
 	/// @}
 

+ 5 - 3
include/anki/math/Vec.h

@@ -2155,12 +2155,14 @@ public:
 		return ((*this) * (1.0 - t)) + (v1 * t);
 	}
 
-	String toString() const
+	template<template <typename> class TAlloc>
+	BasicString<TAlloc> toString(
+		typename BasicString<TAlloc>::Allocator& alloc) const
 	{
-		String out;
+		BasicString<TAlloc> out(alloc);
 		for(U i = 0; i < N; i++)
 		{
-			out += std::to_string(m_arr[i]) + " ";
+			out += BasicString<TAlloc>::toString(m_arr[i]) + CString(" ");
 		}
 		return out;
 	}

+ 14 - 10
include/anki/misc/Xml.h

@@ -20,13 +20,15 @@ namespace anki {
 class XmlElement
 {
 	friend class XmlDocument;
+
 public:
 	XmlElement()
 	:	m_el(nullptr)
 	{}
 
 	XmlElement(const XmlElement& b)
-	:	m_el(b.el)
+	:	m_el(b.el),
+		m_alloc(b.m_alloc)
 	{}
 
 	/// If element has something return true
@@ -43,20 +45,20 @@ public:
 	}
 
 	/// Return the text inside a tag
-	const char* getText() const
+	CString getText() const
 	{
 		check();
-		return m_el->GetText();
+		return CString(m_el->GetText());
 	}
 
 	/// Return the text inside as an int
-	I getInt() const;
+	I64 getInt() const;
 
 	/// Return the text inside as a float
 	F64 getFloat() const;
 
 	/// Get a number of floats
-	Vector<F64> getFloats() const;
+	Vector<F64, StackAllocator> getFloats() const;
 
 	/// Return the text inside as a Mat4
 	Mat4 getMat4() const;
@@ -68,17 +70,18 @@ public:
 	Vec4 getVec4() const;
 
 	/// Get a child element quietly
-	XmlElement getChildElementOptional(const char* name) const;
+	XmlElement getChildElementOptional(const CString& name) const;
 
 	/// Get a child element and throw exception if not found
-	XmlElement getChildElement(const char* name) const;
+	XmlElement getChildElement(const CString& name) const;
 
 	/// Get the next element with the same name. Returns empty XmlElement if
 	/// it reached the end of the list
-	XmlElement getNextSiblingElement(const char* name) const;
+	XmlElement getNextSiblingElement(const CString& name) const;
 
 private:
-	tinyxml2::XMLElement* el;
+	tinyxml2::XMLElement* m_el;
+	StackAllocator<U8> m_alloc;
 
 	void check() const
 	{
@@ -98,7 +101,8 @@ public:
 	XmlElement getChildElement(const CString& name)
 	{
 		XmlElement el;
-		el.m_el = m_doc.FirstChildElement(name);
+		el.m_el = m_doc.FirstChildElement(&name[0]);
+		el.m_alloc = alloc;
 		return el;
 	}
 

+ 18 - 0
include/anki/util/Memory.h

@@ -75,6 +75,12 @@ public:
 	/// other's pool to this instance as well
 	HeapMemoryPool& operator=(const HeapMemoryPool& other);
 
+	/// Check if two memory pools are the same one.
+	Bool operator==(const HeapMemoryPool& b) const noexcept
+	{
+		return m_impl == b.m_impl;
+	}
+
 	/// Allocate memory
 	void* allocate(PtrSize size, PtrSize alignment) noexcept;
 
@@ -139,6 +145,12 @@ public:
 	/// other's pool to this instance as well
 	StackMemoryPool& operator=(const StackMemoryPool& other);
 
+	/// Check if two memory pools are the same one.
+	Bool operator==(const StackMemoryPool& b) const noexcept
+	{
+		return m_impl == b.m_impl;
+	}
+
 	/// Allocate aligned memory. The operation is thread safe
 	/// @param size The size to allocate
 	/// @param alignmentBytes The alignment of the returned address
@@ -242,6 +254,12 @@ public:
 	/// other's pool to this instance as well
 	ChainMemoryPool& operator=(const ChainMemoryPool& other);
 
+	/// Check if two memory pools are the same one.
+	Bool operator==(const ChainMemoryPool& b) const noexcept
+	{
+		return m_impl == b.m_impl;
+	}
+
 	/// Allocate memory. This operation is thread safe
 	/// @param size The size to allocate
 	/// @param alignmentBytes The alignment of the returned address

+ 71 - 1
include/anki/util/String.h

@@ -10,6 +10,8 @@
 #include "anki/util/Exception.h"
 #include "anki/util/Array.h"
 #include <cstring>
+#include <cmath> // For HUGE_VAL
+#include <climits> // For LLONG_MAX
 
 namespace anki {
 
@@ -156,6 +158,34 @@ public:
 		return m_length;
 	}
 
+	/// Convert to F64.
+	F64 toF64() const
+	{
+		checkInit();
+		F64 out = std::strtod(m_ptr, nullptr);
+
+		if(out == HUGE_VAL)
+		{
+			throw ANKI_EXCEPTION("Conversion failed");
+		}
+
+		return out;
+	}
+
+	/// Convert to I64.
+	I64 toI64() const
+	{
+		checkInit();
+		I64 out = std::strtoll(m_ptr, nullptr, 10);
+
+		if(out == LLONG_MAX)
+		{
+			throw ANKI_EXCEPTION("Conversion failed");
+		}
+
+		return out;
+	}
+
 private:
 	const Char* m_ptr = nullptr;
 	mutable U16 m_length = 0;
@@ -273,6 +303,19 @@ public:
 		return &m_data[m_data.size() - 1];
 	}
 
+	/// Add strings.
+	Self operator+(const Self& b) const
+	{
+		b.checkInit();
+		return add(&b.m_data[0], b.m_data.size());
+	}
+
+	/// Add strings.
+	Self operator+(const CString& cstr) const
+	{
+		return add(&cstr[0], cstr.getLength() + 1);
+	}
+
 	/// Append another string to this one.
 	template<template <typename> class TTAlloc>
 	Self& operator+=(const BasicString<TTAlloc>& b)
@@ -464,8 +507,20 @@ public:
 		return Self(alloc, CStringType(&buff[0]));
 	}
 
+	/// Convert to F64.
+	F64 toF64() const
+	{
+		return toCString().toF64();
+	}
+
+	/// Convert to I64.
+	I64 toI64() const
+	{
+		return toCString().toI64();
+	}
+
 private:
-	Vector<Char, Allocator> m_data;
+	Vector<Char, TAlloc> m_data;
 
 	void checkInit() const
 	{
@@ -488,6 +543,21 @@ private:
 		m_data.resize(size + strSize - 1);
 		std::memcpy(&m_data[size - 1], str, sizeof(Char) * strSize);
 	}
+
+	Self add(const Char* str, PtrSize strSize)
+	{
+		checkInit();
+
+		Self out(m_data.get_allocator());
+		out.m_data.resize(m_data.size() + strSize - 1);
+
+		std::memcpy(&out.m_data[0], &m_data[0], 
+			(m_data.size() - 1) * sizeof(Char));
+		std::memcpy(&out.m_data[m_data.size() - 1], str, 
+			strSize * sizeof(Char));
+
+		return out;
+	}
 };
 
 /// A common string type that uses heap allocator.

+ 3 - 3
include/anki/util/Vector.h

@@ -16,11 +16,11 @@ namespace anki {
 /// @{
 
 /// A semi-custom implementation of vector
-template<typename T, typename Alloc = std::allocator<T>>
-class Vector: public std::vector<T, Alloc>
+template<typename T, template <typename> class TAlloc = HeapAllocator>
+class Vector: public std::vector<T, TAlloc<T>>
 {
 public:
-	typedef std::vector<T, Alloc> Base;
+	using Base = std::vector<T, TAlloc<T>>;
 
 	using Base::Base;
 	using Base::operator=;

+ 40 - 31
src/misc/Xml.cpp

@@ -14,55 +14,57 @@ namespace anki {
 //==============================================================================
 
 //==============================================================================
-I XmlElement::getInt() const
+I64 XmlElement::getInt() const
 {
 	check();
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
-		throw ANKI_EXCEPTION("Failed to return int. Element: %s", el->Value());
+		throw ANKI_EXCEPTION("Failed to return int. Element: %s", 
+			m_el->Value());
 	}
-	return std::stoi(txt);
+	return std::strtoimax(txt, nullptr, 10);
 }
 
 //==============================================================================
 F64 XmlElement::getFloat() const
 {
 	check();
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
 		throw ANKI_EXCEPTION("Failed to return float. Element: %s", 
-			el->Value());
+			m_el->Value());
 	}
-	return std::stof(txt);
+	return std::strtof(txt, nullptr);
 }
 
 //==============================================================================V
-Vector<F64> XmlElement::getFloats() const
+Vector<F64, StackAllocator> XmlElement::getFloats() const
 {
 	check();
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
 		throw ANKI_EXCEPTION("Failed to return floats. Element: %s",
-			el->Value());
+			m_el->Value());
 	}
 
-	StringList list = StringList::splitString(txt, ' ');
-	Vector<F64> out;
+	BasicStringList<StackAllocator> list(
+		BasicStringList<StackAllocator>::splitString(txt, ' ', m_alloc));
+	Vector<F64, StackAllocator> out;
 	out.resize(list.size());
 
 	try
 	{
 		for(U i = 0; i < out.size(); i++)
 		{
-			out[i] = std::stof(list[i]);
+			out[i] = list[i].toF64();
 		}
 	}
 	catch(const std::exception& e)
 	{
-		throw ANKI_EXCEPTION("Found non-float element for Mat4");
+		throw ANKI_EXCEPTION("Found non-float element for vec of floats");
 	}
 
 	return out;
@@ -73,13 +75,15 @@ Mat4 XmlElement::getMat4() const
 {
 	check();
 
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
 		throw ANKI_EXCEPTION("Failed to return Mat4");
 	}
 
-	StringList list = StringList::splitString(txt, ' ');
+	BasicStringList<StackAllocator> list = 
+		BasicStringList<StackAllocator>::splitString(txt, ' ', m_alloc);
+
 	if(list.size() != 16)
 	{
 		throw ANKI_EXCEPTION("Expecting 16 elements for Mat4");
@@ -91,7 +95,7 @@ Mat4 XmlElement::getMat4() const
 	{
 		for(U i = 0; i < 16; i++)
 		{
-			out[i] = std::stof(list[i]);
+			out[i] = list[i].toF64();
 		}
 	}
 	catch(const std::exception& e)
@@ -107,13 +111,15 @@ Vec3 XmlElement::getVec3() const
 {
 	check();
 
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
 		throw ANKI_EXCEPTION("Failed to return Vec3");
 	}
 
-	StringList list = StringList::splitString(txt, ' ');
+	BasicStringList<StackAllocator> list = 
+		BasicStringList<StackAllocator>::splitString(txt, ' ', m_alloc);
+
 	if(list.size() != 3)
 	{
 		throw ANKI_EXCEPTION("Expecting 3 elements for Vec3");
@@ -125,7 +131,7 @@ Vec3 XmlElement::getVec3() const
 	{
 		for(U i = 0; i < 3; i++)
 		{
-			out[i] = std::stof(list[i]);
+			out[i] = list[i].toF64();
 		}
 	}
 	catch(const std::exception& e)
@@ -140,13 +146,15 @@ Vec4 XmlElement::getVec4() const
 {
 	check();
 
-	const char* txt = getText();
+	const char* txt = m_el->GetText();
 	if(txt == nullptr)
 	{
 		throw ANKI_EXCEPTION("Failed to return Vec4");
 	}
 
-	StringList list = StringList::splitString(txt, ' ');
+	BasicStringList<StackAllocator> list = 
+		BasicStringList<StackAllocator>::splitString(txt, ' ', m_alloc);
+
 	if(list.size() != 4)
 	{
 		throw ANKI_EXCEPTION("Expecting 3 elements for Vec4");
@@ -158,7 +166,7 @@ Vec4 XmlElement::getVec4() const
 	{
 		for(U i = 0; i < 4; i++)
 		{
-			out[i] = std::stof(list[i]);
+			out[i] = list[i].toF64();
 		}
 	}
 	catch(const std::exception& e)
@@ -170,16 +178,16 @@ Vec4 XmlElement::getVec4() const
 }
 
 //==============================================================================
-XmlElement XmlElement::getChildElementOptional(const char* name) const
+XmlElement XmlElement::getChildElementOptional(const CString& name) const
 {
 	check();
 	XmlElement out;
-	out.el = el->FirstChildElement(name);
+	out.el = el->FirstChildElement(&name[0]);
 	return out;
 }
 
 //==============================================================================
-XmlElement XmlElement::getChildElement(const char* name) const
+XmlElement XmlElement::getChildElement(const CString& name) const
 {
 	check();
 	const XmlElement out = getChildElementOptional(name);
@@ -191,11 +199,11 @@ XmlElement XmlElement::getChildElement(const char* name) const
 }
 
 //==============================================================================
-XmlElement XmlElement::getNextSiblingElement(const char* name) const
+XmlElement XmlElement::getNextSiblingElement(const CString& name) const
 {
 	check();
 	XmlElement out;
-	out.el = el->NextSiblingElement(name);
+	out.el = el->NextSiblingElement(&name[0]);
 	return out;
 }
 
@@ -204,13 +212,14 @@ XmlElement XmlElement::getNextSiblingElement(const char* name) const
 //==============================================================================
 
 //==============================================================================
-void XmlDocument::loadFile(const char* filename, StackAllocator<U8>& alloc)
+void XmlDocument::loadFile(const CString& filename, StackAllocator<U8>& alloc)
 {
 	File file(filename, File::OpenFlag::READ);
-	std::string text;
+
+	BasicString<StackAllocator> text;
 	file.readAllText(text);
 
-	if(doc.Parse(text.c_str()))
+	if(doc.Parse(&text.toCString()[0]))
 	{
 		throw ANKI_EXCEPTION("Cannot parse file. Reason: %s",
 			((doc.GetErrorStr1() == nullptr)