Ver Fonte

Combining Vector and PODVector into Vector. Increasing the minimum C++17 [cache clear] (#2872)

1vanK há 3 anos atrás
pai
commit
df36ca095b

+ 2 - 2
Source/Tools/BindingGenerator/ASUtils.cpp

@@ -402,7 +402,7 @@ ConvertedVariable CppVariableToAS(const TypeAnalyzer& type, VariableUsage usage,
             string newCppVarName = name + "_conv";
             string newCppVarName = name + "_conv";
             result.asDeclaration_ = "Array<" + asSubtypeName + "@>@";
             result.asDeclaration_ = "Array<" + asSubtypeName + "@>@";
             result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
             result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
-            result.glue_ = "    " + cppTypeName + " " + name + " = ArrayToPODVector<" + cppSubtypeName + "*>(" + newCppVarName + ");\n";
+            result.glue_ = "    " + cppTypeName + " " + name + " = ArrayToVector<" + cppSubtypeName + "*>(" + newCppVarName + ");\n";
 
 
             assert(defaultValue.empty()); // TODO: make
             assert(defaultValue.empty()); // TODO: make
 
 
@@ -441,7 +441,7 @@ ConvertedVariable CppVariableToAS(const TypeAnalyzer& type, VariableUsage usage,
             string newCppVarName = name + "_conv";
             string newCppVarName = name + "_conv";
             result.asDeclaration_ = "Array<" + asSubtypeName + ">@+";
             result.asDeclaration_ = "Array<" + asSubtypeName + ">@+";
             result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
             result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
-            result.glue_ = "    " + cppTypeName + " " + name + " = ArrayToPODVector<" + cppSubtypeName + ">(" + newCppVarName + ");\n";
+            result.glue_ = "    " + cppTypeName + " " + name + " = ArrayToVector<" + cppSubtypeName + ">(" + newCppVarName + ");\n";
 
 
             assert(defaultValue.empty()); // TODO: make
             assert(defaultValue.empty()); // TODO: make
 
 

+ 3 - 0
Source/Tools/OgreImporter/OgreImporterUtils.h

@@ -33,6 +33,9 @@ using namespace Urho3D;
 
 
 struct Triangle
 struct Triangle
 {
 {
+    // Fields are not initialized.
+    Triangle() = default;
+
     Triangle(unsigned v0, unsigned v1, unsigned v2) :
     Triangle(unsigned v0, unsigned v1, unsigned v2) :
         v0_{v0},
         v0_{v0},
         v1_{v1},
         v1_{v1},

+ 0 - 54
Source/Urho3D/AngelScript/APITemplates.h

@@ -77,24 +77,6 @@ template <class T> CScriptArray* VectorToArray(const Vector<T>& vector, const ch
         return nullptr;
         return nullptr;
 }
 }
 
 
-/// Template function for PODVector to array conversion.
-template <class T> CScriptArray* VectorToArray(const PODVector<T>& vector, const char* arrayName)
-{
-    Context* context = GetScriptContext();
-    if (context)
-    {
-        asITypeInfo* type = context->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
-
-        for (unsigned i = 0; i < arr->GetSize(); ++i)
-            *(static_cast<T*>(arr->At(i))) = vector[i];
-
-        return arr;
-    }
-    else
-        return nullptr;
-}
-
 /// Template function for data buffer to array conversion.
 /// Template function for data buffer to array conversion.
 template <class T> CScriptArray* BufferToArray(const T* buffer, unsigned size, const char* arrayName)
 template <class T> CScriptArray* BufferToArray(const T* buffer, unsigned size, const char* arrayName)
 {
 {
@@ -137,30 +119,6 @@ template <class T> CScriptArray* VectorToHandleArray(const Vector<T*>& vector, c
         return nullptr;
         return nullptr;
 }
 }
 
 
-/// Template function for PODVector to handle array conversion.
-template <class T> CScriptArray* VectorToHandleArray(const PODVector<T*>& vector, const char* arrayName)
-{
-    Context* context = GetScriptContext();
-    if (context)
-    {
-        asITypeInfo* type = context->GetSubsystem<Script>()->GetObjectType(arrayName);
-        CScriptArray* arr = CScriptArray::Create(type, vector.Size());
-
-        for (unsigned i = 0; i < arr->GetSize(); ++i)
-        {
-            // Increment reference count for storing in the array
-            T* ptr = vector[i];
-            if (ptr)
-                ptr->AddRef();
-            *(static_cast<T**>(arr->At(i))) = ptr;
-        }
-
-        return arr;
-    }
-    else
-        return nullptr;
-}
-
 /// Template function for shared pointer Vector to handle array conversion.
 /// Template function for shared pointer Vector to handle array conversion.
 template <class T> CScriptArray* VectorToHandleArray(const Vector<SharedPtr<T> >& vector, const char* arrayName)
 template <class T> CScriptArray* VectorToHandleArray(const Vector<SharedPtr<T> >& vector, const char* arrayName)
 {
 {
@@ -196,18 +154,6 @@ template <class T> Vector<T> ArrayToVector(CScriptArray* arr)
     return dest;
     return dest;
 }
 }
 
 
-/// Template function for array to PODVector conversion.
-template <class T> PODVector<T> ArrayToPODVector(CScriptArray* arr)
-{
-    PODVector<T> dest(arr ? arr->GetSize() : 0);
-    if (arr)
-    {
-        for (unsigned i = 0; i < arr->GetSize(); ++i)
-            dest[i] = *static_cast<T*>(arr->At(i));
-    }
-    return dest;
-}
-
 template <class T> Vector<SharedPtr<T> > HandleArrayToVector(CScriptArray* arr)
 template <class T> Vector<SharedPtr<T> > HandleArrayToVector(CScriptArray* arr)
 {
 {
     Vector<T*> rawPtrs = ArrayToVector<T*>(arr);
     Vector<T*> rawPtrs = ArrayToVector<T*>(arr);

+ 1 - 1
Source/Urho3D/AngelScript/Generated_GlobalFunctions.cpp

@@ -25,7 +25,7 @@ static CScriptArray* constspVectorlesStringgreamp_ParseArguments_constspStringam
 // bool WriteDrawablesToOBJ(const PODVector<Drawable*>& drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV = false) | File: ../Graphics/Drawable.h
 // bool WriteDrawablesToOBJ(const PODVector<Drawable*>& drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV = false) | File: ../Graphics/Drawable.h
 static bool bool_WriteDrawablesToOBJ_constspPODVectorlesDrawablestargreamp_Filestar_bool_bool_bool(CScriptArray* drawables_conv, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 static bool bool_WriteDrawablesToOBJ_constspPODVectorlesDrawablestargreamp_Filestar_bool_bool_bool(CScriptArray* drawables_conv, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 {
 {
-    PODVector<Drawable*> drawables = ArrayToPODVector<Drawable*>(drawables_conv);
+    PODVector<Drawable*> drawables = ArrayToVector<Drawable*>(drawables_conv);
     bool result = WriteDrawablesToOBJ(drawables, outputFile, asZUp, asRightHanded, writeLightmapUV);
     bool result = WriteDrawablesToOBJ(drawables, outputFile, asZUp, asRightHanded, writeLightmapUV);
     return result;
     return result;
 }
 }

+ 12 - 12
Source/Urho3D/AngelScript/Generated_Members.h

@@ -3375,7 +3375,7 @@ template <class T> void RegisterMembers_Plane(asIScriptEngine* engine, const cha
 // void Polyhedron::AddFace(const PODVector<Vector3>& face)
 // void Polyhedron::AddFace(const PODVector<Vector3>& face)
 template <class T> void Polyhedron_void_AddFace_constspPODVectorlesVector3greamp_template(T* _ptr, CScriptArray* face_conv)
 template <class T> void Polyhedron_void_AddFace_constspPODVectorlesVector3greamp_template(T* _ptr, CScriptArray* face_conv)
 {
 {
-    PODVector<Vector3> face = ArrayToPODVector<Vector3>(face_conv);
+    PODVector<Vector3> face = ArrayToVector<Vector3>(face_conv);
     _ptr->AddFace(face);
     _ptr->AddFace(face);
 }
 }
 
 
@@ -7936,7 +7936,7 @@ template <class T> void RegisterMembers_NodeReplicationState(asIScriptEngine* en
 // void Object::UnsubscribeFromAllEventsExcept(const PODVector<StringHash>& exceptions, bool onlyUserData)
 // void Object::UnsubscribeFromAllEventsExcept(const PODVector<StringHash>& exceptions, bool onlyUserData)
 template <class T> void Object_void_UnsubscribeFromAllEventsExcept_constspPODVectorlesStringHashgreamp_bool_template(T* _ptr, CScriptArray* exceptions_conv, bool onlyUserData)
 template <class T> void Object_void_UnsubscribeFromAllEventsExcept_constspPODVectorlesStringHashgreamp_bool_template(T* _ptr, CScriptArray* exceptions_conv, bool onlyUserData)
 {
 {
-    PODVector<StringHash> exceptions = ArrayToPODVector<StringHash>(exceptions_conv);
+    PODVector<StringHash> exceptions = ArrayToVector<StringHash>(exceptions_conv);
     _ptr->UnsubscribeFromAllEventsExcept(exceptions, onlyUserData);
     _ptr->UnsubscribeFromAllEventsExcept(exceptions, onlyUserData);
 }
 }
 
 
@@ -12315,7 +12315,7 @@ template <class T> CScriptArray* VertexBuffer_constspPODVectorlesVertexElementgr
 // bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic = false)
 // bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic = false)
 template <class T> bool VertexBuffer_bool_SetSize_unsigned_constspPODVectorlesVertexElementgreamp_bool_template(T* _ptr, unsigned vertexCount, CScriptArray* elements_conv, bool dynamic)
 template <class T> bool VertexBuffer_bool_SetSize_unsigned_constspPODVectorlesVertexElementgreamp_bool_template(T* _ptr, unsigned vertexCount, CScriptArray* elements_conv, bool dynamic)
 {
 {
-    PODVector<VertexElement> elements = ArrayToPODVector<VertexElement>(elements_conv);
+    PODVector<VertexElement> elements = ArrayToVector<VertexElement>(elements_conv);
     bool result = _ptr->SetSize(vertexCount, elements, dynamic);
     bool result = _ptr->SetSize(vertexCount, elements, dynamic);
     return result;
     return result;
 }
 }
@@ -12323,7 +12323,7 @@ template <class T> bool VertexBuffer_bool_SetSize_unsigned_constspPODVectorlesVe
 // static bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0)
 // static bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0)
 template <class T> bool VertexBuffer_bool_HasElement_constspPODVectorlesVertexElementgreamp_VertexElementType_VertexElementSemantic_unsignedspchar(CScriptArray* elements_conv, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
 template <class T> bool VertexBuffer_bool_HasElement_constspPODVectorlesVertexElementgreamp_VertexElementType_VertexElementSemantic_unsignedspchar(CScriptArray* elements_conv, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
 {
 {
-    PODVector<VertexElement> elements = ArrayToPODVector<VertexElement>(elements_conv);
+    PODVector<VertexElement> elements = ArrayToVector<VertexElement>(elements_conv);
     bool result = T::HasElement(elements, type, semantic, index);
     bool result = T::HasElement(elements, type, semantic, index);
     return result;
     return result;
 }
 }
@@ -12331,7 +12331,7 @@ template <class T> bool VertexBuffer_bool_HasElement_constspPODVectorlesVertexEl
 // static unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0)
 // static unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index = 0)
 template <class T> unsigned VertexBuffer_unsigned_GetElementOffset_constspPODVectorlesVertexElementgreamp_VertexElementType_VertexElementSemantic_unsignedspchar(CScriptArray* elements_conv, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
 template <class T> unsigned VertexBuffer_unsigned_GetElementOffset_constspPODVectorlesVertexElementgreamp_VertexElementType_VertexElementSemantic_unsignedspchar(CScriptArray* elements_conv, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
 {
 {
-    PODVector<VertexElement> elements = ArrayToPODVector<VertexElement>(elements_conv);
+    PODVector<VertexElement> elements = ArrayToVector<VertexElement>(elements_conv);
     unsigned result = T::GetElementOffset(elements, type, semantic, index);
     unsigned result = T::GetElementOffset(elements, type, semantic, index);
     return result;
     return result;
 }
 }
@@ -12346,7 +12346,7 @@ template <class T> CScriptArray* VertexBuffer_PODVectorlesVertexElementgre_GetEl
 // static unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
 // static unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
 template <class T> unsigned VertexBuffer_unsigned_GetVertexSize_constspPODVectorlesVertexElementgreamp(CScriptArray* elements_conv)
 template <class T> unsigned VertexBuffer_unsigned_GetVertexSize_constspPODVectorlesVertexElementgreamp(CScriptArray* elements_conv)
 {
 {
-    PODVector<VertexElement> elements = ArrayToPODVector<VertexElement>(elements_conv);
+    PODVector<VertexElement> elements = ArrayToVector<VertexElement>(elements_conv);
     unsigned result = T::GetVertexSize(elements);
     unsigned result = T::GetVertexSize(elements);
     return result;
     return result;
 }
 }
@@ -13078,7 +13078,7 @@ template <class T> void RegisterMembers_Network(asIScriptEngine* engine, const c
 // void ConvexData::BuildHull(const PODVector<Vector3>& vertices)
 // void ConvexData::BuildHull(const PODVector<Vector3>& vertices)
 template <class T> void ConvexData_void_BuildHull_constspPODVectorlesVector3greamp_template(T* _ptr, CScriptArray* vertices_conv)
 template <class T> void ConvexData_void_BuildHull_constspPODVectorlesVector3greamp_template(T* _ptr, CScriptArray* vertices_conv)
 {
 {
-    PODVector<Vector3> vertices = ArrayToPODVector<Vector3>(vertices_conv);
+    PODVector<Vector3> vertices = ArrayToVector<Vector3>(vertices_conv);
     _ptr->BuildHull(vertices);
     _ptr->BuildHull(vertices);
 }
 }
 
 
@@ -15135,8 +15135,8 @@ template <class T> bool Model_bool_SetIndexBuffers_constspVectorlesSharedPtrlesI
 template <class T> bool Model_bool_SetVertexBuffers_constspVectorlesSharedPtrlesVertexBuffergregreamp_constspPODVectorlesunsignedgreamp_constspPODVectorlesunsignedgreamp_template(T* _ptr, CScriptArray* buffers_conv, CScriptArray* morphRangeStarts_conv, CScriptArray* morphRangeCounts_conv)
 template <class T> bool Model_bool_SetVertexBuffers_constspVectorlesSharedPtrlesVertexBuffergregreamp_constspPODVectorlesunsignedgreamp_constspPODVectorlesunsignedgreamp_template(T* _ptr, CScriptArray* buffers_conv, CScriptArray* morphRangeStarts_conv, CScriptArray* morphRangeCounts_conv)
 {
 {
     Vector<SharedPtr<VertexBuffer>> buffers = HandleArrayToVector<VertexBuffer>(buffers_conv);
     Vector<SharedPtr<VertexBuffer>> buffers = HandleArrayToVector<VertexBuffer>(buffers_conv);
-    PODVector<unsigned> morphRangeStarts = ArrayToPODVector<unsigned>(morphRangeStarts_conv);
-    PODVector<unsigned> morphRangeCounts = ArrayToPODVector<unsigned>(morphRangeCounts_conv);
+    PODVector<unsigned> morphRangeStarts = ArrayToVector<unsigned>(morphRangeStarts_conv);
+    PODVector<unsigned> morphRangeCounts = ArrayToVector<unsigned>(morphRangeCounts_conv);
     bool result = _ptr->SetVertexBuffers(buffers, morphRangeStarts, morphRangeCounts);
     bool result = _ptr->SetVertexBuffers(buffers, morphRangeStarts, morphRangeCounts);
     return result;
     return result;
 }
 }
@@ -22295,7 +22295,7 @@ template <class T> CScriptArray* ListView_constspPODVectorlesunsignedgreamp_GetS
 // void ListView::SetSelections(const PODVector<unsigned>& indices)
 // void ListView::SetSelections(const PODVector<unsigned>& indices)
 template <class T> void ListView_void_SetSelections_constspPODVectorlesunsignedgreamp_template(T* _ptr, CScriptArray* indices_conv)
 template <class T> void ListView_void_SetSelections_constspPODVectorlesunsignedgreamp_template(T* _ptr, CScriptArray* indices_conv)
 {
 {
-    PODVector<unsigned> indices = ArrayToPODVector<unsigned>(indices_conv);
+    PODVector<unsigned> indices = ArrayToVector<unsigned>(indices_conv);
     _ptr->SetSelections(indices);
     _ptr->SetSelections(indices);
 }
 }
 
 
@@ -23889,7 +23889,7 @@ template <class T> CScriptArray* CollisionChain2D_constspPODVectorlesVector2grea
 // void CollisionChain2D::SetVertices(const PODVector<Vector2>& vertices)
 // void CollisionChain2D::SetVertices(const PODVector<Vector2>& vertices)
 template <class T> void CollisionChain2D_void_SetVertices_constspPODVectorlesVector2greamp_template(T* _ptr, CScriptArray* vertices_conv)
 template <class T> void CollisionChain2D_void_SetVertices_constspPODVectorlesVector2greamp_template(T* _ptr, CScriptArray* vertices_conv)
 {
 {
-    PODVector<Vector2> vertices = ArrayToPODVector<Vector2>(vertices_conv);
+    PODVector<Vector2> vertices = ArrayToVector<Vector2>(vertices_conv);
     _ptr->SetVertices(vertices);
     _ptr->SetVertices(vertices);
 }
 }
 
 
@@ -24004,7 +24004,7 @@ template <class T> CScriptArray* CollisionPolygon2D_constspPODVectorlesVector2gr
 // void CollisionPolygon2D::SetVertices(const PODVector<Vector2>& vertices)
 // void CollisionPolygon2D::SetVertices(const PODVector<Vector2>& vertices)
 template <class T> void CollisionPolygon2D_void_SetVertices_constspPODVectorlesVector2greamp_template(T* _ptr, CScriptArray* vertices_conv)
 template <class T> void CollisionPolygon2D_void_SetVertices_constspPODVectorlesVector2greamp_template(T* _ptr, CScriptArray* vertices_conv)
 {
 {
-    PODVector<Vector2> vertices = ArrayToPODVector<Vector2>(vertices_conv);
+    PODVector<Vector2> vertices = ArrayToVector<Vector2>(vertices_conv);
     _ptr->SetVertices(vertices);
     _ptr->SetVertices(vertices);
 }
 }
 
 

+ 286 - 536
Source/Urho3D/Container/Vector.h

@@ -24,11 +24,12 @@
 
 
 #include "../Container/VectorBase.h"
 #include "../Container/VectorBase.h"
 
 
+#include <algorithm>
 #include <cassert>
 #include <cassert>
 #include <cstring>
 #include <cstring>
-#include <algorithm>
 #include <initializer_list>
 #include <initializer_list>
 #include <new>
 #include <new>
+#include <type_traits>
 #include <utility>
 #include <utility>
 
 
 #ifdef _MSC_VER
 #ifdef _MSC_VER
@@ -70,13 +71,24 @@ public:
     /// Construct with initial data.
     /// Construct with initial data.
     Vector(const T* data, unsigned size)
     Vector(const T* data, unsigned size)
     {
     {
-        DoInsertElements(0, data, data + size, CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            Resize(size);
+            CopyElements(Buffer(), data, size);
+        }
+        else
+        {
+            DoInsertElements(0, data, data + size, CopyTag{});
+        }
     }
     }
 
 
     /// Copy-construct from another vector.
     /// Copy-construct from another vector.
     Vector(const Vector<T>& vector)
     Vector(const Vector<T>& vector)
     {
     {
-        DoInsertElements(0, vector.Begin(), vector.End(), CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+            *this = vector;
+        else
+            DoInsertElements(0, vector.Begin(), vector.End(), CopyTag{});
     }
     }
 
 
     /// Copy-construct from another vector (iterator version).
     /// Copy-construct from another vector (iterator version).
@@ -103,7 +115,9 @@ public:
     /// Destruct.
     /// Destruct.
     ~Vector()
     ~Vector()
     {
     {
-        DestructElements(Buffer(), size_);
+        if constexpr (!std::is_trivial<T>::value)
+            DestructElements(Buffer(), size_);
+
         delete[] buffer_;
         delete[] buffer_;
     }
     }
 
 
@@ -113,9 +127,18 @@ public:
         // In case of self-assignment do nothing
         // In case of self-assignment do nothing
         if (&rhs != this)
         if (&rhs != this)
         {
         {
-            Vector<T> copy(rhs);
-            Swap(copy);
+            if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+            {
+                Resize(rhs.size_);
+                CopyElements(Buffer(), rhs.Buffer(), rhs.size_);
+            }
+            else
+            {
+                Vector<T> copy(rhs);
+                Swap(copy);
+            }
         }
         }
+
         return *this;
         return *this;
     }
     }
 
 
@@ -239,14 +262,28 @@ public:
 #ifndef COVERITY_SCAN_MODEL
 #ifndef COVERITY_SCAN_MODEL
     void Push(const T& value)
     void Push(const T& value)
     {
     {
-        if (size_ < capacity_)
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
         {
         {
-            // Optimize common case
-            ++size_;
-            new (&Back()) T(value);
+            if (size_ < capacity_)
+                ++size_;
+            else
+                Resize(size_ + 1);
+            
+            Back() = value;
         }
         }
         else
         else
-            DoInsertElements(size_, &value, &value + 1, CopyTag{});
+        {
+            if (size_ < capacity_)
+            {
+                // Optimize common case
+                ++size_;
+                new (&Back()) T(value);
+            }
+            else
+            {
+                DoInsertElements(size_, &value, &value + 1, CopyTag{});
+            }
+        }
     }
     }
 
 
     /// Move-add an element at the end.
     /// Move-add an element at the end.
@@ -272,7 +309,21 @@ public:
 #endif
 #endif
 
 
     /// Add another vector at the end.
     /// Add another vector at the end.
-    void Push(const Vector<T>& vector) { DoInsertElements(size_, vector.Begin(), vector.End(), CopyTag{}); }
+    void Push(const Vector<T>& vector)
+    {
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            // Obtain the size before resizing, in case the other vector is another reference to this vector
+            unsigned thisSize = size_;
+            unsigned vectorSize = vector.size_;
+            Resize(thisSize + vectorSize);
+            CopyElements(Buffer() + thisSize, vector.Buffer(), vectorSize);
+        }
+        else
+        {
+            DoInsertElements(size_, vector.Begin(), vector.End(), CopyTag{});
+        }
+    }
 
 
     /// Remove the last element.
     /// Remove the last element.
     void Pop()
     void Pop()
@@ -290,20 +341,58 @@ public:
     /// Insert an element at position.
     /// Insert an element at position.
     void Insert(unsigned pos, T && value)
     void Insert(unsigned pos, T && value)
     {
     {
-        DoInsertElements(pos, &value, &value + 1, MoveTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            if (pos > size_)
+                pos = size_;
+
+            unsigned oldSize = size_;
+            Resize(size_ + 1);
+            MoveRange(pos + 1, pos, oldSize - pos);
+            Buffer()[pos] = value;
+        }
+        else
+        {
+            DoInsertElements(pos, &value, &value + 1, MoveTag{});
+        }
     }
     }
 
 
     /// Insert another vector at position.
     /// Insert another vector at position.
     void Insert(unsigned pos, const Vector<T>& vector)
     void Insert(unsigned pos, const Vector<T>& vector)
     {
     {
-        DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            if (pos > size_)
+                pos = size_;
+
+            unsigned oldSize = size_;
+            Resize(size_ + vector.size_);
+            MoveRange(pos + vector.size_, pos, oldSize - pos);
+            CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
+        }
+        else
+        {
+            DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
+        }
     }
     }
 
 
     /// Insert an element by iterator.
     /// Insert an element by iterator.
     Iterator Insert(const Iterator& dest, const T& value)
     Iterator Insert(const Iterator& dest, const T& value)
     {
     {
-        auto pos = (unsigned)(dest - Begin());
-        return DoInsertElements(pos, &value, &value + 1, CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            auto pos = (unsigned)(dest - Begin());
+            if (pos > size_)
+                pos = size_;
+            Insert(pos, value);
+
+            return Begin() + pos;
+        }
+        else
+        {
+            auto pos = (unsigned)(dest - Begin());
+            return DoInsertElements(pos, &value, &value + 1, CopyTag{});
+        }
     }
     }
 
 
     /// Move-insert an element by iterator.
     /// Move-insert an element by iterator.
@@ -316,22 +405,67 @@ public:
     /// Insert a vector by iterator.
     /// Insert a vector by iterator.
     Iterator Insert(const Iterator& dest, const Vector<T>& vector)
     Iterator Insert(const Iterator& dest, const Vector<T>& vector)
     {
     {
-        auto pos = (unsigned)(dest - Begin());
-        return DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            auto pos = (unsigned)(dest - Begin());
+            if (pos > size_)
+                pos = size_;
+            Insert(pos, vector);
+
+            return Begin() + pos;
+        }
+        else
+        {
+            auto pos = (unsigned)(dest - Begin());
+            return DoInsertElements(pos, vector.Begin(), vector.End(), CopyTag{});
+        }
     }
     }
 
 
     /// Insert a vector partially by iterators.
     /// Insert a vector partially by iterators.
     Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
     Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
     {
     {
-        auto pos = (unsigned)(dest - Begin());
-        return DoInsertElements(pos, start, end, CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            auto pos = (unsigned)(dest - Begin());
+            if (pos > size_)
+                pos = size_;
+            auto length = (unsigned)(end - start);
+            Resize(size_ + length);
+            MoveRange(pos + length, pos, size_ - pos - length);
+            CopyElements(Buffer() + pos, &(*start), length);
+
+            return Begin() + pos;
+        }
+        else
+        {
+            auto pos = (unsigned)(dest - Begin());
+            return DoInsertElements(pos, start, end, CopyTag{});
+        }
     }
     }
 
 
     /// Insert elements.
     /// Insert elements.
     Iterator Insert(const Iterator& dest, const T* start, const T* end)
     Iterator Insert(const Iterator& dest, const T* start, const T* end)
     {
     {
-        auto pos = (unsigned)(dest - Begin());
-        return DoInsertElements(pos, start, end, CopyTag{});
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            auto pos = (unsigned)(dest - Begin());
+            if (pos > size_)
+                pos = size_;
+            auto length = (unsigned)(end - start);
+            Resize(size_ + length);
+            MoveRange(pos + length, pos, size_ - pos - length);
+
+            T* destPtr = Buffer() + pos;
+            for (const T* i = start; i != end; ++i)
+                *destPtr++ = *i;
+
+            return Begin() + pos;
+        }
+        else
+        {
+            auto pos = (unsigned)(dest - Begin());
+            return DoInsertElements(pos, start, end, CopyTag{});
+        }
     }
     }
 
 
     /// Erase a range of elements.
     /// Erase a range of elements.
@@ -341,7 +475,15 @@ public:
         if (pos + length > size_ || !length)
         if (pos + length > size_ || !length)
             return;
             return;
 
 
-        DoEraseElements(pos, length);
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            MoveRange(pos, pos + length, size_ - pos - length);
+            Resize(size_ - length);
+        }
+        else
+        {
+            DoEraseElements(pos, length);
+        }
     }
     }
 
 
     /// Erase a range of elements by swapping elements from the end of the array.
     /// Erase a range of elements by swapping elements from the end of the array.
@@ -354,17 +496,35 @@ public:
 
 
         unsigned newSize = size_ - length;
         unsigned newSize = size_ - length;
         unsigned trailingCount = size_ - shiftStartIndex;
         unsigned trailingCount = size_ - shiftStartIndex;
-        if (trailingCount <= length)
+
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
         {
         {
-            // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
-            DoEraseElements(pos, length);
+            if (trailingCount <= length)
+            {
+                // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
+                MoveRange(pos, shiftStartIndex, trailingCount);
+            }
+            else
+            {
+                // Swap elements from the end of the array into the empty space
+                CopyElements(Buffer() + pos, Buffer() + newSize, length);
+            }
+            Resize(newSize);
         }
         }
         else
         else
         {
         {
-            // Swap elements from the end of the array into the empty space
-            T* buffer = Buffer();
-            std::move(buffer + newSize, buffer + size_, buffer + pos);
-            Resize(newSize);
+            if (trailingCount <= length)
+            {
+                // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
+                DoEraseElements(pos, length);
+            }
+            else
+            {
+                // Swap elements from the end of the array into the empty space
+                T* buffer = Buffer();
+                std::move(buffer + newSize, buffer + size_, buffer + pos);
+                Resize(newSize);
+            }
         }
         }
     }
     }
 
 
@@ -401,7 +561,9 @@ public:
             return true;
             return true;
         }
         }
         else
         else
+        {
             return false;
             return false;
+        }
     }
     }
 
 
     /// Erase an element by value by swapping with the last element. Return true if was found and erased.
     /// Erase an element by value by swapping with the last element. Return true if was found and erased.
@@ -414,20 +576,52 @@ public:
             return true;
             return true;
         }
         }
         else
         else
