[Core] Use std type traits to check operations triviality.

This commit is contained in:
Fabio Alessandrelli 2022-08-04 13:53:03 +02:00
parent 55845bac26
commit 6f02183f8c
4 changed files with 23 additions and 18 deletions

View file

@ -36,6 +36,7 @@
#include <stddef.h> #include <stddef.h>
#include <new> #include <new>
#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
@ -104,7 +105,7 @@ 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();
} }
@ -116,7 +117,7 @@ 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();
} }
@ -146,7 +147,7 @@ T *memnew_arr_template(size_t p_elements) {
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 */
@ -173,7 +174,7 @@ template <typename T>
void memdelete_arr(T *p_class) { 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++) {

View file

@ -36,6 +36,7 @@
#include "core/templates/safe_refcount.h" #include "core/templates/safe_refcount.h"
#include <string.h> #include <string.h>
#include <type_traits>
template <class T> template <class T>
class Vector; class Vector;
@ -204,7 +205,7 @@ void CowData<T>::_unref(void *p_data) {
} }
// 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);
@ -239,7 +240,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) {
for (int i = *_get_size(); i < p_size; i++) { for (int i = *_get_size(); i < p_size; i++) {
memnew_placement(&_ptr[i], T); memnew_placement(&_ptr[i], T);
} }
@ -311,7 +312,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 (!__has_trivial_destructor(T)) { if (!std::is_trivially_destructible<T>::value) {
// 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 = &_ptr[i]; T *t = &_ptr[i];

View file

@ -37,6 +37,7 @@
#include "core/templates/vector.h" #include "core/templates/vector.h"
#include <initializer_list> #include <initializer_list>
#include <type_traits>
// If tight, it grows strictly as much as needed. // If tight, it grows strictly as much as needed.
// Otherwise, it grows exponentially (the default and what you want in most cases). // Otherwise, it grows exponentially (the default and what you want in most cases).
@ -67,7 +68,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;
@ -80,7 +81,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();
} }
} }
@ -93,7 +94,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();
} }
} }
@ -134,7 +135,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();
} }
@ -151,7 +152,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);
} }

View file

@ -35,6 +35,8 @@
#include "core/os/spin_lock.h" #include "core/os/spin_lock.h"
#include "core/typedefs.h" #include "core/typedefs.h"
#include <type_traits>
// PagedArray is used mainly for filling a very large array from multiple threads efficiently and without causing major fragmentation // PagedArray is used mainly for filling a very large array from multiple threads efficiently and without causing major fragmentation
// PageArrayPool manages central page allocation in a thread safe matter // PageArrayPool manages central page allocation in a thread safe matter
@ -197,7 +199,7 @@ public:
uint32_t page = count >> page_size_shift; uint32_t page = count >> page_size_shift;
uint32_t offset = count & page_size_mask; uint32_t offset = count & page_size_mask;
if (!__has_trivial_constructor(T)) { if (!std::is_trivially_constructible<T>::value) {
memnew_placement(&page_data[page][offset], T(p_value)); memnew_placement(&page_data[page][offset], T(p_value));
} else { } else {
page_data[page][offset] = p_value; page_data[page][offset] = p_value;
@ -209,7 +211,7 @@ public:
_FORCE_INLINE_ void pop_back() { _FORCE_INLINE_ void pop_back() {
ERR_FAIL_COND(count == 0); ERR_FAIL_COND(count == 0);
if (!__has_trivial_destructor(T)) { if (!std::is_trivially_destructible<T>::value) {
uint32_t page = (count - 1) >> page_size_shift; uint32_t page = (count - 1) >> page_size_shift;
uint32_t offset = (count - 1) & page_size_mask; uint32_t offset = (count - 1) & page_size_mask;
page_data[page][offset].~T(); page_data[page][offset].~T();
@ -226,7 +228,7 @@ public:
void clear() { void clear() {
//destruct if needed //destruct if needed
if (!__has_trivial_destructor(T)) { if (!std::is_trivially_destructible<T>::value) {
for (uint64_t i = 0; i < count; i++) { for (uint64_t i = 0; i < count; i++) {
uint32_t page = i >> page_size_shift; uint32_t page = i >> page_size_shift;
uint32_t offset = i & page_size_mask; uint32_t offset = i & page_size_mask;
@ -309,13 +311,13 @@ public:
uint32_t to_copy = MIN(page_size - new_remainder, remainder); uint32_t to_copy = MIN(page_size - new_remainder, remainder);
for (uint32_t i = 0; i < to_copy; i++) { for (uint32_t i = 0; i < to_copy; i++) {
if (!__has_trivial_constructor(T)) { if (!std::is_trivially_constructible<T>::value) {
memnew_placement(&dst_page[i + new_remainder], T(remainder_page[i + remainder - to_copy])); memnew_placement(&dst_page[i + new_remainder], T(remainder_page[i + remainder - to_copy]));
} else { } else {
dst_page[i + new_remainder] = remainder_page[i + remainder - to_copy]; dst_page[i + new_remainder] = remainder_page[i + remainder - to_copy];
} }
if (!__has_trivial_destructor(T)) { if (!std::is_trivially_destructible<T>::value) {
remainder_page[i + remainder - to_copy].~T(); remainder_page[i + remainder - to_copy].~T();
} }
} }