mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Add move semantics to core containers.
Adds to SWAP, Variant, StringName, List, CowData and LocalVector. Co-Authored-By: Lukas Tenbrink <lukas.tenbrink@gmail.com>
This commit is contained in:
parent
cd92ad0f69
commit
d549b98c5c
6 changed files with 106 additions and 26 deletions
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "core/error_macros.h"
|
||||
#include "core/os/memory.h"
|
||||
|
@ -159,28 +160,32 @@ public:
|
|||
T *p = ptrw();
|
||||
int len = size();
|
||||
for (int i = p_index; i < len - 1; i++) {
|
||||
p[i] = p[i + 1];
|
||||
p[i] = std::move(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] = std::move(p[i - 1]);
|
||||
}
|
||||
set(p_pos, p_val);
|
||||
p[p_pos] = p_val;
|
||||
|
||||
return OK;
|
||||
};
|
||||
}
|
||||
|
||||
int find(const T &p_val, int p_from = 0) const;
|
||||
|
||||
_FORCE_INLINE_ CowData();
|
||||
_FORCE_INLINE_ ~CowData();
|
||||
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
|
||||
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
|
15
core/list.h
15
core/list.h
|
@ -444,6 +444,16 @@ 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());
|
||||
|
||||
|
@ -685,6 +695,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
List(List &&p_list) {
|
||||
_data = p_list._data;
|
||||
p_list._data = nullptr;
|
||||
}
|
||||
|
||||
List() {
|
||||
_data = nullptr;
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "core/vector.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
template <class T, class U = uint32_t, bool force_trivial = false>
|
||||
class LocalVector {
|
||||
|
@ -67,9 +68,9 @@ public:
|
|||
}
|
||||
|
||||
if (!std::is_trivially_constructible<T>::value && !force_trivial) {
|
||||
memnew_placement(&data[count++], T(p_elem));
|
||||
memnew_placement(&data[count++], T(std::move(p_elem)));
|
||||
} else {
|
||||
data[count++] = p_elem;
|
||||
data[count++] = std::move(p_elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +78,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] = std::move(data[i + 1]);
|
||||
}
|
||||
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||
data[count].~T();
|
||||
|
@ -90,7 +91,7 @@ public:
|
|||
ERR_FAIL_INDEX(p_index, count);
|
||||
count--;
|
||||
if (count > p_index) {
|
||||
data[p_index] = data[count];
|
||||
data[p_index] = std::move(data[count]);
|
||||
}
|
||||
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||
data[count].~T();
|
||||
|
@ -193,13 +194,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(std::move(p_val));
|
||||
} else {
|
||||
resize(count + 1);
|
||||
for (U i = count - 1; i > p_pos; i--) {
|
||||
data[i] = data[i - 1];
|
||||
data[i] = std::move(data[i - 1]);
|
||||
}
|
||||
data[p_pos] = p_val;
|
||||
data[p_pos] = std::move(p_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,6 +285,17 @@ public:
|
|||
data[i] = r[i];
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
|
@ -291,6 +303,22 @@ 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++) {
|
||||
|
@ -298,6 +326,14 @@ public:
|
|||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void operator=(Vector<T> &&p_from) {
|
||||
resize(p_from.size());
|
||||
for (U i = 0; i < count; i++) {
|
||||
data[i] = std::move(p_from[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline LocalVector &operator=(const PoolVector<T> &p_from) {
|
||||
resize(p_from.size());
|
||||
typename PoolVector<T>::Read r = p_from.read();
|
||||
|
|
|
@ -163,6 +163,23 @@ 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);
|
||||
StringName(const StringName &p_name);
|
||||
StringName(const String &p_name);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define TYPEDEFS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* Basic definitions and simple functions to be used everywhere.
|
||||
|
@ -175,15 +176,7 @@ T *_nullptr() {
|
|||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
#define SWAP(m_x, m_y) std::swap((m_x), (m_y))
|
||||
#endif //swap
|
||||
|
||||
/* clang-format off */
|
||||
|
|
|
@ -159,7 +159,7 @@ private:
|
|||
Basis *_basis;
|
||||
Transform *_transform;
|
||||
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);
|
||||
|
@ -432,7 +432,21 @@ 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; }
|
||||
_FORCE_INLINE_ ~Variant() {
|
||||
if (type != Variant::NIL) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue