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 <string.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "core/error_macros.h"
|
#include "core/error_macros.h"
|
||||||
#include "core/os/memory.h"
|
#include "core/os/memory.h"
|
||||||
|
@ -159,28 +160,32 @@ public:
|
||||||
T *p = ptrw();
|
T *p = ptrw();
|
||||||
int len = size();
|
int len = size();
|
||||||
for (int i = p_index; i < len - 1; i++) {
|
for (int i = p_index; i < len - 1; i++) {
|
||||||
p[i] = p[i + 1];
|
p[i] = std::move(p[i + 1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
resize(len - 1);
|
resize(len - 1);
|
||||||
};
|
}
|
||||||
|
|
||||||
Error insert(int p_pos, const T &p_val) {
|
Error insert(int p_pos, const T &p_val) {
|
||||||
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
|
int new_size = size() + 1;
|
||||||
resize(size() + 1);
|
ERR_FAIL_INDEX_V(p_pos, new_size, ERR_INVALID_PARAMETER);
|
||||||
for (int i = (size() - 1); i > p_pos; i--) {
|
Error err = resize(new_size);
|
||||||
set(i, get(i - 1));
|
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;
|
return OK;
|
||||||
};
|
}
|
||||||
|
|
||||||
int find(const T &p_val, int p_from = 0) const;
|
int find(const T &p_val, int p_from = 0) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ CowData();
|
_FORCE_INLINE_ CowData();
|
||||||
_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>
|
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) {
|
T &operator[](int p_index) {
|
||||||
CRASH_BAD_INDEX(p_index, size());
|
CRASH_BAD_INDEX(p_index, size());
|
||||||
|
|
||||||
|
@ -685,6 +695,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List(List &&p_list) {
|
||||||
|
_data = p_list._data;
|
||||||
|
p_list._data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
List() {
|
List() {
|
||||||
_data = nullptr;
|
_data = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "core/vector.h"
|
#include "core/vector.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -67,9 +68,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!std::is_trivially_constructible<T>::value && !force_trivial) {
|
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 {
|
} else {
|
||||||
data[count++] = p_elem;
|
data[count++] = std::move(p_elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ public:
|
||||||
ERR_FAIL_UNSIGNED_INDEX(p_index, count);
|
ERR_FAIL_UNSIGNED_INDEX(p_index, count);
|
||||||
count--;
|
count--;
|
||||||
for (U i = p_index; i < count; i++) {
|
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) {
|
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||||
data[count].~T();
|
data[count].~T();
|
||||||
|
@ -90,7 +91,7 @@ public:
|
||||||
ERR_FAIL_INDEX(p_index, count);
|
ERR_FAIL_INDEX(p_index, count);
|
||||||
count--;
|
count--;
|
||||||
if (count > p_index) {
|
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) {
|
if (!std::is_trivially_destructible<T>::value && !force_trivial) {
|
||||||
data[count].~T();
|
data[count].~T();
|
||||||
|
@ -193,13 +194,13 @@ public:
|
||||||
void insert(U p_pos, T p_val) {
|
void insert(U p_pos, T p_val) {
|
||||||
ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1);
|
ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1);
|
||||||
if (p_pos == count) {
|
if (p_pos == count) {
|
||||||
push_back(p_val);
|
push_back(std::move(p_val));
|
||||||
} else {
|
} else {
|
||||||
resize(count + 1);
|
resize(count + 1);
|
||||||
for (U i = count - 1; i > p_pos; i--) {
|
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];
|
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) {
|
inline LocalVector &operator=(const LocalVector &p_from) {
|
||||||
resize(p_from.size());
|
resize(p_from.size());
|
||||||
for (U i = 0; i < p_from.count; i++) {
|
for (U i = 0; i < p_from.count; i++) {
|
||||||
|
@ -291,6 +303,22 @@ public:
|
||||||
}
|
}
|
||||||
return *this;
|
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) {
|
inline LocalVector &operator=(const Vector<T> &p_from) {
|
||||||
resize(p_from.size());
|
resize(p_from.size());
|
||||||
for (U i = 0; i < count; i++) {
|
for (U i = 0; i < count; i++) {
|
||||||
|
@ -298,6 +326,14 @@ public:
|
||||||
}
|
}
|
||||||
return *this;
|
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) {
|
inline LocalVector &operator=(const PoolVector<T> &p_from) {
|
||||||
resize(p_from.size());
|
resize(p_from.size());
|
||||||
typename PoolVector<T>::Read r = p_from.read();
|
typename PoolVector<T>::Read r = p_from.read();
|
||||||
|
|
|
@ -163,6 +163,23 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void operator=(const StringName &p_name);
|
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 char *p_name);
|
||||||
StringName(const StringName &p_name);
|
StringName(const StringName &p_name);
|
||||||
StringName(const String &p_name);
|
StringName(const String &p_name);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define TYPEDEFS_H
|
#define TYPEDEFS_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic definitions and simple functions to be used everywhere.
|
* Basic definitions and simple functions to be used everywhere.
|
||||||
|
@ -175,15 +176,7 @@ T *_nullptr() {
|
||||||
|
|
||||||
/** Generic swap template */
|
/** Generic swap template */
|
||||||
#ifndef SWAP
|
#ifndef SWAP
|
||||||
|
#define SWAP(m_x, m_y) std::swap((m_x), (m_y))
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //swap
|
#endif //swap
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
|
@ -159,7 +159,7 @@ private:
|
||||||
Basis *_basis;
|
Basis *_basis;
|
||||||
Transform *_transform;
|
Transform *_transform;
|
||||||
void *_ptr; //generic pointer
|
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;
|
} _data GCC_ALIGNED_8;
|
||||||
|
|
||||||
void reference(const Variant &p_variant);
|
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);
|
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=(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(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() { type = NIL; }
|
||||||
_FORCE_INLINE_ ~Variant() {
|
_FORCE_INLINE_ ~Variant() {
|
||||||
if (type != Variant::NIL) {
|
if (type != Variant::NIL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue