mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-22 15:31:41 +00:00
Handle inserting from rdcarray into itself
* This self-insertion has the same kind of problem as overlapping ranges in memcpy, the act of inserting items can affect the input range by shifting things around. For inserting a single object we just copy it, for inserting a range we duplicate the whole array and then do the insert from the old range (and destruct it). * Clearly this is not the most efficient implementation, a better solution would be to append onto the existing array (potentially not even reallocating then) and doing a rotate/shift in place.
This commit is contained in:
@@ -381,6 +381,20 @@ public:
|
||||
|
||||
void insert(size_t offs, const T *el, size_t count)
|
||||
{
|
||||
if(el + count >= begin() && end() >= el)
|
||||
{
|
||||
// we're inserting from ourselves, so if we did this blindly we'd potentially change the
|
||||
// contents of the inserted range while doing the insertion.
|
||||
// To fix that, we store our original data in a temp and copy into ourselves again. Then we
|
||||
// insert from the range (which now points to the copy) and let it be destroyed.
|
||||
// This could be more efficient as an append and then a rotate, but this is simpler for now.
|
||||
rdcarray<T> copy;
|
||||
copy.swap(*this);
|
||||
this->reserve(copy.capacity());
|
||||
*this = copy;
|
||||
return insert(offs, el, count);
|
||||
}
|
||||
|
||||
const size_t oldSize = size();
|
||||
|
||||
// invalid size
|
||||
@@ -487,7 +501,18 @@ public:
|
||||
insert(offs, in.begin(), in.size());
|
||||
}
|
||||
inline void insert(size_t offs, const rdcarray<T> &in) { insert(offs, in.data(), in.size()); }
|
||||
inline void insert(size_t offs, const T &in) { insert(offs, &in, 1); }
|
||||
inline void insert(size_t offs, const T &in)
|
||||
{
|
||||
if(&in < begin() || &in > end())
|
||||
{
|
||||
insert(offs, &in, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
T copy(in);
|
||||
insert(offs, ©, 1);
|
||||
}
|
||||
}
|
||||
// helpful shortcut for 'append at end', basically a multi-element push_back
|
||||
inline void append(const T *el, size_t count) { insert(size(), el, count); }
|
||||
void erase(size_t offs, size_t count = 1)
|
||||
|
||||
Reference in New Issue
Block a user