summaryrefslogtreecommitdiff
path: root/src/dynamic-array.hpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-09-08 16:43:06 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-09-08 16:43:06 -0400
commit08cdf72330276a4b4883fea41c3ada1087800a41 (patch)
treec60f14feee3dd40e5d762a17cb8c76ba446d1ab8 /src/dynamic-array.hpp
parent9d6c681037eb4fb3c6d9eca6b1ff1d01d429614e (diff)
Use move operator for DynArray<T>::Push
The EventBucket struct has a DynArray as a member. Calling ::Push({}) instantiates a new item and thus a new DynArray. When the new `{}` object goes out of scope, the DynArray destructor was being called, invalidating the data pointer. This commit ensures that if the object is cloned or moved, the pointer, which now lives in the outer array, remains valid.
Diffstat (limited to 'src/dynamic-array.hpp')
-rw-r--r--src/dynamic-array.hpp44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/dynamic-array.hpp b/src/dynamic-array.hpp
index 978e291..f06ddac 100644
--- a/src/dynamic-array.hpp
+++ b/src/dynamic-array.hpp
@@ -11,7 +11,7 @@
#define BAKE_DYN_ARRAY(T) template struct DynArray<T>;
struct DynArrayBase {
- char *ptr = nullptr;
+ mutable char *ptr = nullptr;
int64_t elementSize = 0;
int64_t elementCount = 0;
int64_t reservedCount = 0;
@@ -21,6 +21,10 @@ template <typename T>
struct DynArray: DynArrayBase {
DynArray();
explicit DynArray(int64_t reserveCount);
+ DynArray(const DynArray<T> &other);
+ DynArray(DynArray<T> &&other);
+ DynArray &operator=(const DynArray<T> &other);
+ DynArray &operator=(DynArray<T> &&other);
~DynArray();
T &operator[](std::size_t index);
T *GetPtr();
@@ -50,6 +54,40 @@ template <typename T> inline DynArray<T>::DynArray() {
this->elementSize = sizeof(T);
}
+template <typename T> inline DynArray<T>::DynArray(const DynArray<T> &rh) {
+ this->ptr = rh.ptr;
+ this->elementSize = rh.elementSize;
+ this->elementCount = rh.elementCount;
+ this->reservedCount = rh.reservedCount;
+ rh.ptr = nullptr;
+}
+
+template <typename T> inline DynArray<T>::DynArray(DynArray<T> &&rh) {
+ this->ptr = rh.ptr;
+ this->elementSize = rh.elementSize;
+ this->elementCount = rh.elementCount;
+ this->reservedCount = rh.reservedCount;
+ rh.ptr = nullptr;
+}
+
+template <typename T> inline DynArray<T> &DynArray<T>::operator=(const DynArray<T> &rh) {
+ this->ptr = rh.ptr;
+ this->elementSize = rh.elementSize;
+ this->elementCount = rh.elementCount;
+ this->reservedCount = rh.reservedCount;
+ rh.ptr = nullptr;
+ return *this;
+}
+
+template <typename T> inline DynArray<T> &DynArray<T>::operator=(DynArray<T> &&rh) {
+ this->ptr = rh.ptr;
+ this->elementSize = rh.elementSize;
+ this->elementCount = rh.elementCount;
+ this->reservedCount = rh.reservedCount;
+ rh.ptr = nullptr;
+ return *this;
+}
+
template <typename T> inline DynArray<T>::~DynArray() {
DynArrayDestroy(this);
}
@@ -81,7 +119,9 @@ template <typename T> inline void DynArray<T>::Push(const T &val) {
auto safeReserveCount = this->reservedCount == 0 ? 1 : this->reservedCount;
DynArrayReserve(this, int64_t(safeReserveCount * 1.5));
}
- std::memcpy(this->ptr + (sizeof(T) * this->elementCount), &val, sizeof(T));
+ auto itemPtr = this->ptr + (sizeof(T) * this->elementCount);
+ auto &targetItem = *reinterpret_cast<T *>(itemPtr);
+ targetItem = val;
this->elementCount += 1;
}