+        {
             return false;
             return false;
+        }
     }
     }
 
 
     /// Clear the vector.
     /// Clear the vector.
     void Clear() { Resize(0); }
     void Clear() { Resize(0); }
 
 
     /// Resize the vector.
     /// Resize the vector.
-    void Resize(unsigned newSize) { DoResize(newSize); }
+    void Resize(unsigned newSize)
+    {
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
+        {
+            if (newSize > capacity_)
+            {
+                if (!capacity_)
+                    capacity_ = newSize;
+                else
+                {
+                    while (capacity_ < newSize)
+                        capacity_ += (capacity_ + 1) >> 1;
+                }
+
+                unsigned char* newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
+                // Move the data into the new buffer and delete the old
+                if (buffer_)
+                {
+                    CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
+                    delete[] buffer_;
+                }
+                buffer_ = newBuffer;
+            }
+
+            size_ = newSize;
+        }
+        else
+        {
+            DoResize(newSize);
+        }
+    }
 
 
     /// Resize the vector and fill new elements with default value.
     /// Resize the vector and fill new elements with default value.
     void Resize(unsigned newSize, const T& value)
     void Resize(unsigned newSize, const T& value)
     {
     {
         unsigned oldSize = Size();
         unsigned oldSize = Size();
-        DoResize(newSize);
+        Resize(newSize);
         for (unsigned i = oldSize; i < newSize; ++i)
         for (unsigned i = oldSize; i < newSize; ++i)
             At(i) = value;
             At(i) = value;
     }
     }
