diff --git a/renderdoc/api/replay/basic_types.h b/renderdoc/api/replay/basic_types.h index da8ab385a..8d56c7854 100644 --- a/renderdoc/api/replay/basic_types.h +++ b/renderdoc/api/replay/basic_types.h @@ -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 struct ItemHelper { 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 } }; +// ItemCopyHelper checks if memcpy can be used over placement new + +template ::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 +struct ItemCopyHelper +{ + 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 ::value> +struct ItemDestroyHelper +{ + static void destroyRange(T *first, int32_t count) + { + for(int32_t i = 0; i < count; i++) + (first + i)->~T(); + } +}; + +template +struct ItemDestroyHelper +{ + static void destroyRange(T *first, int32_t itemCount) {} +}; + template struct rdcarray { @@ -326,10 +348,10 @@ public: if(elems) { // copy the elements to new storage - ItemHelper::copyRange(newElems, elems, usedCount); + ItemCopyHelper::copyRange(newElems, elems, usedCount); // delete the old elements - ItemHelper::destroyRange(elems, usedCount); + ItemDestroyHelper::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::destroyRange(elems + usedCount, oldCount - usedCount); + ItemDestroyHelper::destroyRange(elems + usedCount, oldCount - usedCount); } } @@ -626,7 +648,7 @@ public: setUsedCount((int32_t)in.size()); // copy construct the new elems - ItemHelper::copyRange(elems, in.data(), usedCount); + ItemCopyHelper::copyRange(elems, in.data(), usedCount); null_terminator::fixup(elems, usedCount); @@ -671,7 +693,7 @@ public: setUsedCount((int32_t)in.size()); // copy construct the new elems - ItemHelper::copyRange(elems, in.data(), usedCount); + ItemCopyHelper::copyRange(elems, in.data(), usedCount); null_terminator::fixup(elems, usedCount); @@ -690,7 +712,7 @@ public: setUsedCount((int32_t)count); // copy construct the new elems - ItemHelper::copyRange(elems, in, usedCount); + ItemCopyHelper::copyRange(elems, in, usedCount); } #if defined(RENDERDOC_QT_COMPAT)