mirror of https://github.com/godotengine/godot
Merge pull request #95920 from Repiteo/core/initializer-list-templates
Core: Expand `std::initializer_list` support in container templates
This commit is contained in:
commit
eaa447135c
|
|
@ -703,6 +703,13 @@ public:
|
|||
capacity(INITIAL_CAPACITY - 1) {
|
||||
}
|
||||
|
||||
AHashMap(std::initializer_list<KeyValue<TKey, TValue>> p_init) {
|
||||
reserve(p_init.size());
|
||||
for (const KeyValue<TKey, TValue> &E : p_init) {
|
||||
insert(E.key, E.value);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (elements != nullptr) {
|
||||
if constexpr (!(std::is_trivially_destructible_v<TKey> && std::is_trivially_destructible_v<TValue>)) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "core/templates/safe_refcount.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -250,6 +251,7 @@ public:
|
|||
|
||||
_FORCE_INLINE_ CowData() {}
|
||||
_FORCE_INLINE_ ~CowData();
|
||||
_FORCE_INLINE_ CowData(std::initializer_list<T> p_init);
|
||||
_FORCE_INLINE_ CowData(const CowData<T> &p_from) { _ref(p_from); }
|
||||
_FORCE_INLINE_ CowData(CowData<T> &&p_from) {
|
||||
_ptr = p_from._ptr;
|
||||
|
|
@ -492,6 +494,19 @@ CowData<T>::~CowData() {
|
|||
_unref();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
CowData<T>::CowData(std::initializer_list<T> p_init) {
|
||||
Error err = resize(p_init.size());
|
||||
if (err != OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
Size i = 0;
|
||||
for (const T &element : p_init) {
|
||||
set(i++, element);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "core/templates/paged_allocator.h"
|
||||
#include "core/templates/pair.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
/**
|
||||
* A HashMap implementation that uses open addressing with Robin Hood hashing.
|
||||
* Robin Hood hashing swaps out entries that have a smaller probing distance
|
||||
|
|
@ -640,6 +642,13 @@ public:
|
|||
capacity_index = MIN_CAPACITY_INDEX;
|
||||
}
|
||||
|
||||
HashMap(std::initializer_list<KeyValue<TKey, TValue>> p_init) {
|
||||
reserve(p_init.size());
|
||||
for (const KeyValue<TKey, TValue> &E : p_init) {
|
||||
insert(E.key, E.value);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t debug_get_hash(uint32_t p_index) {
|
||||
if (num_elements == 0) {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -445,6 +445,13 @@ public:
|
|||
capacity_index = MIN_CAPACITY_INDEX;
|
||||
}
|
||||
|
||||
HashSet(std::initializer_list<TKey> p_init) {
|
||||
reserve(p_init.size());
|
||||
for (const TKey &E : p_init) {
|
||||
insert(E);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "core/os/memory.h"
|
||||
#include "core/templates/sort_array.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
/**
|
||||
* Generic Templatized Linked List Implementation.
|
||||
* The implementation differs from the STL one because
|
||||
|
|
@ -763,6 +765,12 @@ public:
|
|||
|
||||
List() {}
|
||||
|
||||
List(std::initializer_list<T> p_init) {
|
||||
for (const T &E : p_init) {
|
||||
push_back(E);
|
||||
}
|
||||
}
|
||||
|
||||
~List() {
|
||||
clear();
|
||||
if (_data) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/math/math_funcs.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/templates/hashfuncs.h"
|
||||
#include "core/templates/pair.h"
|
||||
|
||||
/**
|
||||
* A HashMap implementation that uses open addressing with Robin Hood hashing.
|
||||
|
|
@ -353,6 +354,13 @@ public:
|
|||
return it;
|
||||
}
|
||||
|
||||
OAHashMap(std::initializer_list<KeyValue<TKey, TValue>> p_init) {
|
||||
reserve(p_init.size());
|
||||
for (const KeyValue<TKey, TValue> &E : p_init) {
|
||||
set(E.key, E.value);
|
||||
}
|
||||
}
|
||||
|
||||
OAHashMap(const OAHashMap &p_other) {
|
||||
(*this) = p_other;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "core/os/memory.h"
|
||||
#include "core/templates/pair.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
// based on the very nice implementation of rb-trees by:
|
||||
// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
|
||||
|
||||
|
|
@ -763,6 +765,12 @@ public:
|
|||
_copy_from(p_map);
|
||||
}
|
||||
|
||||
RBMap(std::initializer_list<KeyValue<K, V>> p_init) {
|
||||
for (const KeyValue<K, V> &E : p_init) {
|
||||
insert(E.key, E.value);
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RBMap() {}
|
||||
|
||||
~RBMap() {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "core/os/memory.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
// based on the very nice implementation of rb-trees by:
|
||||
// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
|
||||
|
||||
|
|
@ -701,6 +703,12 @@ public:
|
|||
_copy_from(p_set);
|
||||
}
|
||||
|
||||
RBSet(std::initializer_list<T> p_init) {
|
||||
for (const T &E : p_init) {
|
||||
insert(E);
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RBSet() {}
|
||||
|
||||
~RBSet() {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
// Design goals for these classes:
|
||||
|
|
@ -226,6 +227,13 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ SafeList() {}
|
||||
_FORCE_INLINE_ SafeList(std::initializer_list<T> p_init) {
|
||||
for (const T &E : p_init) {
|
||||
insert(E);
|
||||
}
|
||||
}
|
||||
|
||||
~SafeList() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!maybe_cleanup()) {
|
||||
|
|
|
|||
|
|
@ -283,15 +283,8 @@ public:
|
|||
}
|
||||
|
||||
_FORCE_INLINE_ Vector() {}
|
||||
_FORCE_INLINE_ Vector(std::initializer_list<T> p_init) {
|
||||
Error err = _cowdata.resize(p_init.size());
|
||||
ERR_FAIL_COND(err);
|
||||
|
||||
Size i = 0;
|
||||
for (const T &element : p_init) {
|
||||
_cowdata.set(i++, element);
|
||||
}
|
||||
}
|
||||
_FORCE_INLINE_ Vector(std::initializer_list<T> p_init) :
|
||||
_cowdata(p_init) {}
|
||||
_FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); }
|
||||
_FORCE_INLINE_ Vector(Vector &&p_from) :
|
||||
_cowdata(std::move(p_from._cowdata)) {}
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ public:
|
|||
}
|
||||
|
||||
_FORCE_INLINE_ VMap() {}
|
||||
_FORCE_INLINE_ VMap(std::initializer_list<T> p_init) :
|
||||
_cowdata(p_init) {}
|
||||
_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
|
||||
|
||||
inline void operator=(const VMap &p_from) {
|
||||
|
|
|
|||
|
|
@ -137,6 +137,10 @@ public:
|
|||
inline const T &operator[](int p_index) const {
|
||||
return _data[p_index];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ VSet() {}
|
||||
_FORCE_INLINE_ VSet(std::initializer_list<T> p_init) :
|
||||
_data(p_init) {}
|
||||
};
|
||||
|
||||
#endif // VSET_H
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@
|
|||
|
||||
namespace TestAHashMap {
|
||||
|
||||
TEST_CASE("[AHashMap] List initialization") {
|
||||
AHashMap<int, String> map{ { 0, "A" }, { 1, "B" }, { 2, "C" }, { 3, "D" }, { 4, "E" } };
|
||||
|
||||
CHECK(map.size() == 5);
|
||||
CHECK(map[0] == "A");
|
||||
CHECK(map[1] == "B");
|
||||
CHECK(map[2] == "C");
|
||||
CHECK(map[3] == "D");
|
||||
CHECK(map[4] == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[AHashMap] List initialization with existing elements") {
|
||||
AHashMap<int, String> map{ { 0, "A" }, { 0, "B" }, { 0, "C" }, { 0, "D" }, { 0, "E" } };
|
||||
|
||||
CHECK(map.size() == 1);
|
||||
CHECK(map[0] == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[AHashMap] Insert element") {
|
||||
AHashMap<int, int> map;
|
||||
AHashMap<int, int>::Iterator e = map.insert(42, 84);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@
|
|||
|
||||
namespace TestHashMap {
|
||||
|
||||
TEST_CASE("[HashMap] List initialization") {
|
||||
HashMap<int, String> map{ { 0, "A" }, { 1, "B" }, { 2, "C" }, { 3, "D" }, { 4, "E" } };
|
||||
|
||||
CHECK(map.size() == 5);
|
||||
CHECK(map[0] == "A");
|
||||
CHECK(map[1] == "B");
|
||||
CHECK(map[2] == "C");
|
||||
CHECK(map[3] == "D");
|
||||
CHECK(map[4] == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[HashMap] List initialization with existing elements") {
|
||||
HashMap<int, String> map{ { 0, "A" }, { 0, "B" }, { 0, "C" }, { 0, "D" }, { 0, "E" } };
|
||||
|
||||
CHECK(map.size() == 1);
|
||||
CHECK(map[0] == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[HashMap] Insert element") {
|
||||
HashMap<int, int> map;
|
||||
HashMap<int, int>::Iterator e = map.insert(42, 84);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@
|
|||
|
||||
namespace TestHashSet {
|
||||
|
||||
TEST_CASE("[HashSet] List initialization") {
|
||||
HashSet<int> set{ 0, 1, 2, 3, 4 };
|
||||
|
||||
CHECK(set.size() == 5);
|
||||
CHECK(set.has(0));
|
||||
CHECK(set.has(1));
|
||||
CHECK(set.has(2));
|
||||
CHECK(set.has(3));
|
||||
CHECK(set.has(4));
|
||||
}
|
||||
|
||||
TEST_CASE("[HashSet] List initialization with existing elements") {
|
||||
HashSet<int> set{ 0, 0, 0, 0, 0 };
|
||||
|
||||
CHECK(set.size() == 1);
|
||||
CHECK(set.has(0));
|
||||
}
|
||||
|
||||
TEST_CASE("[HashSet] Insert element") {
|
||||
HashSet<int> set;
|
||||
HashSet<int>::Iterator e = set.insert(42);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,17 @@ static void populate_integers(List<int> &p_list, List<int>::Element *r_elements[
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[List] List initialization") {
|
||||
List<int> list{ 0, 1, 2, 3, 4 };
|
||||
|
||||
CHECK(list.size() == 5);
|
||||
CHECK(list.get(0) == 0);
|
||||
CHECK(list.get(1) == 1);
|
||||
CHECK(list.get(2) == 2);
|
||||
CHECK(list.get(3) == 3);
|
||||
CHECK(list.get(4) == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("[List] Push/pop back") {
|
||||
List<String> list;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,32 @@
|
|||
|
||||
namespace TestOAHashMap {
|
||||
|
||||
TEST_CASE("[OAHashMap] List initialization") {
|
||||
OAHashMap<int, String> map{ { 0, "A" }, { 1, "B" }, { 2, "C" }, { 3, "D" }, { 4, "E" } };
|
||||
|
||||
CHECK(map.get_num_elements() == 5);
|
||||
String value;
|
||||
CHECK(map.lookup(0, value));
|
||||
CHECK(value == "A");
|
||||
CHECK(map.lookup(1, value));
|
||||
CHECK(value == "B");
|
||||
CHECK(map.lookup(2, value));
|
||||
CHECK(value == "C");
|
||||
CHECK(map.lookup(3, value));
|
||||
CHECK(value == "D");
|
||||
CHECK(map.lookup(4, value));
|
||||
CHECK(value == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[OAHashMap] List initialization with existing elements") {
|
||||
OAHashMap<int, String> map{ { 0, "A" }, { 0, "B" }, { 0, "C" }, { 0, "D" }, { 0, "E" } };
|
||||
|
||||
CHECK(map.get_num_elements() == 1);
|
||||
String value;
|
||||
CHECK(map.lookup(0, value));
|
||||
CHECK(value == "E");
|
||||
}
|
||||
|
||||
TEST_CASE("[OAHashMap] Insert element") {
|
||||
OAHashMap<int, int> map;
|
||||
map.insert(42, 84);
|
||||
|
|
|
|||
Loading…
Reference in New Issue