@@ -438,22 +632,44 @@ public:
         if (newCapacity < size_)
         if (newCapacity < size_)
             newCapacity = size_;
             newCapacity = size_;
 
 
-        if (newCapacity != capacity_)
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
         {
         {
-            T* newBuffer = nullptr;
-            capacity_ = newCapacity;
+            if (newCapacity != capacity_)
+            {
+                unsigned char* newBuffer = nullptr;
+                capacity_ = newCapacity;
 
 
-            if (capacity_)
+                if (capacity_)
+                {
+                    newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
+                    // Move the data into the new buffer
+                    CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
+                }
+
+                // Delete the old buffer
+                delete[] buffer_;
+                buffer_ = newBuffer;
+            }
+        }
+        else
+        {
+            if (newCapacity != capacity_)
             {
             {
-                newBuffer = reinterpret_cast<T*>(AllocateBuffer((unsigned)(capacity_ * sizeof(T))));
-                // Move the data into the new buffer
-                ConstructElements(newBuffer, Begin(), End(), MoveTag{});
+                T* newBuffer = nullptr;
+                capacity_ = newCapacity;
+
+                if (capacity_)
+                {
+                    newBuffer = reinterpret_cast<T*>(AllocateBuffer((unsigned)(capacity_ * sizeof(T))));
+                    // Move the data into the new buffer
+                    ConstructElements(newBuffer, Begin(), End(), MoveTag{});
+                }
+
+                // Delete the old buffer
+                DestructElements(Buffer(), size_);
+                delete[] buffer_;
+                buffer_ = reinterpret_cast<unsigned char*>(newBuffer);
             }
             }
-
-            // Delete the old buffer
-            DestructElements(Buffer(), size_);
-            delete[] buffer_;
-            buffer_ = reinterpret_cast<unsigned char*>(newBuffer);
         }
         }
     }
     }
 
 
