Loading...
common/Array.h dyld-960 dyld-1066.8
--- dyld/dyld-960/common/Array.h
+++ dyld/dyld-1066.8/common/Array.h
@@ -26,6 +26,7 @@
 
 #include <algorithm>
 #include <stdint.h>
+#include <stdio.h>
 #include <assert.h>
 #include <stddef.h>
 #include <mach/mach.h>
@@ -109,14 +110,17 @@
                     OverflowSafeArray(T* stackStorage, uintptr_t stackAllocCount) : Array<T>(stackStorage, stackAllocCount) {}
                     ~OverflowSafeArray();
 
-                    OverflowSafeArray(OverflowSafeArray&) = default;
+                    OverflowSafeArray(const OverflowSafeArray&) = delete;
+                    OverflowSafeArray& operator=(const OverflowSafeArray& other) = delete;
+                    OverflowSafeArray(OverflowSafeArray&&);
                     OverflowSafeArray& operator=(OverflowSafeArray&& other);
 
     void            push_back(const T& t)        { verifySpace(1); this->_elements[this->_usedCount++] = t; }
+    void            push_back(T&& t)             { verifySpace(1); this->_elements[this->_usedCount++] = std::move(t); }
     template <class... Args>
     void            emplace_back(Args&&... args) { verifySpace(1); new (&this->_elements[this->_usedCount++])T(args...); }
     void            default_constuct_back()      { verifySpace(1); new (&this->_elements[this->_usedCount++])T(); }
-    void            clear() { this->_usedCount = 0; }
+    void            clear();
     void            reserve(uintptr_t n) { if (this->_allocCount < n) growTo(n); }
     void            resize(uintptr_t n) {
         if (n == this->_usedCount)
@@ -158,13 +162,23 @@
 #if BUILDING_LIBDYLD
         //FIXME We should figure out a way to do this in dyld
         char crashString[256];
-        snprintf(crashString, 256, "OverflowSafeArray failed to allocate %llu bytes, vm_allocate returned: %d\n",
+        snprintf(crashString, sizeof(crashString), "OverflowSafeArray failed to allocate %llu bytes, vm_allocate returned: %d\n",
                 (uint64_t)_overflowBufferSize, kr);
         CRSetCrashLogMessage(crashString);
 #endif
         assert(0);
     }
-    ::memcpy((void*)_overflowBuffer, (void*)this->_elements, this->_usedCount*sizeof(T));
+    if constexpr (std::is_trivially_copyable<T>::value) {
+        ::memcpy((void*)_overflowBuffer, (void*)this->_elements, this->_usedCount*sizeof(T));
+    } else if constexpr (std::is_move_constructible<T>::value) {
+        //static_assert(std::is_trivially_copyable<T>::value, "Type isn't POD, but our destructor doesn't destroy elements");
+        T* newBuffer = (T*)_overflowBuffer;
+        for (uintptr_t i = 0; i != this->_usedCount; ++i)
+            new (&newBuffer[i]) T(std::move(this->_elements[i]));
+    } else {
+        static_assert(std::is_trivially_copyable<T>::value || std::is_move_constructible<T>::value,
+                      "Type must be trivially copyable/move_constructible");
+    }
     this->_elements = (T*)_overflowBuffer;
     this->_allocCount = _overflowBufferSize / sizeof(T);
 
@@ -173,8 +187,21 @@
 }
 
 template <typename T, uintptr_t MAXCOUNT>
+inline void OverflowSafeArray<T,MAXCOUNT>::clear()
+{
+    if constexpr (!std::is_trivially_destructible<T>::value) {
+        for (uintptr_t i = 0; i != this->_usedCount; ++i)
+            this->_elements[i].~T();
+    }
+    this->_usedCount = 0;
+}
+
+template <typename T, uintptr_t MAXCOUNT>
 inline OverflowSafeArray<T,MAXCOUNT>::~OverflowSafeArray()
 {
+    // Call clear in case there are element destructors to call
+    clear();
+
     if ( _overflowBuffer != 0 )
         ::vm_deallocate(mach_task_self(), _overflowBuffer, _overflowBufferSize);
 }
@@ -188,6 +215,14 @@
     // Free our buffer if we have one
     if ( _overflowBuffer != 0 )
         ::vm_deallocate(mach_task_self(), _overflowBuffer, _overflowBufferSize);
+
+    new (this) OverflowSafeArray<T,MAXCOUNT>(std::move(other));
+    return *this;
+}
+
+template <typename T, uintptr_t MAXCOUNT>
+inline OverflowSafeArray<T,MAXCOUNT>::OverflowSafeArray(OverflowSafeArray<T,MAXCOUNT>&& other)
+{
 
     // Now take the buffer from the other array
     this->_elements     = other._elements;
@@ -202,7 +237,6 @@
     other._usedCount            = 0;
     other._overflowBuffer       = 0;
     other._overflowBufferSize   = 0;
-    return *this;
 }