]> git.lizzy.rs Git - irrlicht.git/commitdiff
Make irrArray backed by std::vector (#101)
authorparadust7 <102263465+paradust7@users.noreply.github.com>
Sat, 21 May 2022 21:56:36 +0000 (14:56 -0700)
committerGitHub <noreply@github.com>
Sat, 21 May 2022 21:56:36 +0000 (23:56 +0200)
include/ISkinnedMesh.h
include/heapsort.h [deleted file]
include/irrArray.h
include/irrlicht.h
source/Irrlicht/COBJMeshFileLoader.cpp
source/Irrlicht/COGLESDriver.cpp
source/Irrlicht/COGLESDriver.h
source/Irrlicht/CSceneManager.h
source/Irrlicht/CSkinnedMesh.cpp
source/Irrlicht/CSkinnedMesh.h

index 44d05e588ad5b36ffb0c2386560d8377e648899d..33ae23c474cd40c37e0fd82107c2b8ed8fa95516 100644 (file)
@@ -100,7 +100,7 @@ namespace scene
                private:\r
                        //! Internal members used by CSkinnedMesh\r
                        friend class CSkinnedMesh;\r
-                       bool *Moved;\r
+                       char *Moved;\r
                        core::vector3df StaticPos;\r
                        core::vector3df StaticNormal;\r
                };\r
diff --git a/include/heapsort.h b/include/heapsort.h
deleted file mode 100644 (file)
index 36211c4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt\r
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-\r
-#ifndef __IRR_HEAPSORT_H_INCLUDED__\r
-#define __IRR_HEAPSORT_H_INCLUDED__\r
-\r
-#include "irrTypes.h"\r
-\r
-namespace irr\r
-{\r
-namespace core\r
-{\r
-\r
-//! Sinks an element into the heap.\r
-template<class T>\r
-inline void heapsink(T*array, s32 element, s32 max)\r
-{\r
-       while ((element<<1) < max) // there is a left child\r
-       {\r
-               s32 j = (element<<1);\r
-\r
-               if (j+1 < max && array[j] < array[j+1])\r
-                       j = j+1; // take right child\r
-\r
-               if (array[element] < array[j])\r
-               {\r
-                       T t = array[j]; // swap elements\r
-                       array[j] = array[element];\r
-                       array[element] = t;\r
-                       element = j;\r
-               }\r
-               else\r
-                       return;\r
-       }\r
-}\r
-\r
-\r
-//! Sorts an array with size 'size' using heapsort.\r
-template<class T>\r
-inline void heapsort(T* array_, s32 size)\r
-{\r
-       // for heapsink we pretend this is not c++, where\r
-       // arrays start with index 0. So we decrease the array pointer,\r
-       // the maximum always +2 and the element always +1\r
-\r
-       T* virtualArray = array_ - 1;\r
-       s32 virtualSize = size + 2;\r
-       s32 i;\r
-\r
-       // build heap\r
-\r
-       for (i=((size-1)/2); i>=0; --i)\r
-               heapsink(virtualArray, i+1, virtualSize-1);\r
-\r
-       // sort array, leave out the last element (0)\r
-       for (i=size-1; i>0; --i)\r
-       {\r
-               T t = array_[0];\r
-               array_[0] = array_[i];\r
-               array_[i] = t;\r
-               heapsink(virtualArray, 1, i + 1);\r
-       }\r
-}\r
-\r
-} // end namespace core\r
-} // end namespace irr\r
-\r
-#endif\r
-\r
index 99ecb2de22776fad51c4333b3a19d810a1a3509e..dbad8c872a33eb386c3069dee9da784b7d7a426d 100644 (file)
@@ -5,9 +5,11 @@
 #ifndef __IRR_ARRAY_H_INCLUDED__\r
 #define __IRR_ARRAY_H_INCLUDED__\r
 \r
+#include <algorithm>\r
+#include <iterator>\r
+#include <vector>\r
+\r
 #include "irrTypes.h"\r
-#include "heapsort.h"\r
-#include "irrAllocator.h"\r
 #include "irrMath.h"\r
 \r
 namespace irr\r
