mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-13 17:25:54 +00:00
Change the check for when copyRange/destroyRange can be trivially done
* Even if a struct isn't trivial (e.g. it contains a constructor) it can still be trivially copyable (just POD with memcpy), or trivially destructable (with no destructor). Make sure we don't fall back to slower copies/destroys for this case as it's relatively common.
This commit is contained in:
@@ -170,18 +170,6 @@ struct ItemHelper
|
||||
new(first + i) T();
|
||||
}
|
||||
|
||||
static void copyRange(T *dest, const T *src, int32_t count)
|
||||
{
|
||||
for(int32_t i = 0; i < count; i++)
|
||||
new(dest + i) T(src[i]);
|
||||
}
|
||||
|
||||
static void destroyRange(T *first, int32_t count)
|
||||
{
|
||||
for(int32_t i = 0; i < count; i++)
|
||||
(first + i)->~T();
|
||||
}
|
||||
|
||||
static bool equalRange(T *a, T *b, int32_t count)
|
||||
{
|
||||
for(int32_t i = 0; i < count; i++)
|
||||
@@ -205,11 +193,6 @@ template <typename T>
|
||||
struct ItemHelper<T, true>
|
||||
{
|
||||
static void initRange(T *first, int32_t itemCount) { memset(first, 0, itemCount * sizeof(T)); }
|
||||
static void copyRange(T *dest, const T *src, int32_t count)
|
||||
{
|
||||
memcpy(dest, src, count * sizeof(T));
|
||||
}
|
||||
static void destroyRange(T *first, int32_t itemCount) {}
|
||||
static bool equalRange(T *a, T *b, int32_t count) { return !memcmp(a, b, count * sizeof(T)); }
|
||||
static bool lessthanRange(T *a, T *b, int32_t count)
|
||||
{
|
||||
@@ -217,6 +200,45 @@ struct ItemHelper<T, true>
|
||||
}
|
||||
};
|
||||
|
||||
// ItemCopyHelper checks if memcpy can be used over placement new
|
||||
|
||||
template <typename T, bool isStd = std::is_trivially_copyable<T>::value>
|
||||
struct ItemCopyHelper
|
||||
{
|
||||
static void copyRange(T *dest, const T *src, int32_t count)
|
||||
{
|
||||
for(int32_t i = 0; i < count; i++)
|
||||
new(dest + i) T(src[i]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ItemCopyHelper<T, true>
|
||||
{
|
||||
static void copyRange(T *dest, const T *src, int32_t count)
|
||||
{
|
||||
memcpy(dest, src, count * sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
// ItemDestroyHelper checks if the destructor is trivial/do-nothing and can be skipped
|
||||
|
||||
template <typename T, bool isStd = std::is_trivially_destructible<T>::value>
|
||||
struct ItemDestroyHelper
|
||||
{
|
||||
static void destroyRange(T *first, int32_t count)
|
||||
{
|
||||
for(int32_t i = 0; i < count; i++)
|
||||
(first + i)->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ItemDestroyHelper<T, true>
|
||||
{
|
||||
static void destroyRange(T *first, int32_t itemCount) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rdcarray
|
||||
{
|
||||
@@ -326,10 +348,10 @@ public:
|
||||
if(elems)
|
||||
{
|
||||
// copy the elements to new storage
|
||||
ItemHelper<T>::copyRange(newElems, elems, usedCount);
|
||||
ItemCopyHelper<T>::copyRange(newElems, elems, usedCount);
|
||||
|
||||
// delete the old elements
|
||||
ItemHelper<T>::destroyRange(elems, usedCount);
|
||||
ItemDestroyHelper<T>::destroyRange(elems, usedCount);
|
||||
}
|
||||
|
||||
// deallocate tee old storage
|
||||
@@ -366,7 +388,7 @@ public:
|
||||
// resizing down, we just need to update the count and destruct removed elements
|
||||
setUsedCount((int32_t)s);
|
||||
|
||||
ItemHelper<T>::destroyRange(elems + usedCount, oldCount - usedCount);
|
||||
ItemDestroyHelper<T>::destroyRange(elems + usedCount, oldCount - usedCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +648,7 @@ public:
|
||||
setUsedCount((int32_t)in.size());
|
||||
|
||||
// copy construct the new elems
|
||||
ItemHelper<T>::copyRange(elems, in.data(), usedCount);
|
||||
ItemCopyHelper<T>::copyRange(elems, in.data(), usedCount);
|
||||
|
||||
null_terminator<T>::fixup(elems, usedCount);
|
||||
|
||||
@@ -671,7 +693,7 @@ public:
|
||||
setUsedCount((int32_t)in.size());
|
||||
|
||||
// copy construct the new elems
|
||||
ItemHelper<T>::copyRange(elems, in.data(), usedCount);
|
||||
ItemCopyHelper<T>::copyRange(elems, in.data(), usedCount);
|
||||
|
||||
null_terminator<T>::fixup(elems, usedCount);
|
||||
|
||||
@@ -690,7 +712,7 @@ public:
|
||||
setUsedCount((int32_t)count);
|
||||
|
||||
// copy construct the new elems
|
||||
ItemHelper<T>::copyRange(elems, in, usedCount);
|
||||
ItemCopyHelper<T>::copyRange(elems, in, usedCount);
|
||||
}
|
||||
|
||||
#if defined(RENDERDOC_QT_COMPAT)
|
||||
|
||||
Reference in New Issue
Block a user