Backported move semantics from godot 3.x. with some changes.

Original commit:
d549b98c5c
This commit is contained in:
Relintai 2025-03-31 09:33:17 +02:00
parent b819224539
commit 70ec81c137
6 changed files with 134 additions and 16 deletions

View File

@ -37,6 +37,7 @@
#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include "core/os/safe_refcount.h"
#include "core/typedefs.h"
template <class T>
class Vector;
@ -161,19 +162,26 @@ public:
T *p = ptrw();
int len = size();
for (int i = p_index; i < len - 1; i++) {
p[i] = p[i + 1];
p[i] = MOVE_VAR(p[i + 1]);
};
resize(len - 1);
}
Error insert(int p_pos, const T &p_val) {
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
resize(size() + 1);
for (int i = (size() - 1); i > p_pos; i--) {
set(i, get(i - 1));
int new_size = size() + 1;
ERR_FAIL_INDEX_V(p_pos, new_size , ERR_INVALID_PARAMETER);
Error err = resize(new_size);
ERR_FAIL_COND_V(err, err);
T *p = ptrw();
for (int i = new_size - 1; i > p_pos; i--) {
p[i] = MOVE_VAR(p[i - 1]);
}
set(p_pos, p_val);
p[p_pos] = p_val;
return OK;
}

View File

@ -35,6 +35,7 @@
#include "core/containers/sort_array.h"
#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include "core/typedefs.h"
/**
* Generic Templatized Linked List Implementation.
@ -445,6 +446,18 @@ public:
}
}
void operator=(List &&p_list) {
if (unlikely(this == &p_list)) {
return;
}
clear();
_data = p_list._data;
p_list._data = nullptr;
}
T &operator[](int p_index) {
CRASH_BAD_INDEX(p_index, size());
@ -686,6 +699,11 @@ public:
}
}
List(List &&p_list) {
_data = p_list._data;
p_list._data = nullptr;
}
List() {
_data = nullptr;
};

View File

@ -37,6 +37,7 @@
#include "core/containers/vector.h"
#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include "core/typedefs.h"
template <class T, class U = uint32_t, bool force_trivial = false>
class LocalVector {
@ -66,9 +67,9 @@ public:
}
if (!HAS_TRIVIAL_CONSTRUCTOR(T) && !force_trivial) {
memnew_placement(&data[count++], T(p_elem));
memnew_placement(&data[count++], T(MOVE_VAR(p_elem)));
} else {
data[count++] = p_elem;
data[count++] = MOVE_VAR(p_elem);
}
}
@ -76,7 +77,7 @@ public:
ERR_FAIL_UNSIGNED_INDEX(p_index, count);
count--;
for (U i = p_index; i < count; i++) {
data[i] = data[i + 1];
data[i] = MOVE_VAR(data[i + 1]);
}
if (!HAS_TRIVIAL_DESTRUCTOR(T) && !force_trivial) {
data[count].~T();
@ -202,13 +203,13 @@ public:
void insert(U p_pos, T p_val) {
ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1);
if (p_pos == count) {
push_back(p_val);
push_back(MOVE_VAR(p_val));
} else {
resize(count + 1);
for (U i = count - 1; i > p_pos; i--) {
data[i] = data[i - 1];
data[i] = MOVE_VAR(data[i - 1]);
}
data[p_pos] = p_val;
data[p_pos] = MOVE_VAR(p_val);
}
}
@ -294,6 +295,16 @@ public:
}
}
LocalVector(LocalVector &&p_from) {
data = p_from.data;
count = p_from.count;
capacity = p_from.capacity;
p_from.data = nullptr;
p_from.count = 0;
p_from.capacity = 0;
}
inline LocalVector &operator=(const LocalVector &p_from) {
resize(p_from.size());
for (U i = 0; i < p_from.count; i++) {
@ -301,6 +312,23 @@ public:
}
return *this;
}
inline void operator=(LocalVector &&p_from) {
if (unlikely(this == &p_from)) {
return;
}
reset();
data = p_from.data;
count = p_from.count;
capacity = p_from.capacity;
p_from.data = nullptr;
p_from.count = 0;
p_from.capacity = 0;
}
inline LocalVector &operator=(const Vector<T> &p_from) {
resize(p_from.size());
for (U i = 0; i < count; i++) {
@ -308,6 +336,15 @@ public:
}
return *this;
}
inline void operator=(Vector<T> &&p_from) {
resize(p_from.size());
for (U i = 0; i < count; i++) {
data[i] = MOVE_VAR(p_from[i]);
}
}
inline LocalVector &operator=(const PoolVector<T> &p_from) {
resize(p_from.size());
typename PoolVector<T>::Read r = p_from.read();

View File

@ -193,6 +193,25 @@ public:
};
void operator=(const StringName &p_name);
StringName &operator=(StringName &&p_name) {
if (_data == p_name._data) {
return *this;
}
unref();
_data = p_name._data;
p_name._data = nullptr;
return *this;
}
StringName(StringName &&p_name) {
_data = p_name._data;
p_name._data = nullptr;
}
StringName(const char *p_name, bool p_static = false);
StringName(const StringName &p_name);
StringName(const String &p_name, bool p_static = false);

View File

@ -188,15 +188,35 @@ T *_nullptr() {
#define CLAMP(m_a, m_min, m_max) (((m_a) < (m_min)) ? (m_min) : (((m_a) > (m_max)) ? m_max : m_a))
#endif
template<typename T>
struct REMOVE_REFERENCE {
using type = T;
};
template<typename T>
struct REMOVE_REFERENCE<T&> {
using type = T;
};
template<typename T>
struct REMOVE_REFERENCE<T&&> {
using type = T;
};
template<typename T>
typename REMOVE_REFERENCE<T>::type&& MOVE_VAR(T&& t) {
return static_cast<typename REMOVE_REFERENCE<T>::type&&>(t);
}
/** Generic swap template */
#ifndef SWAP
#define SWAP(m_x, m_y) __swap_tmpl((m_x), (m_y))
template <class T>
inline void __swap_tmpl(T &x, T &y) {
T aux = x;
x = y;
y = aux;
T aux = MOVE_VAR(x);
x = MOVE_VAR(y);
y = MOVE_VAR(aux);
}
#endif //swap

View File

@ -180,7 +180,7 @@ private:
Transform *_transform;
Projection *_projection;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 };
} _data GCC_ALIGNED_8;
void reference(const Variant &p_variant);
@ -485,7 +485,23 @@ public:
static void construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct = nullptr, void *p_construct_ud = nullptr);
void operator=(const Variant &p_variant); // only this is enough for all the other types
void operator=(Variant &&p_variant) {
if (unlikely(this == &p_variant)) {
return;
}
clear();
type = p_variant.type;
_data = p_variant._data;
p_variant.type = NIL;
}
Variant(const Variant &p_variant);
Variant(Variant &&p_variant) {
type = p_variant.type;
_data = p_variant._data;
p_variant.type = NIL;
}
_FORCE_INLINE_ Variant() {
type = NIL;
}