@@ -18,44 +20,27 @@ namespace core
 //! Self reallocating template array (like stl vector) with additional features.\r
 /** Some features are: Heap sorting, binary search methods, easier debugging.\r
 */\r
-template <class T, typename TAlloc = irrAllocator<T> >\r
+template <class T>\r
 class array\r
 {\r
-\r
 public:\r
+       static_assert(!std::is_same<T, bool>::value,\r
+               "irr::core::array<T> with T = bool not supported. Use std::vector instead.");\r
 \r
        //! Default constructor for empty array.\r
-       array() : data(0), allocated(0), used(0),\r
-                       strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true)\r
-       {\r
-       }\r
-\r
+       array() : m_data(), is_sorted(true)\r
+       { }\r
 \r
        //! Constructs an array and allocates an initial chunk of memory.\r
        /** \param start_count Amount of elements to pre-allocate. */\r
-       explicit array(u32 start_count) : data(0), allocated(0), used(0),\r
-                       strategy(ALLOC_STRATEGY_DOUBLE),\r
-                       free_when_destroyed(true), is_sorted(true)\r
+       explicit array(u32 start_count) : m_data(), is_sorted(true)\r
        {\r
-               reallocate(start_count);\r
+               m_data.reserve(start_count);\r
        }\r
 \r
-\r
        //! Copy constructor\r
-       array(const array<T, TAlloc>& other) : data(0)\r
-       {\r
-               *this = other;\r
-       }\r
-\r
-\r
-       //! Destructor.\r
-       /** Frees allocated memory, if set_free_when_destroyed was not set to\r
-       false by the user before. */\r
-       ~array()\r
-       {\r
-               clear();\r
-       }\r
-\r
+       array(const array<T>& other) : m_data(other.m_data), is_sorted(other.is_sorted)\r
+       { }\r
 \r
        //! Reallocates the array, make it bigger or smaller.\r
        /** \param new_size New size of array.\r
@@ -65,52 +50,28 @@ public:
        */\r
        void reallocate(u32 new_size, bool canShrink=true)\r
        {\r
-               if (allocated==new_size)\r
-                       return;\r
-               if (!canShrink && (new_size < allocated))\r
-                       return;\r
-\r
-               T* old_data = data;\r
-\r
-               data = allocator.allocate(new_size); //new T[new_size];\r
-               allocated = new_size;\r
-\r
-               // copy old data\r
-               const s32 end = used < new_size ? used : new_size;\r
-\r
-               for (s32 i=0; i<end; ++i)\r
-               {\r
-                       // data[i] = old_data[i];\r
-                       allocator.construct(&data[i], old_data[i]);\r
+               size_t allocated = m_data.capacity();\r
+               if (new_size < allocated) {\r
+                       if (canShrink)\r
+                               m_data.resize(new_size);\r
+               } else {\r
+                       m_data.reserve(new_size);\r
                }\r
-\r
-               // destruct old data\r
-               for (u32 j=0; j<used; ++j)\r
-                       allocator.destruct(&old_data[j]);\r
-\r
-               if (allocated < used)\r
-                       used = allocated;\r
-\r
-               allocator.deallocate(old_data); //delete [] old_data;\r
        }\r
 \r
-\r
-       //! set a new allocation strategy\r
-       /** if the maximum size of the array is unknown, you can define how big the\r
-       allocation should happen.\r
-       \param newStrategy New strategy to apply to this array. */\r
-       void setAllocStrategy ( eAllocStrategy newStrategy = ALLOC_STRATEGY_DOUBLE )\r
-       {\r
-               strategy = newStrategy;\r
-       }\r
-\r
-\r
        //! Adds an element at back of array.\r
        /** If the array is too small to add this new element it is made bigger.\r
        \param element: Element to add at the back of the array. */\r
        void push_back(const T& element)\r
        {\r
-               insert(element, used);\r
+               m_data.push_back(element);\r
+               is_sorted = false;\r
+       }\r
+\r
+       void push_back(T&& element)\r
+       {\r
+               m_data.push_back(std::move(element));\r
+               is_sorted = false;\r
        }\r
 \r
 \r
@@ -121,7 +82,14 @@ public:
        \param element Element to add at the back of the array. */\r
        void push_front(const T& element)\r
        {\r
-               insert(element);\r
+               m_data.insert(m_data.begin(), element);\r
+               is_sorted = false;\r
+       }\r
+\r
+       void push_front(T&& element)\r
+       {\r
+               m_data.insert(m_data.begin(), std::move(element));\r
+               is_sorted = false;\r
        }\r
 \r
 \r
@@ -131,106 +99,21 @@ public:
        \param index: Where position to insert the new element. */\r
        void insert(const T& element, u32 index=0)\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>used) // access violation\r
