|
@@ -36,8 +36,6 @@
|
|
|
#pragma warning(disable:6293)
|
|
#pragma warning(disable:6293)
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-#define URHO3D_VECTOR_ISINSIDE(val) (&val >= Buffer() && &val < Buffer() + size_)
|
|
|
|
|
-
|
|
|
|
|
namespace Urho3D
|
|
namespace Urho3D
|
|
|
{
|
|
{
|
|
|
|
|
|
|
@@ -57,13 +55,21 @@ public:
|
|
|
/// Construct with initial size.
|
|
/// Construct with initial size.
|
|
|
explicit Vector(unsigned size)
|
|
explicit Vector(unsigned size)
|
|
|
{
|
|
{
|
|
|
- Resize(size, 0);
|
|
|
|
|
|
|
+ Resize(size);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// Construct with initial size and default value.
|
|
|
|
|
+ Vector(unsigned size, const T& value)
|
|
|
|
|
+ {
|
|
|
|
|
+ Resize(size);
|
|
|
|
|
+ for (unsigned i = 0; i < size; ++i)
|
|
|
|
|
+ At(i) = value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Construct with initial data.
|
|
/// Construct with initial data.
|
|
|
Vector(const T* data, unsigned size)
|
|
Vector(const T* data, unsigned size)
|
|
|
{
|
|
{
|
|
|
- Resize(size, data);
|
|
|
|
|
|
|
+ InsertElements(0, data, data + size);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Construct from another vector.
|
|
/// Construct from another vector.
|
|
@@ -84,7 +90,7 @@ public:
|
|
|
/// Destruct.
|
|
/// Destruct.
|
|
|
~Vector()
|
|
~Vector()
|
|
|
{
|
|
{
|
|
|
- Clear();
|
|
|
|
|
|
|
+ DestructElements(Buffer(), size_);
|
|
|
delete[] buffer_;
|
|
delete[] buffer_;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -92,7 +98,7 @@ public:
|
|
|
Vector<T>& operator =(const Vector<T>& rhs)
|
|
Vector<T>& operator =(const Vector<T>& rhs)
|
|
|
{
|
|
{
|
|
|
Clear();
|
|
Clear();
|
|
|
- Resize(rhs.size_, rhs.Buffer());
|
|
|
|
|
|
|
+ InsertElements(0, rhs.Begin(), rhs.End());
|
|
|
return *this;
|
|
return *this;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -192,14 +198,7 @@ public:
|
|
|
#ifndef COVERITY_SCAN_MODEL
|
|
#ifndef COVERITY_SCAN_MODEL
|
|
|
void Push(const T& value)
|
|
void Push(const T& value)
|
|
|
{
|
|
{
|
|
|
- if (!URHO3D_VECTOR_ISINSIDE(value))
|
|
|
|
|
- Resize(size_ + 1, &value);
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- // Value is inside vector; make copy to avoid iterator invalidation
|
|
|
|
|
- T valueCopy(value);
|
|
|
|
|
- Resize(size_ + 1, &valueCopy);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ InsertElements(size_, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
#else
|
|
#else
|
|
|
// FIXME: Attempt had been made to use this model in the Coverity-Scan model file without any success
|
|
// FIXME: Attempt had been made to use this model in the Coverity-Scan model file without any success
|
|
@@ -207,109 +206,58 @@ public:
|
|
|
void Push(const T& value)
|
|
void Push(const T& value)
|
|
|
{
|
|
{
|
|
|
T array[] = {value};
|
|
T array[] = {value};
|
|
|
- Resize(size_ + 1, array);
|
|
|
|
|
|
|
+ InsertElements(size_, array, array + 1);
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
/// Add another vector at the end.
|
|
/// Add another vector at the end.
|
|
|
- void Push(const Vector<T>& vector) { Resize(size_ + vector.size_, vector.Buffer()); }
|
|
|
|
|
|
|
+ void Push(const Vector<T>& vector) { InsertElements(size_, vector.Begin(), vector.End()); }
|
|
|
|
|
|
|
|
/// Remove the last element.
|
|
/// Remove the last element.
|
|
|
void Pop()
|
|
void Pop()
|
|
|
{
|
|
{
|
|
|
if (size_)
|
|
if (size_)
|
|
|
- Resize(size_ - 1, 0);
|
|
|
|
|
|
|
+ Resize(size_ - 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Insert an element at position.
|
|
/// Insert an element at position.
|
|
|
void Insert(unsigned pos, const T& value)
|
|
void Insert(unsigned pos, const T& value)
|
|
|
{
|
|
{
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
-
|
|
|
|
|
- unsigned oldSize = size_;
|
|
|
|
|
-
|
|
|
|
|
- if (!URHO3D_VECTOR_ISINSIDE(value))
|
|
|
|
|
- {
|
|
|
|
|
- Resize(size_ + 1, 0);
|
|
|
|
|
- MoveRange(pos + 1, pos, oldSize - pos);
|
|
|
|
|
- Buffer()[pos] = value;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- T valueCopy(value);
|
|
|
|
|
- Resize(size_ + 1, 0);
|
|
|
|
|
- MoveRange(pos + 1, pos, oldSize - pos);
|
|
|
|
|
- Buffer()[pos] = valueCopy;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ InsertElements(pos, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
-
|
|
|
|
|
- unsigned oldSize = size_;
|
|
|
|
|
- Resize(size_ + vector.size_, 0);
|
|
|
|
|
- MoveRange(pos + vector.size_, pos, oldSize - pos);
|
|
|
|
|
- CopyElements(Buffer() + pos, vector.Buffer(), vector.size_);
|
|
|
|
|
|
|
+ InsertElements(pos, vector.Begin(), vector.End());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- Insert(pos, value);
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- Insert(pos, vector);
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, vector.Begin(), vector.End());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- unsigned length = (unsigned)(end - start);
|
|
|
|
|
- Resize(size_ + length, 0);
|
|
|
|
|
- MoveRange(pos + length, pos, size_ - pos - length);
|
|
|
|
|
-
|
|
|
|
|
- T* destPtr = Buffer() + pos;
|
|
|
|
|
- for (ConstIterator it = start; it != end; ++it)
|
|
|
|
|
- *destPtr++ = *it;
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, start, end);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- unsigned length = (unsigned)(end - start);
|
|
|
|
|
- Resize(size_ + length, 0);
|
|
|
|
|
- MoveRange(pos + length, pos, size_ - pos - length);
|
|
|
|
|
-
|
|
|
|
|
- T* destPtr = Buffer() + pos;
|
|
|
|
|
- for (const T* i = start; i != end; ++i)
|
|
|
|
|
- *destPtr++ = *i;
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, start, end);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Erase a range of elements.
|
|
/// Erase a range of elements.
|
|
@@ -320,7 +268,7 @@ public:
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
MoveRange(pos, pos + length, size_ - pos - length);
|
|
MoveRange(pos, pos + length, size_ - pos - length);
|
|
|
- Resize(size_ - length, 0);
|
|
|
|
|
|
|
+ Resize(size_ - 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.
|
|
@@ -343,7 +291,7 @@ public:
|
|
|
// Swap elements from the end of the array into the empty space
|
|
// Swap elements from the end of the array into the empty space
|
|
|
CopyElements(Buffer() + pos, Buffer() + newSize, length);
|
|
CopyElements(Buffer() + pos, Buffer() + newSize, length);
|
|
|
}
|
|
}
|
|
|
- Resize(newSize, 0);
|
|
|
|
|
|
|
+ Resize(newSize);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Erase an element by iterator. Return iterator to the next element.
|
|
/// Erase an element by iterator. Return iterator to the next element.
|
|
@@ -399,7 +347,7 @@ public:
|
|
|
void Clear() { Resize(0); }
|
|
void Clear() { Resize(0); }
|
|
|
|
|
|
|
|
/// Resize the vector.
|
|
/// Resize the vector.
|
|
|
- void Resize(unsigned newSize) { Resize(newSize, 0); }
|
|
|
|
|
|
|
+ void Resize(unsigned newSize) { Vector<T> tempBuffer; Resize(newSize, 0, tempBuffer); }
|
|
|
|
|
|
|
|
/// Set new capacity.
|
|
/// Set new capacity.
|
|
|
void Reserve(unsigned newCapacity)
|
|
void Reserve(unsigned newCapacity)
|
|
@@ -503,8 +451,8 @@ public:
|
|
|
T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
|
|
T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- /// Resize the vector and create/remove new elements as necessary.
|
|
|
|
|
- void Resize(unsigned newSize, const T* src)
|
|
|
|
|
|
|
+ /// Resize the vector and create/remove new elements as necessary. Current buffer will be stored in tempBuffer in case of reallocation.
|
|
|
|
|
+ void Resize(unsigned newSize, const T* src, Vector<T>& tempBuffer)
|
|
|
{
|
|
{
|
|
|
// If size shrinks, destruct the removed elements
|
|
// If size shrinks, destruct the removed elements
|
|
|
if (newSize < size_)
|
|
if (newSize < size_)
|
|
@@ -514,6 +462,10 @@ private:
|
|
|
// Allocate new buffer if necessary and copy the current elements
|
|
// Allocate new buffer if necessary and copy the current elements
|
|
|
if (newSize > capacity_)
|
|
if (newSize > capacity_)
|
|
|
{
|
|
{
|
|
|
|
|
+ Swap(tempBuffer);
|
|
|
|
|
+ size_ = tempBuffer.size_;
|
|
|
|
|
+ capacity_ = tempBuffer.capacity_;
|
|
|
|
|
+
|
|
|
if (!capacity_)
|
|
if (!capacity_)
|
|
|
capacity_ = newSize;
|
|
capacity_ = newSize;
|
|
|
else
|
|
else
|
|
@@ -522,14 +474,11 @@ private:
|
|
|
capacity_ += (capacity_ + 1) >> 1;
|
|
capacity_ += (capacity_ + 1) >> 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- unsigned char* newBuffer = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
|
|
|
|
|
- if (buffer_)
|
|
|
|
|
|
|
+ buffer_ = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
|
|
|
|
|
+ if (tempBuffer.Buffer())
|
|
|
{
|
|
{
|
|
|
- ConstructElements(reinterpret_cast<T*>(newBuffer), Buffer(), size_);
|
|
|
|
|
- DestructElements(Buffer(), size_);
|
|
|
|
|
- delete[] buffer_;
|
|
|
|
|
|
|
+ ConstructElements(Buffer(), tempBuffer.Buffer(), size_);
|
|
|
}
|
|
}
|
|
|
- buffer_ = newBuffer;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Initialize the new elements
|
|
// Initialize the new elements
|
|
@@ -539,6 +488,26 @@ private:
|
|
|
size_ = newSize;
|
|
size_ = newSize;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// Insert elements.
|
|
|
|
|
+ template <typename RandomIteratorT>
|
|
|
|
|
+ Iterator InsertElements(unsigned pos, RandomIteratorT start, RandomIteratorT end)
|
|
|
|
|
+ {
|
|
|
|
|
+ assert(start <= end);
|
|
|
|
|
+
|
|
|
|
|
+ if (pos > size_)
|
|
|
|
|
+ pos = size_;
|
|
|
|
|
+ unsigned length = (unsigned)(end - start);
|
|
|
|
|
+ Vector<T> tempBuffer;
|
|
|
|
|
+ Resize(size_ + length, 0, tempBuffer);
|
|
|
|
|
+ MoveRange(pos + length, pos, size_ - pos - length);
|
|
|
|
|
+
|
|
|
|
|
+ T* destPtr = Buffer() + pos;
|
|
|
|
|
+ for (RandomIteratorT it = start; it != end; ++it)
|
|
|
|
|
+ *destPtr++ = *it;
|
|
|
|
|
+
|
|
|
|
|
+ return Begin() + pos;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// Move a range of elements within the vector.
|
|
/// Move a range of elements within the vector.
|
|
|
void MoveRange(unsigned dest, unsigned src, unsigned count)
|
|
void MoveRange(unsigned dest, unsigned src, unsigned count)
|
|
|
{
|
|
{
|
|
@@ -607,11 +576,18 @@ public:
|
|
|
Resize(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.
|
|
/// Construct with initial data.
|
|
|
PODVector(const T* data, unsigned size)
|
|
PODVector(const T* data, unsigned size)
|
|
|
{
|
|
{
|
|
|
- Resize(size);
|
|
|
|
|
- CopyElements(Buffer(), data, size);
|
|
|
|
|
|
|
+ InsertElements(0, data, data + size);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Construct from another vector.
|
|
/// Construct from another vector.
|
|
@@ -638,8 +614,8 @@ public:
|
|
|
/// Assign from another vector.
|
|
/// Assign from another vector.
|
|
|
PODVector<T>& operator =(const PODVector<T>& rhs)
|
|
PODVector<T>& operator =(const PODVector<T>& rhs)
|
|
|
{
|
|
{
|
|
|
- Resize(rhs.size_);
|
|
|
|
|
- CopyElements(Buffer(), rhs.Buffer(), rhs.size_);
|
|
|
|
|
|
|
+ Clear();
|
|
|
|
|
+ InsertElements(0, rhs.Begin(), rhs.End());
|
|
|
return *this;
|
|
return *this;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -738,32 +714,13 @@ public:
|
|
|
/// Add an element at the end.
|
|
/// Add an element at the end.
|
|
|
void Push(const T& value)
|
|
void Push(const T& value)
|
|
|
{
|
|
{
|
|
|
- if (!URHO3D_VECTOR_ISINSIDE(value))
|
|
|
|
|
- {
|
|
|
|
|
- if (size_ < capacity_)
|
|
|
|
|
- ++size_;
|
|
|
|
|
- else
|
|
|
|
|
- Resize(size_ + 1);
|
|
|
|
|
- Back() = value;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- // Value is inside vector; make copy to avoid iterator invalidation
|
|
|
|
|
- T valueCopy(value);
|
|
|
|
|
- if (size_ < capacity_)
|
|
|
|
|
- ++size_;
|
|
|
|
|
- else
|
|
|
|
|
- Resize(size_ + 1);
|
|
|
|
|
- Back() = valueCopy;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ InsertElements(size_, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Add another vector at the end.
|
|
/// Add another vector at the end.
|
|
|
void Push(const PODVector<T>& vector)
|
|
void Push(const PODVector<T>& vector)
|
|
|
{
|
|
{
|
|
|
- unsigned oldSize = size_;
|
|
|
|
|
- Resize(size_ + vector.size_);
|
|
|
|
|
- CopyElements(Buffer() + oldSize, vector.Buffer(), vector.size_);
|
|
|
|
|
|
|
+ InsertElements(size_, vector.Begin(), vector.End());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Remove the last element.
|
|
/// Remove the last element.
|
|
@@ -776,89 +733,41 @@ public:
|
|
|
/// Insert an element at position.
|
|
/// Insert an element at position.
|
|
|
void Insert(unsigned pos, const T& value)
|
|
void Insert(unsigned pos, const T& value)
|
|
|
{
|
|
{
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
-
|
|
|
|
|
- unsigned oldSize = size_;
|
|
|
|
|
-
|
|
|
|
|
- if (!URHO3D_VECTOR_ISINSIDE(value))
|
|
|
|
|
- {
|
|
|
|
|
- Resize(size_ + 1);
|
|
|
|
|
- MoveRange(pos + 1, pos, oldSize - pos);
|
|
|
|
|
- Buffer()[pos] = value;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- T valueCopy(value);
|
|
|
|
|
- Resize(size_ + 1);
|
|
|
|
|
- MoveRange(pos + 1, pos, oldSize - pos);
|
|
|
|
|
- Buffer()[pos] = valueCopy;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ InsertElements(pos, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Insert another vector at position.
|
|
/// Insert another vector at position.
|
|
|
void Insert(unsigned pos, const PODVector<T>& vector)
|
|
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_);
|
|
|
|
|
|
|
+ InsertElements(pos, vector.Begin(), vector.End());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- Insert(pos, value);
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, &value, &value + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Insert a vector by iterator.
|
|
/// Insert a vector by iterator.
|
|
|
Iterator Insert(const Iterator& dest, const PODVector<T>& vector)
|
|
Iterator Insert(const Iterator& dest, const PODVector<T>& vector)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- Insert(pos, vector);
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, vector.Begin(), vector.End());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- unsigned length = (unsigned)(end - start);
|
|
|
|
|
- Resize(size_ + length);
|
|
|
|
|
- MoveRange(pos + length, pos, size_ - pos - length);
|
|
|
|
|
- CopyElements(Buffer() + pos, &(*start), length);
|
|
|
|
|
-
|
|
|
|
|
- return Begin() + pos;
|
|
|
|
|
|
|
+ return InsertElements(pos, start, end);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
{
|
|
{
|
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
unsigned pos = (unsigned)(dest - Begin());
|
|
|
- if (pos > size_)
|
|
|
|
|
- pos = size_;
|
|
|
|
|
- unsigned 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;
|
|
|
|
|
|
|
+ return InsertElements(pos, start, end);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Erase a range of elements.
|
|
/// Erase a range of elements.
|
|
@@ -950,27 +859,8 @@ public:
|
|
|
/// Resize the vector.
|
|
/// Resize the vector.
|
|
|
void Resize(unsigned newSize)
|
|
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;
|
|
|
|
|
|
|
+ PODVector<T> tempBuffer;
|
|
|
|
|
+ Resize(newSize, tempBuffer);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Set new capacity.
|
|
/// Set new capacity.
|
|
@@ -1066,6 +956,52 @@ public:
|
|
|
T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
|
|
T* Buffer() const { return reinterpret_cast<T*>(buffer_); }
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
|
|
+ /// Resize the vector. Current buffer will be stored in tempBuffer in case of reallocation.
|
|
|
|
|
+ void Resize(unsigned newSize, PODVector<T>& tempBuffer)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (newSize > capacity_)
|
|
|
|
|
+ {
|
|
|
|
|
+ Swap(tempBuffer);
|
|
|
|
|
+ size_ = tempBuffer.size_;
|
|
|
|
|
+ capacity_ = tempBuffer.capacity_;
|
|
|
|
|
+
|
|
|
|
|
+ if (!capacity_)
|
|
|
|
|
+ capacity_ = newSize;
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ while (capacity_ < newSize)
|
|
|
|
|
+ capacity_ += (capacity_ + 1) >> 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ buffer_ = AllocateBuffer((unsigned)(capacity_ * sizeof(T)));
|
|
|
|
|
+ // Move the data into the new buffer
|
|
|
|
|
+ if (tempBuffer.Buffer())
|
|
|
|
|
+ {
|
|
|
|
|
+ CopyElements(Buffer(), tempBuffer.Buffer(), size_);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ size_ = newSize;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// Insert elements.
|
|
|
|
|
+ template <typename RandomIteratorT>
|
|
|
|
|
+ Iterator InsertElements(unsigned pos, RandomIteratorT start, RandomIteratorT end)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (pos > size_)
|
|
|
|
|
+ pos = size_;
|
|
|
|
|
+ unsigned length = (unsigned)(end - start);
|
|
|
|
|
+ PODVector<T> tempBuffer;
|
|
|
|
|
+ Resize(size_ + length, tempBuffer);
|
|
|
|
|
+ MoveRange(pos + length, pos, size_ - pos - length);
|
|
|
|
|
+
|
|
|
|
|
+ T* destPtr = Buffer() + pos;
|
|
|
|
|
+ for (RandomIteratorT i = start; i != end; ++i)
|
|
|
|
|
+ *destPtr++ = *i;
|
|
|
|
|
+
|
|
|
|
|
+ return Begin() + pos;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/// Move a range of elements within the vector.
|
|
/// Move a range of elements within the vector.
|
|
|
void MoveRange(unsigned dest, unsigned src, unsigned count)
|
|
void MoveRange(unsigned dest, unsigned src, unsigned count)
|
|
|
{
|
|
{
|