|
@@ -31,6 +31,8 @@
|
|
|
#ifndef COWDATA_H_
|
|
|
#define COWDATA_H_
|
|
|
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
#include "core/os/memory.h"
|
|
|
#include "core/safe_refcount.h"
|
|
|
|
|
@@ -194,12 +196,14 @@ void CowData<T>::_unref(void *p_data) {
|
|
|
return; // still in use
|
|
|
// clean up
|
|
|
|
|
|
- uint32_t *count = _get_size();
|
|
|
- T *data = (T *)(count + 1);
|
|
|
+ if (!__has_trivial_destructor(T)) {
|
|
|
+ uint32_t *count = _get_size();
|
|
|
+ T *data = (T *)(count + 1);
|
|
|
|
|
|
- for (uint32_t i = 0; i < *count; ++i) {
|
|
|
- // call destructors
|
|
|
- data[i].~T();
|
|
|
+ for (uint32_t i = 0; i < *count; ++i) {
|
|
|
+ // call destructors
|
|
|
+ data[i].~T();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// free mem
|
|
@@ -226,9 +230,13 @@ void CowData<T>::_copy_on_write() {
|
|
|
T *_data = (T *)(mem_new);
|
|
|
|
|
|
// initialize new elements
|
|
|
- for (uint32_t i = 0; i < current_size; i++) {
|
|
|
+ if (__has_trivial_copy(T)) {
|
|
|
+ memcpy(mem_new, _ptr, current_size * sizeof(T));
|
|
|
|
|
|
- memnew_placement(&_data[i], T(_get_data()[i]));
|
|
|
+ } else {
|
|
|
+ for (uint32_t i = 0; i < current_size; i++) {
|
|
|
+ memnew_placement(&_data[i], T(_get_data()[i]));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
_unref(_ptr);
|
|
@@ -275,22 +283,25 @@ Error CowData<T>::resize(int p_size) {
|
|
|
}
|
|
|
|
|
|
// construct the newly created elements
|
|
|
- T *elems = _get_data();
|
|
|
|
|
|
- for (int i = *_get_size(); i < p_size; i++) {
|
|
|
+ if (!__has_trivial_constructor(T)) {
|
|
|
+ T *elems = _get_data();
|
|
|
|
|
|
- memnew_placement(&elems[i], T);
|
|
|
+ for (int i = *_get_size(); i < p_size; i++) {
|
|
|
+ memnew_placement(&elems[i], T);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
*_get_size() = p_size;
|
|
|
|
|
|
} else if (p_size < size()) {
|
|
|
|
|
|
- // deinitialize no longer needed elements
|
|
|
- for (uint32_t i = p_size; i < *_get_size(); i++) {
|
|
|
-
|
|
|
- T *t = &_get_data()[i];
|
|
|
- t->~T();
|
|
|
+ if (!__has_trivial_destructor(T)) {
|
|
|
+ // deinitialize no longer needed elements
|
|
|
+ for (uint32_t i = p_size; i < *_get_size(); i++) {
|
|
|
+ T *t = &_get_data()[i];
|
|
|
+ t->~T();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|