-\r
-               if (used + 1 > allocated)\r
-               {\r
-                       // this doesn't work if the element is in the same\r
-                       // array. So we'll copy the element first to be sure\r
-                       // we'll get no data corruption\r
-                       const T e(element);\r
-\r
-                       // increase data block\r
-                       u32 newAlloc;\r
-                       switch ( strategy )\r
-                       {\r
-                               case ALLOC_STRATEGY_DOUBLE:\r
-                                       newAlloc = used + 5 + (allocated < 500 ? used : used >> 2);\r
-                                       break;\r
-                               default:\r
-                               case ALLOC_STRATEGY_SAFE:\r
-                                       newAlloc = used + 1;\r
-                                       break;\r
-                       }\r
-                       reallocate( newAlloc);\r
-\r
-                       // move array content and construct new element\r
-                       // first move end one up\r
-                       for (u32 i=used; i>index; --i)\r
-                       {\r
-                               if (i<used)\r
-                                       allocator.destruct(&data[i]);\r
-                               allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];\r
-                       }\r
-                       // then add new element\r
-                       if (used > index)\r
-                               allocator.destruct(&data[index]);\r
-                       allocator.construct(&data[index], e); // data[index] = e;\r
-               }\r
-               else\r
-               {\r
-                       // element inserted not at end\r
-                       if ( used > index )\r
-                       {\r
-                               // create one new element at the end\r
-                               allocator.construct(&data[used], data[used-1]);\r
-\r
-                               // move the rest of the array content\r
-                               for (u32 i=used-1; i>index; --i)\r
-                               {\r
-                                       data[i] = data[i-1];\r
-                               }\r
-                               // insert the new element\r
-                               data[index] = element;\r
-                       }\r
-                       else\r
-                       {\r
-                               // insert the new element to the end\r
-                               allocator.construct(&data[index], element);\r
-                       }\r
-               }\r
-               // set to false as we don't know if we have the comparison operators\r
+               _IRR_DEBUG_BREAK_IF(index > m_data.size()) // access violation\r
+               auto pos = std::next(m_data.begin(), index);\r
+               m_data.insert(pos, element);\r
                is_sorted = false;\r
-               ++used;\r
        }\r
 \r
-\r
        //! Clears the array and deletes all allocated memory.\r
        void clear()\r
        {\r
-               if (free_when_destroyed)\r
-               {\r
-                       for (u32 i=0; i<used; ++i)\r
-                               allocator.destruct(&data[i]);\r
-\r
-                       allocator.deallocate(data); // delete [] data;\r
-               }\r
-               data = 0;\r
-               used = 0;\r
-               allocated = 0;\r
+               // vector::clear() reduces the size to 0, but doesn't free memory.\r
+               // This swap is guaranteed to delete the allocated memory.\r
+               std::vector<T>().swap(m_data);\r
                is_sorted = true;\r
        }\r
 \r