@@ -527,7 +743,7 @@ public:
         return Buffer()[size_ - 1];
         return Buffer()[size_ - 1];
     }
     }
 
 
-    /// Return size of vector.
+    /// Return number of elements.
     unsigned Size() const { return size_; }
     unsigned Size() const { return size_; }
 
 
     /// Return capacity of vector.
     /// Return capacity of vector.
@@ -569,7 +785,9 @@ private:
     static unsigned CalculateCapacity(unsigned size, unsigned capacity)
     static unsigned CalculateCapacity(unsigned size, unsigned capacity)
     {
     {
         if (!capacity)
         if (!capacity)
+        {
             return size;
             return size;
+        }
         else
         else
         {
         {
             while (capacity < size)
             while (capacity < size)
@@ -583,7 +801,9 @@ private:
     {
     {
         // If size shrinks, destruct the removed elements
         // If size shrinks, destruct the removed elements
         if (newSize < size_)
         if (newSize < size_)
+        {
             DestructElements(Buffer() + newSize, size_ - newSize);
             DestructElements(Buffer() + newSize, size_ - newSize);
+        }
         else
         else
         {
         {
             // Allocate new buffer if necessary and copy the current elements
             // Allocate new buffer if necessary and copy the current elements
@@ -679,518 +899,48 @@ private:
             ++dest;
             ++dest;
         }
         }
     }
     }
-};
-
-/// %Vector template class for POD types. Does not call constructors or destructors and uses block move. Is intentionally (for performance reasons) unsafe for self-insertion.
-template <class T> class PODVector : public VectorBase
-{
-public:
-    using ValueType = T;
-    using Iterator = RandomAccessIterator<T>;
-    using ConstIterator = RandomAccessConstIterator<T>;
-
-    /// Construct empty.
-    PODVector() noexcept = default;
-
-    /// Construct with initial size.
-    explicit PODVector(unsigned size)
-    {
-        Resize(size);
-    }
-
-    /// Construct with initial size and default value.
-    PODVector(unsigned size, const T& value)
-    {
-        Resize(size);
-        for (unsigned i = 0; i < size; ++i)
-            At(i) = value;
-    }
-
-    /// Construct with initial data.
-    PODVector(const T* data, unsigned size)
-    {
-        Resize(size);
-        CopyElements(Buffer(), data, size);
-    }
 
 
-    /// Construct from another vector.
-    PODVector(const PODVector<T>& vector)
-    {
-        *this = vector;
-    }
-    /// Aggregate initialization constructor.
-    PODVector(const std::initializer_list<T>& list) : PODVector()
+    /// Move a range of elements within the vector. Only for PODVector.
+    void MoveRange(unsigned dest, unsigned src, unsigned count)
     {
     {
-        for (auto it = list.begin(); it != list.end(); it++)
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
         {
         {
-            Push(*it);
+            if (count)
+                memmove(Buffer() + dest, Buffer() + src, count * sizeof(T));
         }
         }
-    }
-    /// Destruct.
-    ~PODVector()
-    {
-        delete[] buffer_;
-    }
-
-    /// Assign from another vector.
-    PODVector<T>& operator =(const PODVector<T>& rhs)
-    {
-        // In case of self-assignment do nothing
-        if (&rhs != this)
+        else
         {
         {
-            Resize(rhs.size_);
-            CopyElements(Buffer(), rhs.Buffer(), rhs.size_);
+            static_assert(true);
         }
         }
-        return *this;
-    }
-
-    /// Add-assign an element.
-    PODVector<T>& operator +=(const T& rhs)
-    {
-        Push(rhs);
-        return *this;
-    }
-
-    /// Add-assign another vector.
-    PODVector<T>& operator +=(const PODVector<T>& rhs)
-    {
-        Push(rhs);
-        return *this;
-    }
-
-    /// Add an element.
-    PODVector<T> operator +(const T& rhs) const
-    {
-        PODVector<T> ret(*this);
-        ret.Push(rhs);
-        return ret;
-    }
-
-    /// Add another vector.
-    PODVector<T> operator +(const PODVector<T>& rhs) const
-    {
-        PODVector<T> ret(*this);
-        ret.Push(rhs);
-        return ret;
     }
     }
 
 
-    /// Test for equality with another vector.
-    bool operator ==(const PODVector<T>& rhs) const
+    /// Copy elements from one buffer to another. Only for PODVector.
+    static void CopyElements(T* dest, const T* src, unsigned count)
     {
     {
-        if (rhs.size_ != size_)
-            return false;
-
-        T* buffer = Buffer();
-        T* rhsBuffer = rhs.Buffer();
-        for (unsigned i = 0; i < size_; ++i)
+        if constexpr (std::is_trivial<T>::value && std::is_standard_layout<T>::value)
         {
         {
-            if (buffer[i] != rhsBuffer[i])
-                return false;
+            if (count)
+                memcpy(dest, src, count * sizeof(T));
         }
         }
-
-        return true;
-    }
-
-    /// Test for inequality with another vector.
-    bool operator !=(const PODVector<T>& rhs) const
-    {
-        if (rhs.size_ != size_)
-            return true;
-
-        T* buffer = Buffer();
-        T* rhsBuffer = rhs.Buffer();
-        for (unsigned i = 0; i < size_; ++i)
+        else
         {
         {
-            if (buffer[i] != rhsBuffer[i])
-                return true;
+            static_assert(true);
         }
         }
-
-        return false;
     }
     }
+};
 
 
-    /// Return element at index.
-    T& operator [](unsigned index)
-    {
-        assert(index < size_);
-        return Buffer()[index];
-    }
+/// For backwards compatibility.
+template <typename T>
+using PODVector = Vector<T>;
 
 
-    /// Return const element at index.
-    const T& operator [](unsigned index) const
-    {
-        assert(index < size_);
-        return Buffer()[index];
-    }
+template <class T> typename Urho3D::Vector<T>::ConstIterator begin(const Urho3D::Vector<T>& v) { return v.Begin(); }
 
 
-    /// Return element at index.
-    T& At(unsigned index)
-    {
-        assert(index < size_);
-        return Buffer()[index];
-    }
+template <class T> typename Urho3D::Vector<T>::ConstIterator end(const Urho3D::Vector<T>& v) { return v.End(); }
 
 
-    /// Return const element at index.
-    const T& At(unsigned index) const
-    {
-        assert(index < size_);
-        return Buffer()[index];
-    }
-
-    /// Add an element at the end.
-    void Push(const T& value)
-    {
-        if (size_ < capacity_)
-            ++size_;
-        else
-            Resize(size_ + 1);
-        Back() = value;
-    }
-
-    /// Add another vector at the end.
-    void Push(const PODVector<T>& vector)
-    {
-        // Obtain the size before resizing, in case the other vector is another reference to this vector
-        unsigned thisSize = size_;
-        unsigned vectorSize = vector.size_;
-        Resize(thisSize + vectorSize);
-        CopyElements(Buffer() + thisSize, vector.Buffer(), vectorSize);
-    }
-
-    /// Remove the last element.
-    void Pop()
-    {
-        if (size_)
-            Resize(size_ - 1);
-    }
-
-    /// Insert an element at position.
-    void Insert(unsigned pos, const T& value)
-    {
-        if (pos > size_)
-            pos = size_;
-
-        unsigned oldSize = size_;
-        Resize(size_ + 1);
-        MoveRange(pos + 1, pos, oldSize - pos);
-        Buffer()[pos] = value;
-    }
-
-    /// Insert another vector at position.
-    void Insert(unsigned pos, const PODVector<T>& vector)
-    {
-        if (pos > size_)
-            pos = size_;
-
-        unsigned oldSize = size_;
-        Resize(size_ + vector.size_);
-        MoveRange(pos + vector.size_, pos, oldSize - pos);
-        CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
-    }
-
-    /// Insert an element by iterator.
-    Iterator Insert(const Iterator& dest, const T& value)
-    {
-        auto pos = (unsigned)(dest - Begin());
-        if (pos > size_)
-            pos = size_;
-        Insert(pos, value);
-
-        return Begin() + pos;
-    }
-
-    /// Insert a vector by iterator.
-    Iterator Insert(const Iterator& dest, const PODVector<T>& vector)
-    {
-        auto pos = (unsigned)(dest - Begin());
-        if (pos > size_)
-            pos = size_;
-        Insert(pos, vector);
-
-        return Begin() + pos;
-    }
-
-    /// Insert a vector partially by iterators.
-    Iterator Insert(const Iterator& dest, const ConstIterator& start, const ConstIterator& end)
-    {
-        auto pos = (unsigned)(dest - Begin());
-        if (pos > size_)
-            pos = size_;
-        auto length = (unsigned)(end - start);
-        Resize(size_ + length);
-        MoveRange(pos + length, pos, size_ - pos - length);
-        CopyElements(Buffer() + pos, &(*start), length);
-
-        return Begin() + pos;
-    }
-
-    /// Insert elements.
-    Iterator Insert(const Iterator& dest, const T* start, const T* end)
-    {
-        auto pos = (unsigned)(dest - Begin());
-        if (pos > size_)
-            pos = size_;
-        auto length = (unsigned)(end - start);
-        Resize(size_ + length);
-        MoveRange(pos + length, pos, size_ - pos - length);
-
-        T* destPtr = Buffer() + pos;
-        for (const T* i = start; i != end; ++i)
-            *destPtr++ = *i;
-
-        return Begin() + pos;
-    }
-
-    /// Erase a range of elements.
-    void Erase(unsigned pos, unsigned length = 1)
-    {
-        // Return if the range is illegal
-        if (!length || pos + length > size_)
-            return;
-
-        MoveRange(pos, pos + length, size_ - pos - length);
-        Resize(size_ - length);
-    }
-
-    /// Erase an element by iterator. Return iterator to the next element.
-    Iterator Erase(const Iterator& it)
-    {
-        auto pos = (unsigned)(it - Begin());
-        if (pos >= size_)
-            return End();
-        Erase(pos);
-
-        return Begin() + pos;
-    }
-
-    /// Erase a range by iterators. Return iterator to the next element.
-    Iterator Erase(const Iterator& start, const Iterator& end)
-    {
-        auto pos = (unsigned)(start - Begin());
-        if (pos >= size_)
-            return End();
-        auto length = (unsigned)(end - start);
-        Erase(pos, length);
-
-        return Begin() + pos;
-    }
-
-    /// Erase a range of elements by swapping elements from the end of the array.
-    void EraseSwap(unsigned pos, unsigned length = 1)
-    {
-        unsigned shiftStartIndex = pos + length;
-        // Return if the range is illegal
-        if (shiftStartIndex > size_ || !length)
-            return;
-
-        unsigned newSize = size_ - length;
-        unsigned trailingCount = size_ - shiftStartIndex;
-        if (trailingCount <= length)
-        {
-            // We're removing more elements from the array than exist past the end of the range being removed, so perform a normal shift and destroy
-            MoveRange(pos, shiftStartIndex, trailingCount);
-        }
-        else
-        {
-            // Swap elements from the end of the array into the empty space
-            CopyElements(Buffer() + pos, Buffer() + newSize, length);
-        }
-        Resize(newSize);
-    }
-
-    /// Erase an element by value. Return true if was found and erased.
-    bool Remove(const T& value)
-    {
-        Iterator i = Find(value);
-        if (i != End())
-        {
-            Erase(i);
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /// Erase an element by value by swapping with the last element. Return true if was found and erased.
-    bool RemoveSwap(const T& value)
-    {
-        Iterator i = Find(value);
-        if (i != End())
-        {
-            EraseSwap(i - Begin());
-            return true;
-        }
-        else
-            return false;
-    }
-
-    /// Clear the vector.
-    void Clear() { Resize(0); }
-
-    /// Resize the vector.
-    void Resize(unsigned newSize)
-    {
-        if (newSize > capacity_)
-        {
-            if (!capacity_)
-                capacity_ = newSize;
-            else
-            {
-                while (capacity_ < newSize)
-                    capacity_ += (capacity_ + 1) >> 1;
-            }
-
-            unsigned char* newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
-            // Move the data into the new buffer and delete the old
-            if (buffer_)
-            {
-                CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
-                delete[] buffer_;
-            }
-            buffer_ = newBuffer;
-        }
-
-        size_ = newSize;
-    }
-
-    /// Resize the vector and fill new elements with default value.
-    void Resize(unsigned newSize, const T& value)
-    {
-        unsigned oldSize = Size();
-        Resize(newSize);
-        for (unsigned i = oldSize; i < newSize; ++i)
-            At(i) = value;
-    }
-
-    /// Set new capacity.
-    void Reserve(unsigned newCapacity)
-    {
-        if (newCapacity < size_)
-            newCapacity = size_;
-
-        if (newCapacity != capacity_)
-        {
-            unsigned char* newBuffer = nullptr;
-            capacity_ = newCapacity;
-
-            if (capacity_)
-            {
-                newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
-                // Move the data into the new buffer
-                CopyElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
-            }
-
-            // Delete the old buffer
-            delete[] buffer_;
-            buffer_ = newBuffer;
-        }
-    }
-
-    /// Reallocate so that no extra memory is used.
-    void Compact() { Reserve(size_); }
-
-    /// Return iterator to value, or to the end if not found.
-    Iterator Find(const T& value)
-    {
-        Iterator it = Begin();
-        while (it != End() && *it != value)
-            ++it;
-        return it;
-    }
-
-    /// Return const iterator to value, or to the end if not found.
-    ConstIterator Find(const T& value) const
-    {
-        ConstIterator it = Begin();
-        while (it != End() && *it != value)
-            ++it;
-        return it;
-    }
-
-    /// Return index of value in vector, or size if not found.
-    unsigned IndexOf(const T& value) const
-    {
-        return Find(value) - Begin();
-    }
-
-    /// Return whether contains a specific value.
-    bool Contains(const T& value) const { return Find(value) != End(); }
-
-    /// Return iterator to the beginning.
-    Iterator Begin() { return Iterator(Buffer()); }
-
-    /// Return const iterator to the beginning.
-    ConstIterator Begin() const { return ConstIterator(Buffer()); }
-
-    /// Return iterator to the end.
-    Iterator End() { return Iterator(Buffer() + size_); }
-
-    /// Return const iterator to the end.
-    ConstIterator End() const { return ConstIterator(Buffer() + size_); }
-
-    /// Return first element.
-    T& Front() { return Buffer()[0]; }
-
-    /// Return const first element.
-    const T& Front() const { return Buffer()[0]; }
-
-    /// Return last element.
-    T& Back()
-    {
-        assert(size_);
-        return Buffer()[size_ - 1];
-    }
-
-    /// Return const last element.
-    const T& Back() const
-    {
-        assert(size_);
-        return Buffer()[size_ - 1];
-    }
-
-    /// Return number of elements.
-    unsigned Size() const { return size_; }
-
-    /// Return capacity of vector.
-    unsigned Capacity() const { return capacity_; }
-
-    /// Return whether vector is empty.
-    bool Empty() const { return size_ == 0; }
-
-    /// Return the buffer with right type.
-    T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
-
-private:
-    /// Move a range of elements within the vector.
-    void MoveRange(unsigned dest, unsigned src, unsigned count)
-    {
-        if (count)
-            memmove(Buffer() + dest, Buffer() + src, count * sizeof(T));
-    }
-
-    /// Copy elements from one buffer to another.
-    static void CopyElements(T* dest, const T* src, unsigned count)
-    {
-        if (count)
-            memcpy(dest, src, count * sizeof(T));
-    }
-};
-
-template <class T> typename Urho3D::Vector<T>::ConstIterator begin(const Urho3D::Vector<T>& v) { return v.Begin(); }
-
-template <class T> typename Urho3D::Vector<T>::ConstIterator end(const Urho3D::Vector<T>& v) { return v.End(); }
-
-template <class T> typename Urho3D::Vector<T>::Iterator begin(Urho3D::Vector<T>& v) { return v.Begin(); }
+template <class T> typename Urho3D::Vector<T>::Iterator begin(Urho3D::Vector<T>& v) { return v.Begin(); }
 
 
 template <class T> typename Urho3D::Vector<T>::Iterator end(Urho3D::Vector<T>& v) { return v.End(); }
 template <class T> typename Urho3D::Vector<T>::Iterator end(Urho3D::Vector<T>& v) { return v.End(); }
 
 
-template <class T> typename Urho3D::PODVector<T>::ConstIterator begin(const Urho3D::PODVector<T>& v) { return v.Begin(); }
-
-template <class T> typename Urho3D::PODVector<T>::ConstIterator end(const Urho3D::PODVector<T>& v) { return v.End(); }
-
-template <class T> typename Urho3D::PODVector<T>::Iterator begin(Urho3D::PODVector<T>& v) { return v.Begin(); }
-
-template <class T> typename Urho3D::PODVector<T>::Iterator end(Urho3D::PODVector<T>& v) { return v.End(); }
-
 }
 }
 
 
 #ifdef _MSC_VER
 #ifdef _MSC_VER

+ 3 - 0
Source/Urho3D/UI/Text.h

@@ -56,6 +56,9 @@ struct CharLocation
 /// @nobind
 /// @nobind
 struct GlyphLocation
 struct GlyphLocation
 {
 {
+    /// Fields are not initialized.
+    GlyphLocation() = default;
+
     /// Construct.
     /// Construct.
     GlyphLocation(float x, float y, const FontGlyph* glyph) :
     GlyphLocation(float x, float y, const FontGlyph* glyph) :
         x_(x),
         x_(x),

+ 2 - 2
cmake/Modules/UrhoCommon.cmake

@@ -509,11 +509,11 @@ if (WIN32 AND NOT CMAKE_PROJECT_NAME MATCHES ^Urho3D-ExternalProject-)
 endif ()
 endif ()
 
 
 # Platform and compiler specific options
 # Platform and compiler specific options
-set (CMAKE_CXX_STANDARD 11)
+set (CMAKE_CXX_STANDARD 17)
 set (CMAKE_CXX_STANDARD_REQUIRED ON)
 set (CMAKE_CXX_STANDARD_REQUIRED ON)
 set (CMAKE_CXX_EXTENSIONS OFF)
 set (CMAKE_CXX_EXTENSIONS OFF)
 if (EMSCRIPTEN)     # It appears CMake does not detect C++standard for EMCC correctly, so do it the old way still
 if (EMSCRIPTEN)     # It appears CMake does not detect C++standard for EMCC correctly, so do it the old way still
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
 endif ()
 endif ()
 if (APPLE)
 if (APPLE)
     if (IOS)
     if (IOS)