[Core] Use std type traits to check operations triviality.
(cherry picked from commit 6f02183f8c)
This commit is contained in:
committed by
Rémi Verschelde
parent
eb36a16b36
commit
1ee9c15baf
@ -32,6 +32,7 @@
|
|||||||
#define COWDATA_H_
|
#define COWDATA_H_
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
#include "core/error_macros.h"
|
||||||
#include "core/os/memory.h"
|
#include "core/os/memory.h"
|
||||||
@ -203,7 +204,7 @@ void CowData<T>::_unref(void *p_data) {
|
|||||||
return; // still in use
|
return; // still in use
|
||||||
// clean up
|
// clean up
|
||||||
|
|
||||||
if (!__has_trivial_destructor(T)) {
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
uint32_t *count = _get_size();
|
uint32_t *count = _get_size();
|
||||||
T *data = (T *)(count + 1);
|
T *data = (T *)(count + 1);
|
||||||
|
|
||||||
@ -238,7 +239,7 @@ uint32_t CowData<T>::_copy_on_write() {
|
|||||||
T *_data = (T *)(mem_new);
|
T *_data = (T *)(mem_new);
|
||||||
|
|
||||||
// initialize new elements
|
// initialize new elements
|
||||||
if (__has_trivial_copy(T)) {
|
if (std::is_trivially_copyable<T>::value) {
|
||||||
memcpy(mem_new, _ptr, current_size * sizeof(T));
|
memcpy(mem_new, _ptr, current_size * sizeof(T));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -302,7 +303,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
|
|
||||||
// construct the newly created elements
|
// construct the newly created elements
|
||||||
|
|
||||||
if (!__has_trivial_constructor(T)) {
|
if (!std::is_trivially_constructible<T>::value) {
|
||||||
T *elems = _get_data();
|
T *elems = _get_data();
|
||||||
|
|
||||||
for (int i = *_get_size(); i < p_size; i++) {
|
for (int i = *_get_size(); i < p_size; i++) {
|
||||||
@ -313,8 +314,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
*_get_size() = p_size;
|
*_get_size() = p_size;
|
||||||
|
|
||||||
} else if (p_size < current_size) {
|
} else if (p_size < current_size) {
|
||||||
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
if (!__has_trivial_destructor(T)) {
|
|
||||||
// deinitialize no longer needed elements
|
// deinitialize no longer needed elements
|
||||||
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
||||||
T *t = &_get_data()[i];
|
T *t = &_get_data()[i];
|
||||||
|
|||||||
@ -37,6 +37,8 @@
|
|||||||
#include "core/sort_array.h"
|
#include "core/sort_array.h"
|
||||||
#include "core/vector.h"
|
#include "core/vector.h"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
template <class T, class U = uint32_t, bool force_trivial = false>
|
template <class T, class U = uint32_t, bool force_trivial = false>
|
||||||
class LocalVector {
|
class LocalVector {
|
||||||
private:
|
private:
|
||||||
@ -64,7 +66,7 @@ public:
|
|||||||
CRASH_COND_MSG(!data, "Out of memory");
|
CRASH_COND_MSG(!data, "Out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!__has_trivial_constructor(T) && !force_trivial) {
|
if (!std::is_trivially_constructible<T>::value && !force_trivial) {
|
||||||
memnew_placement(&data[count++], T(p_elem));
|
memnew_placement(&data[count++], T(p_elem));
|
||||||
} else {
|
} else {
|
||||||
data[count++] = p_elem;
|
data[count++] = p_elem;
|
||||||
@ -77,7 +79,7 @@ public:
|
|||||||
for (U i = p_index; i < count; i++) {
|
for (U i = p_index; i < count; i++) {
|
||||||
data[i] = data[i + 1];
|
data[i] = data[i + 1];
|
||||||
}
|
}
|
||||||
if (!__has_trivial_destructor(T) && !force_trivial) {
|
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||||
data[count].~T();
|
data[count].~T();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,7 +92,7 @@ public:
|
|||||||
if (count > p_index) {
|
if (count > p_index) {
|
||||||
data[p_index] = data[count];
|
data[p_index] = data[count];
|
||||||
}
|
}
|
||||||
if (!__has_trivial_destructor(T) && !force_trivial) {
|
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||||
data[count].~T();
|
data[count].~T();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,7 +132,7 @@ public:
|
|||||||
_FORCE_INLINE_ U size() const { return count; }
|
_FORCE_INLINE_ U size() const { return count; }
|
||||||
void resize(U p_size) {
|
void resize(U p_size) {
|
||||||
if (p_size < count) {
|
if (p_size < count) {
|
||||||
if (!__has_trivial_destructor(T) && !force_trivial) {
|
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||||
for (U i = p_size; i < count; i++) {
|
for (U i = p_size; i < count; i++) {
|
||||||
data[i].~T();
|
data[i].~T();
|
||||||
}
|
}
|
||||||
@ -147,7 +149,7 @@ public:
|
|||||||
data = (T *)memrealloc(data, capacity * sizeof(T));
|
data = (T *)memrealloc(data, capacity * sizeof(T));
|
||||||
CRASH_COND_MSG(!data, "Out of memory");
|
CRASH_COND_MSG(!data, "Out of memory");
|
||||||
}
|
}
|
||||||
if (!__has_trivial_constructor(T) && !force_trivial) {
|
if (!std::is_trivially_constructible<T>::value && !force_trivial) {
|
||||||
for (U i = count; i < p_size; i++) {
|
for (U i = count; i < p_size; i++) {
|
||||||
memnew_placement(&data[i], T);
|
memnew_placement(&data[i], T);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
#include "core/safe_refcount.h"
|
#include "core/safe_refcount.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#ifndef PAD_ALIGN
|
#ifndef PAD_ALIGN
|
||||||
#define PAD_ALIGN 16 //must always be greater than this at much
|
#define PAD_ALIGN 16 //must always be greater than this at much
|
||||||
@ -113,8 +114,9 @@ void memdelete(T *p_class) {
|
|||||||
|
|
||||||
if (!predelete_handler(p_class))
|
if (!predelete_handler(p_class))
|
||||||
return; // doesn't want to be deleted
|
return; // doesn't want to be deleted
|
||||||
if (!__has_trivial_destructor(T))
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
p_class->~T();
|
p_class->~T();
|
||||||
|
}
|
||||||
|
|
||||||
Memory::free_static(p_class, false);
|
Memory::free_static(p_class, false);
|
||||||
}
|
}
|
||||||
@ -124,8 +126,9 @@ void memdelete_allocator(T *p_class) {
|
|||||||
|
|
||||||
if (!predelete_handler(p_class))
|
if (!predelete_handler(p_class))
|
||||||
return; // doesn't want to be deleted
|
return; // doesn't want to be deleted
|
||||||
if (!__has_trivial_destructor(T))
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
p_class->~T();
|
p_class->~T();
|
||||||
|
}
|
||||||
|
|
||||||
A::free(p_class);
|
A::free(p_class);
|
||||||
}
|
}
|
||||||
@ -151,7 +154,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
|||||||
ERR_FAIL_COND_V(!mem, failptr);
|
ERR_FAIL_COND_V(!mem, failptr);
|
||||||
*(mem - 1) = p_elements;
|
*(mem - 1) = p_elements;
|
||||||
|
|
||||||
if (!__has_trivial_constructor(T)) {
|
if (!std::is_trivially_constructible<T>::value) {
|
||||||
T *elems = (T *)mem;
|
T *elems = (T *)mem;
|
||||||
|
|
||||||
/* call operator new */
|
/* call operator new */
|
||||||
@ -180,7 +183,7 @@ void memdelete_arr(T *p_class) {
|
|||||||
|
|
||||||
uint64_t *ptr = (uint64_t *)p_class;
|
uint64_t *ptr = (uint64_t *)p_class;
|
||||||
|
|
||||||
if (!__has_trivial_destructor(T)) {
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
uint64_t elem_count = *(ptr - 1);
|
uint64_t elem_count = *(ptr - 1);
|
||||||
|
|
||||||
for (uint64_t i = 0; i < elem_count; i++) {
|
for (uint64_t i = 0; i < elem_count; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user