-\r
-       //! Sets pointer to new array, using this as new workspace.\r
-       /** Make sure that set_free_when_destroyed is used properly.\r
-       \param newPointer: Pointer to new array of elements.\r
-       \param size: Size of the new array.\r
-       \param _is_sorted Flag which tells whether the new array is already\r
-       sorted.\r
-       \param _free_when_destroyed Sets whether the new memory area shall be\r
-       freed by the array upon destruction, or if this will be up to the user\r
-       application. */\r
-       void set_pointer(T* newPointer, u32 size, bool _is_sorted=false, bool _free_when_destroyed=true)\r
-       {\r
-               clear();\r
-               data = newPointer;\r
-               allocated = size;\r
-               used = size;\r
-               is_sorted = _is_sorted;\r
-               free_when_destroyed=_free_when_destroyed;\r
-       }\r
-\r
        //! Set (copy) data from given memory block\r
        /** \param newData data to set, must have newSize elements\r
        \param newSize Amount of elements in newData\r
@@ -240,12 +123,11 @@ public:
        */\r
        void set_data(const T* newData, u32 newSize, bool newDataIsSorted=false, bool canShrink=false)\r
        {\r
-               reallocate(newSize, canShrink);\r
-               set_used(newSize);\r
-               for ( u32 i=0; i<newSize; ++i)\r
-               {\r
-                       data[i] = newData[i];\r
+               m_data.resize(newSize);\r
+               if (canShrink) {\r
+                       m_data.shrink_to_fit();\r
                }\r
+               std::copy(newData, newData + newSize, m_data.begin());\r
                is_sorted = newDataIsSorted;\r
        }\r
 \r
@@ -255,85 +137,51 @@ public:
        \param size Amount of elements in otherData     */\r
        bool equals(const T* otherData, u32 size) const\r
        {\r
-               if (used != size)\r
+               if (m_data.size() != size)\r
                        return false;\r
-\r
-               for (u32 i=0; i<size; ++i)\r
-                       if (data[i] != otherData[i])\r
-                               return false;\r
-               return true;\r
+               return std::equal(m_data.begin(), m_data.end(), otherData);\r
        }\r
 \r
-\r
-\r
-       //! Sets if the array should delete the memory it uses upon destruction.\r
-       /** Also clear and set_pointer will only delete the (original) memory\r
-       area if this flag is set to true, which is also the default. The\r
-       methods reallocate, set_used, push_back, push_front, insert, and erase\r
-       will still try to deallocate the original memory, which might cause\r
-       troubles depending on the intended use of the memory area.\r
-       \param f If true, the array frees the allocated memory in its\r
-       destructor, otherwise not. The default is true. */\r
-       void set_free_when_destroyed(bool f)\r
-       {\r
-               free_when_destroyed = f;\r
-       }\r
-\r
-\r
        //! Sets the size of the array and allocates new elements if necessary.\r
-       /** Please note: This is only secure when using it with simple types,\r
-       because no default constructor will be called for the added elements.\r
-       \param usedNow Amount of elements now used. */\r
+       /** \param usedNow Amount of elements now used. */\r
        void set_used(u32 usedNow)\r
        {\r
-               if (allocated < usedNow)\r
-                       reallocate(usedNow);\r
-\r
-               used = usedNow;\r
+               m_data.resize(usedNow);\r
        }\r
 \r
        //! Assignment operator\r
-       const array<T, TAlloc>& operator=(const array<T, TAlloc>& other)\r
+       const array<T>& operator=(const array<T>& other)\r
        {\r
                if (this == &other)\r
                        return *this;\r
-               strategy = other.strategy;\r
-\r
-               // (TODO: we could probably avoid re-allocations of data when (allocated < other.allocated)\r
-\r
-               if (data)\r
-                       clear();\r
-\r
-               used = other.used;\r
-               free_when_destroyed = true;\r
+               m_data = other.m_data;\r
                is_sorted = other.is_sorted;\r
-               allocated = other.allocated;\r
-\r
-               if (other.allocated == 0)\r
-               {\r
-                       data = 0;\r
-               }\r
-               else\r
-               {\r
-                       data = allocator.allocate(other.allocated); // new T[other.allocated];\r
-\r
-                       for (u32 i=0; i<other.used; ++i)\r
-                               allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i];\r
-               }\r
+               return *this;\r
+       }\r
 \r
+       array<T>& operator=(const std::vector<T> &other)\r
+       {\r
+               m_data = other;\r
+               is_sorted = false;\r
                return *this;\r
        }\r
 \r
+       array<T>& operator=(std::vector<T> &&other)\r
+       {\r
+               m_data = std::move(other);\r
+               is_sorted = false;\r
+               return *this;\r
+       }\r
 \r
        //! Equality operator\r
-       bool operator == (const array<T, TAlloc>& other) const\r
+       bool operator == (const array<T>& other) const\r
        {\r
                return equals(other.const_pointer(), other.size());\r
        }\r
 \r
 \r
        //! Inequality operator\r
-       bool operator != (const array<T, TAlloc>& other) const\r
+       bool operator != (const array<T>& other) const\r
        {\r
                return !(*this==other);\r
        }\r
@@ -342,36 +190,36 @@ public:
        //! Direct access operator\r
        T& operator [](u32 index)\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // access violation\r
+               _IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation\r
 \r
-               return data[index];\r
+               return m_data[index];\r
        }\r
 \r
 \r
        //! Direct const access operator\r
        const T& operator [](u32 index) const\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // access violation\r
+               _IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation\r
 \r
-               return data[index];\r
+               return m_data[index];\r
        }\r
 \r
 \r
        //! Gets last element.\r
        T& getLast()\r
        {\r
-               _IRR_DEBUG_BREAK_IF(!used) // access violation\r
+               _IRR_DEBUG_BREAK_IF(m_data.empty()) // access violation\r
 \r
-               return data[used-1];\r
+               return m_data.back();\r
        }\r
 \r
 \r
        //! Gets last element\r
        const T& getLast() const\r
        {\r
-               _IRR_DEBUG_BREAK_IF(!used) // access violation\r
+               _IRR_DEBUG_BREAK_IF(m_data.empty()) // access violation\r
 \r
-               return data[used-1];\r
+               return m_data.back();\r
        }\r
 \r
 \r
@@ -379,7 +227,7 @@ public:
        /** \return Pointer to the array. */\r
        T* pointer()\r
        {\r
-               return data;\r
+               return &m_data[0];\r
        }\r
 \r
 \r
@@ -387,7 +235,7 @@ public:
        /** \return Pointer to the array. */\r
        const T* const_pointer() const\r
        {\r
-               return data;\r
+               return &m_data[0];\r
        }\r
 \r
 \r
@@ -395,7 +243,7 @@ public:
        /** \return Size of elements in the array which are actually occupied. */\r
        u32 size() const\r
        {\r
-               return used;\r
+               return m_data.size();\r
        }\r
 \r
 \r
@@ -404,7 +252,7 @@ public:
        allocated would be allocated_size() * sizeof(ElementTypeUsed); */\r
        u32 allocated_size() const\r
        {\r
-               return allocated;\r
+               return m_data.capacity();\r
        }\r
 \r
 \r
@@ -412,7 +260,7 @@ public:
        /** \return True if the array is empty false if not. */\r
        bool empty() const\r
        {\r
-               return used == 0;\r
+               return m_data.empty();\r
        }\r
 \r
 \r
@@ -421,9 +269,10 @@ public:
        O(n*log n) in worst case. */\r
        void sort()\r
        {\r
-               if (!is_sorted && used>1)\r
-                       heapsort(data, used);\r
-               is_sorted = true;\r
+               if (!is_sorted) {\r
+                       std::sort(m_data.begin(), m_data.end());\r
+                       is_sorted = true;\r
+               }\r
        }\r
 \r
 \r
@@ -437,10 +286,9 @@ public:
        s32 binary_search(const T& element)\r
        {\r
                sort();\r
-               return binary_search(element, 0, used-1);\r
+               return binary_search(element, 0, (s32)m_data.size() - 1);\r
        }\r
 \r
