diff --git a/src/utility/tarray.h b/src/utility/tarray.h index 1b64f3c3e..ac84da6c7 100644 --- a/src/utility/tarray.h +++ b/src/utility/tarray.h @@ -31,6 +31,20 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** +** NOTE: TArray takes advantage of the assumption that the contained type is +** able to be trivially moved. The definition of trivially movable by the C++ +** standard is more strict than the actual set of types that can be moved with +** memmove. For example, FString uses non-trivial constructors/destructor in +** order to maintain the reference count, but can be "safely" by passed if the +** opaque destructor call is avoided. Similarly types like TArray itself which +** only null the owning pointers when moving which can be skipped if the +** destructor is not called. +** +** It is possible that with LTO TArray could be made safe for non-trivial types, +** but we don't wish to rely on LTO to reach expected performance. The set of +** types which can not be contained by TArray as a result of this choice is +** actually extremely small. +** */ @@ -352,7 +366,8 @@ public: Array[index].~T(); if (index < --Count) { - memmove (&Array[index], &Array[index+1], sizeof(T)*(Count - index)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index], (const void*)&Array[index+1], sizeof(T)*(Count - index)); } } } @@ -372,7 +387,8 @@ public: Count -= deletecount; if (index < Count) { - memmove (&Array[index], &Array[index+deletecount], sizeof(T)*(Count - index)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index], (const void*)&Array[index+deletecount], sizeof(T)*(Count - index)); } } } @@ -394,7 +410,8 @@ public: Resize (Count + 1); // Now move items from the index and onward out of the way - memmove (&Array[index+1], &Array[index], sizeof(T)*(Count - index - 1)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index+1], (const void*)&Array[index], sizeof(T)*(Count - index - 1)); // And put the new element in ::new ((void *)&Array[index]) T(item);