瀏覽代碼

Add move semantics to core containers.

Adds to SWAP, Variant, StringName, List, CowData and LocalVector.

Co-Authored-By: Lukas Tenbrink <[email protected]>
lawnjelly 8 月之前
父節點
當前提交
d549b98c5c
共有 6 個文件被更改,包括 106 次插入26 次删除
  1. 14 9
      core/cowdata.h
  2. 15 0
      core/list.h
  3. 43 7
      core/local_vector.h
  4. 17 0
      core/string_name.h
  5. 2 9
      core/typedefs.h
  6. 15 1
      core/variant.h

+ 14 - 9
core/cowdata.h

@@ -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 - 0
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;
 	};

+ 43 - 7
core/local_vector.h

@@ -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();

+ 17 - 0
core/string_name.h

@@ -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);

+ 2 - 9
core/typedefs.h

@@ -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 */

+ 15 - 1
core/variant.h

@@ -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) {