-\r
        //! Performs a binary search for an element if possible, returns -1 if not found.\r
        /** This method is for const arrays and so cannot call sort(), if the array is\r
        not sorted then linear_search will be used instead. Potentially very slow!\r
@@ -450,12 +298,11 @@ public:
        s32 binary_search(const T& element) const\r
        {\r
                if (is_sorted)\r
-                       return binary_search(element, 0, used-1);\r
+                       return binary_search(element, 0, (s32)m_data.size() - 1);\r
                else\r
                        return linear_search(element);\r
        }\r
 \r
-\r
        //! Performs a binary search for an element, returns -1 if not found.\r
        /** \param element: Element to search for.\r
        \param left First left index\r
@@ -464,31 +311,15 @@ public:
        is returned. */\r
        s32 binary_search(const T& element, s32 left, s32 right) const\r
        {\r
-               if (!used)\r
+               if (left > right)\r
                        return -1;\r
-\r
-               s32 m;\r
-\r
-               do\r
-               {\r
-                       m = (left+right)>>1;\r
-\r
-                       if (element < data[m])\r
-                               right = m - 1;\r
-                       else\r
-                               left = m + 1;\r
-\r
-               } while((element < data[m] || data[m] < element) && left<=right);\r
-               // this last line equals to:\r
-               // " while((element != array[m]) && left<=right);"\r
-               // but we only want to use the '<' operator.\r
-               // the same in next line, it is "(element == array[m])"\r
-\r
-\r
-               if (!(element < data[m]) && !(data[m] < element))\r
-                       return m;\r
-\r
-               return -1;\r
+               auto lpos = std::next(m_data.begin(), left);\r
+               auto rpos = std::next(m_data.begin(), right);\r
+               auto it = std::lower_bound(lpos, rpos, element);\r
+               // *it = first element in [first, last) that is >= element, or last if not found.\r
+               if (*it < element || element < *it)\r
+                       return -1;\r
+               return it - m_data.begin();\r
        }\r
 \r
 \r
@@ -503,25 +334,11 @@ public:
        s32 binary_search_multi(const T& element, s32 &last)\r
        {\r
                sort();\r
-               s32 index = binary_search(element, 0, used-1);\r
-               if ( index < 0 )\r
-                       return index;\r
-\r
-               // The search can be somewhere in the middle of the set\r
-               // look linear previous and past the index\r
-               last = index;\r
-\r
-               while ( index > 0 && !(element < data[index - 1]) && !(data[index - 1] < element) )\r
-               {\r
-                       index -= 1;\r
-               }\r
-               // look linear up\r
-               while ( last < (s32) used - 1 && !(element < data[last + 1]) && !(data[last + 1] < element) )\r
-               {\r
-                       last += 1;\r
-               }\r
-\r
-               return index;\r
+               auto iters = std::equal_range(m_data.begin(), m_data.end(), element);\r
+               if (iters.first == iters.second)\r
+                       return -1;\r
+               last = (iters.second - m_data.begin()) - 1;\r
+               return iters.first - m_data.begin();\r
        }\r
 \r
 \r
@@ -533,11 +350,10 @@ public:
        is returned. */\r
        s32 linear_search(const T& element) const\r
        {\r
-               for (u32 i=0; i<used; ++i)\r
-                       if (element == data[i])\r
-                               return (s32)i;\r
-\r
-               return -1;\r
+               auto it = std::find(m_data.begin(), m_data.end(), element);\r
+               if (it == m_data.end())\r
+                       return -1;\r
+               return it - m_data.begin();\r
        }\r
 \r
 \r
@@ -549,11 +365,11 @@ public:
        is returned. */\r
        s32 linear_reverse_search(const T& element) const\r
        {\r
-               for (s32 i=used-1; i>=0; --i)\r
-                       if (data[i] == element)\r
-                               return i;\r
-\r
-               return -1;\r
+               auto it = std::find(m_data.rbegin(), m_data.rend(), element);\r
+               if (it == m_data.rend())\r
+                       return -1;\r
+               size_t offset = it - m_data.rbegin();\r
+               return m_data.size() - offset - 1;\r
        }\r
 \r
 \r
@@ -563,17 +379,9 @@ public:
        \param index: Index of element to be erased. */\r
        void erase(u32 index)\r
        {\r
-               _IRR_DEBUG_BREAK_IF(index>=used) // access violation\r
-\r
-               for (u32 i=index+1; i<used; ++i)\r
-               {\r
-                       allocator.destruct(&data[i-1]);\r
-                       allocator.construct(&data[i-1], data[i]); // data[i-1] = data[i];\r
-               }\r
-\r
-               allocator.destruct(&data[used-1]);\r
-\r
-               --used;\r
+               _IRR_DEBUG_BREAK_IF(index >= m_data.size()) // access violation\r
+               auto it = std::next(m_data.begin(), index);\r
+               m_data.erase(it);\r
        }\r
 \r
 \r
@@ -584,30 +392,14 @@ public:
        \param count: Amount of elements to be erased. */\r
        void erase(u32 index, s32 count)\r
        {\r
-               if (index>=used || count<1)\r
+               if (index >= m_data.size() || count < 1)\r
                        return;\r
-               if (index+count>used)\r
-                       count = used-index;\r
-\r
-               u32 i;\r
-               for (i=index; i<index+count; ++i)\r
-                       allocator.destruct(&data[i]);\r
-\r
-               for (i=index+count; i<used; ++i)\r
-               {\r
-                       if (i-count >= index+count) // not already destructed before loop\r
-                               allocator.destruct(&data[i-count]);\r
-\r
-                       allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i];\r
-\r
-                       if (i >= used-count) // those which are not overwritten\r
-                               allocator.destruct(&data[i]);\r
-               }\r
-\r
-               used-= count;\r
+               count = std::min(count, (s32)m_data.size() - (s32)index);\r
+               auto first = std::next(m_data.begin(), index);\r
+               auto last = std::next(first, count);\r
+               m_data.erase(first, last);\r
        }\r
 \r
-\r
        //! Sets if the array is sorted\r
        void set_sorted(bool _is_sorted)\r
        {\r
@@ -619,38 +411,30 @@ public:
        /** Afterward this object will contain the content of the other object and the other\r
        object will contain the content of this object.\r
        \param other Swap content with this object */\r
-       void swap(array<T, TAlloc>& other)\r
-       {\r
-               core::swap(data, other.data);\r
-               core::swap(allocated, other.allocated);\r
-               core::swap(used, other.used);\r
-               core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation\r
-               eAllocStrategy helper_strategy(strategy); // can't use core::swap with bitfields\r
-               strategy = other.strategy;\r
-               other.strategy = helper_strategy;\r
-               bool helper_free_when_destroyed(free_when_destroyed);\r
-               free_when_destroyed = other.free_when_destroyed;\r
-               other.free_when_destroyed = helper_free_when_destroyed;\r
-               bool helper_is_sorted(is_sorted);\r
-               is_sorted = other.is_sorted;\r
-               other.is_sorted = helper_is_sorted;\r
+       void swap(array<T>& other)\r
+       {\r
+               m_data.swap(other.m_data);\r
+               std::swap(is_sorted, other.is_sorted);\r
+       }\r
+\r
+       //! Pull the contents of this array as a vector.\r
+       // The array is left empty.\r
+       std::vector<T> steal()\r
+       {\r
+               std::vector<T> ret = std::move(m_data);\r
+               m_data.clear();\r
+               is_sorted = true;\r
+               return ret;\r
        }\r
 \r
-       typedef TAlloc allocator_type;\r
        typedef T value_type;\r
        typedef u32 size_type;\r
 \r
 private:\r
-       T* data;\r
-       u32 allocated;\r
-       u32 used;\r
-       TAlloc allocator;\r
-       eAllocStrategy strategy:4;\r
-       bool free_when_destroyed:1;\r
-       bool is_sorted:1;\r
+       std::vector<T> m_data;\r
+       bool is_sorted;\r
 };\r
 \r
-\r
 } // end namespace core\r
 } // end namespace irr\r
 \r
index 706795a38c29f63c18b14b038cae83721f06e8ce..978643625c9a5365d7920740cf7cfb55e676c5af 100644 (file)
@@ -50,7 +50,6 @@
 #include "EMessageBoxFlags.h"\r
 #include "ESceneNodeTypes.h"\r
 #include "fast_atof.h"\r
-#include "heapsort.h"\r
 #include "IAnimatedMesh.h"\r
 #include "IAnimatedMeshSceneNode.h"\r
 #include "IAttributes.h"\r
index cdd953b1667278ad90e02c367a81688d19da4b35..8746eb6196c7febd21770a11689783ee480c0c12 100644 (file)
@@ -70,9 +70,9 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
 \r
        const u32 WORD_BUFFER_LENGTH = 512;\r
 \r
-       core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > vertexBuffer(1000);\r
-       core::array<core::vector3df, core::irrAllocatorFast<core::vector3df> > normalsBuffer(1000);\r
-       core::array<core::vector2df, core::irrAllocatorFast<core::vector2df> > textureCoordBuffer(1000);\r
+       core::array<core::vector3df> vertexBuffer(1000);\r
+       core::array<core::vector3df> normalsBuffer(1000);\r
+       core::array<core::vector2df> textureCoordBuffer(1000);\r
 \r
        SObjMtl * currMtl = new SObjMtl();\r
        Materials.push_back(currMtl);\r
index a48909e18298d658f1b3d798027082e32b9053ac..4ee95eabb4671bc6b9325313aae245b3bffddc92 100644 (file)
@@ -112,12 +112,12 @@ bool COGLES1Driver::genericDriverInit(const core::dimension2d<u32>& screenSize,
        glPixelStorei(GL_PACK_ALIGNMENT, 1);\r
 \r
        UserClipPlane.reallocate(MaxUserClipPlanes);\r
-       UserClipPlaneEnabled.reallocate(MaxUserClipPlanes);\r
+       UserClipPlaneEnabled.resize(MaxUserClipPlanes);\r
 \r
        for (s32 i = 0; i < MaxUserClipPlanes; ++i)\r
        {\r
                UserClipPlane.push_back(core::plane3df());\r
-               UserClipPlaneEnabled.push_back(false);\r
+               UserClipPlaneEnabled[i] = false;\r
        }\r
 \r
        for (s32 i = 0; i < ETS_COUNT; ++i)\r
index 85e51566cf70c6fc818ab3078b622d9c1311120b..2e04848e9788f5169594c20037d01488df50d401 100644 (file)
@@ -363,7 +363,7 @@ namespace video
 \r
                SMaterial Material, LastMaterial;\r
                core::array<core::plane3df> UserClipPlane;\r
-               core::array<bool> UserClipPlaneEnabled;\r
+               std::vector<bool> UserClipPlaneEnabled;\r
 \r
                core::stringc VendorName;\r
 \r
index dcad727990bd7534ca37cc29ba99bf5796a61849..6af151f8779da1250815d04fdfbea5491ffd2512 100644 (file)
@@ -231,6 +231,9 @@ namespace scene
 \r
                struct DefaultNodeEntry\r
                {\r
+                       DefaultNodeEntry()\r
+                       { }\r
+\r
                        DefaultNodeEntry(ISceneNode* n) :\r
                                Node(n), TextureValue(0)\r
                        {\r
@@ -251,6 +254,9 @@ namespace scene
                //! sort on distance (center) to camera\r
                struct TransparentNodeEntry\r
                {\r
+                       TransparentNodeEntry()\r
+                       { }\r
+\r
                        TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera)\r
                                : Node(n)\r
                        {\r
index e41d6c3e8393d7325b23255f581d9c6b64a2e9a3..9f47f3b68a6663c54d10acd5e842a41ae7b65eb3 100644 (file)
@@ -1042,7 +1042,7 @@ void CSkinnedMesh::finalize()
 \r
        for (i=0; i<LocalBuffers.size(); ++i)\r
        {\r
-               Vertices_Moved.push_back( core::array<bool>() );\r
+               Vertices_Moved.push_back( core::array<char>() );\r
                Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());\r
        }\r
 \r
index 86d3a6bff9e4f6a8d904206f66c0b203c163e21f..f70fc3f79ebdcff37adc4aabf195569fe1602eea 100644 (file)
@@ -196,7 +196,9 @@ private:
                core::array<SJoint*> AllJoints;\r
                core::array<SJoint*> RootJoints;\r
 \r
-               core::array< core::array<bool> > Vertices_Moved;\r
+               // bool can't be used here because std::vector<bool>\r
+               // doesn't allow taking a reference to individual elements.\r
+               core::array< core::array<char> > Vertices_Moved;\r
 \r
                core::aabbox3d<f32> BoundingBox;\r
 \r