diff options
Diffstat (limited to 'core/templates')
33 files changed, 336 insertions, 206 deletions
diff --git a/core/templates/bin_sorted_array.h b/core/templates/bin_sorted_array.h index 8db3e7aeb8..59ac4cdaa1 100644 --- a/core/templates/bin_sorted_array.h +++ b/core/templates/bin_sorted_array.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/command_queue_mt.cpp b/core/templates/command_queue_mt.cpp index 04a8095f0b..a40ff88a19 100644 --- a/core/templates/command_queue_mt.cpp +++ b/core/templates/command_queue_mt.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h index 519a896ffc..7d3e31b5bc 100644 --- a/core/templates/command_queue_mt.h +++ b/core/templates/command_queue_mt.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -215,7 +215,7 @@ T *instance; \ M method; \ SEMIC_SEP_LIST(PARAM_DECL, N); \ - virtual void call() { \ + virtual void call() override { \ (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ } \ }; @@ -227,7 +227,7 @@ T *instance; \ M method; \ SEMIC_SEP_LIST(PARAM_DECL, N); \ - virtual void call() { \ + virtual void call() override { \ *ret = (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ } \ }; @@ -238,7 +238,7 @@ T *instance; \ M method; \ SEMIC_SEP_LIST(PARAM_DECL, N); \ - virtual void call() { \ + virtual void call() override { \ (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ } \ }; @@ -311,9 +311,9 @@ class CommandQueueMT { }; struct SyncCommand : public CommandBase { - SyncSemaphore *sync_sem; + SyncSemaphore *sync_sem = nullptr; - virtual void post() { + virtual void post() override { sync_sem->sem.post(); } }; diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index e79ca037db..f1ac32928f 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -86,13 +86,6 @@ private: return reinterpret_cast<uint32_t *>(_ptr) - 1; } - _FORCE_INLINE_ T *_get_data() const { - if (!_ptr) { - return nullptr; - } - return reinterpret_cast<T *>(_ptr); - } - _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const { return next_power_of_2(p_elements * sizeof(T)); } @@ -128,11 +121,11 @@ public: _FORCE_INLINE_ T *ptrw() { _copy_on_write(); - return (T *)_get_data(); + return _ptr; } _FORCE_INLINE_ const T *ptr() const { - return _get_data(); + return _ptr; } _FORCE_INLINE_ int size() const { @@ -150,19 +143,19 @@ public: _FORCE_INLINE_ void set(int p_index, const T &p_elem) { ERR_FAIL_INDEX(p_index, size()); _copy_on_write(); - _get_data()[p_index] = p_elem; + _ptr[p_index] = p_elem; } _FORCE_INLINE_ T &get_m(int p_index) { CRASH_BAD_INDEX(p_index, size()); _copy_on_write(); - return _get_data()[p_index]; + return _ptr[p_index]; } _FORCE_INLINE_ const T &get(int p_index) const { CRASH_BAD_INDEX(p_index, size()); - return _get_data()[p_index]; + return _ptr[p_index]; } Error resize(int p_size); @@ -249,7 +242,7 @@ uint32_t CowData<T>::_copy_on_write() { } else { for (uint32_t i = 0; i < current_size; i++) { - memnew_placement(&_data[i], T(_get_data()[i])); + memnew_placement(&_data[i], T(_ptr[i])); } } @@ -308,10 +301,8 @@ Error CowData<T>::resize(int p_size) { // construct the newly created elements if (!__has_trivial_constructor(T)) { - T *elems = _get_data(); - for (int i = *_get_size(); i < p_size; i++) { - memnew_placement(&elems[i], T); + memnew_placement(&_ptr[i], T); } } @@ -321,7 +312,7 @@ Error CowData<T>::resize(int p_size) { if (!__has_trivial_destructor(T)) { // deinitialize no longer needed elements for (uint32_t i = p_size; i < *_get_size(); i++) { - T *t = &_get_data()[i]; + T *t = &_ptr[i]; t->~T(); } } diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index 45e0cc2427..fa5677cc70 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,7 +40,6 @@ /** * @class HashMap - * @author Juan Linietsky <reduzio@gmail.com> * * Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key. * The implementation provides hashers for the default types, if you need a special kind of hasher, provide @@ -48,7 +47,8 @@ * @param TKey Key, search is based on it, needs to be hasheable. It is unique in this container. * @param TData Data, data associated with the key * @param Hasher Hasher object, needs to provide a valid static hash function for TKey - * @param Comparator comparator object, needs to be able to safely compare two TKey values. It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. + * @param Comparator comparator object, needs to be able to safely compare two TKey values. + * It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check. * @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter. * @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP * times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER. diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index c1a7c4146e..2a129f97d5 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/list.h b/core/templates/list.h index afbed998c2..fe14d85d8f 100644 --- a/core/templates/list.h +++ b/core/templates/list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 3854e1e94c..f4e0748c27 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,6 +36,8 @@ #include "core/templates/sort_array.h" #include "core/templates/vector.h" +#include <initializer_list> + template <class T, class U = uint32_t, bool force_trivial = false> class LocalVector { private: @@ -228,25 +230,29 @@ public: } _FORCE_INLINE_ LocalVector() {} + _FORCE_INLINE_ LocalVector(std::initializer_list<T> p_init) { + reserve(p_init.size()); + for (const T &element : p_init) { + push_back(element); + } + } _FORCE_INLINE_ LocalVector(const LocalVector &p_from) { resize(p_from.size()); for (U i = 0; i < p_from.count; i++) { data[i] = p_from.data[i]; } } - inline LocalVector &operator=(const LocalVector &p_from) { + inline void operator=(const LocalVector &p_from) { resize(p_from.size()); for (U i = 0; i < p_from.count; i++) { data[i] = p_from.data[i]; } - return *this; } - inline LocalVector &operator=(const Vector<T> &p_from) { + inline void operator=(const Vector<T> &p_from) { resize(p_from.size()); for (U i = 0; i < count; i++) { data[i] = p_from[i]; } - return *this; } _FORCE_INLINE_ ~LocalVector() { diff --git a/core/templates/lru.h b/core/templates/lru.h index e55e40da48..48ba318b12 100644 --- a/core/templates/lru.h +++ b/core/templates/lru.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/map.h b/core/templates/map.h index badb407e5d..c54da1dc03 100644 --- a/core/templates/map.h +++ b/core/templates/map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -178,7 +178,7 @@ public: private: struct _Data { Element *_root = nullptr; - Element *_nil; + Element *_nil = nullptr; int size_cache = 0; _FORCE_INLINE_ _Data() { @@ -344,7 +344,7 @@ private: void _insert_rb_fix(Element *p_new_node) { Element *node = p_new_node; Element *nparent = node->parent; - Element *ngrand_parent; + Element *ngrand_parent = nullptr; while (nparent->color == RED) { ngrand_parent = nparent->parent; @@ -500,7 +500,7 @@ private: Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; - Element *sibling; + Element *sibling = nullptr; if (rp == rp->parent->left) { rp->parent->left = node; sibling = rp->parent->right; diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h index 025cc30db4..e4d9323c45 100644 --- a/core/templates/oa_hash_map.h +++ b/core/templates/oa_hash_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -145,7 +145,7 @@ private: uint32_t old_capacity = capacity; // Capacity can't be 0. - capacity = MAX(1, p_new_capacity); + capacity = MAX(1u, p_new_capacity); TKey *old_keys = keys; TValue *old_values = values; @@ -306,7 +306,7 @@ public: bool valid; const TKey *key; - TValue *value; + TValue *value = nullptr; private: uint32_t pos; @@ -353,7 +353,7 @@ public: (*this) = p_other; } - OAHashMap &operator=(const OAHashMap &p_other) { + void operator=(const OAHashMap &p_other) { if (capacity != 0) { clear(); } @@ -363,12 +363,11 @@ public: for (Iterator it = p_other.iter(); it.valid; it = p_other.next_iter(it)) { set(*it.key, *it.value); } - return *this; } OAHashMap(uint32_t p_initial_capacity = 64) { // Capacity can't be 0. - capacity = MAX(1, p_initial_capacity); + capacity = MAX(1u, p_initial_capacity); keys = static_cast<TKey *>(Memory::alloc_static(sizeof(TKey) * capacity)); values = static_cast<TValue *>(Memory::alloc_static(sizeof(TValue) * capacity)); diff --git a/core/templates/ordered_hash_map.h b/core/templates/ordered_hash_map.h index 4996b88190..3d1f3a08ec 100644 --- a/core/templates/ordered_hash_map.h +++ b/core/templates/ordered_hash_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -85,11 +85,10 @@ public: next_element(other.next_element) { } - Element &operator=(const Element &other) { + void operator=(const Element &other) { list_element = other.list_element; next_element = other.next_element; prev_element = other.prev_element; - return *this; } _FORCE_INLINE_ bool operator==(const Element &p_other) const { @@ -145,9 +144,8 @@ public: list_element(other.list_element) { } - ConstElement &operator=(const ConstElement &other) { + void operator=(const ConstElement &other) { list_element = other.list_element; - return *this; } ConstElement next() const { diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h index dfc885c6eb..b9067e2edd 100644 --- a/core/templates/paged_allocator.h +++ b/core/templates/paged_allocator.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -86,10 +86,10 @@ public: } p_mem->~T(); available_pool[allocs_available >> page_shift][allocs_available & page_mask] = p_mem; + allocs_available++; if (thread_safe) { spin_lock.unlock(); } - allocs_available++; } void reset(bool p_allow_unfreed = false) { diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h index 599d3dde4f..33d2757bec 100644 --- a/core/templates/paged_array.h +++ b/core/templates/paged_array.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/pair.h b/core/templates/pair.h index e30ee8bc56..eb86e21b03 100644 --- a/core/templates/pair.h +++ b/core/templates/pair.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/pass_func.h b/core/templates/pass_func.h index d2f465e91c..8bd34ddfd6 100644 --- a/core/templates/pass_func.h +++ b/core/templates/pass_func.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/pooled_list.h b/core/templates/pooled_list.h index b139dadb75..f13156b292 100644 --- a/core/templates/pooled_list.h +++ b/core/templates/pooled_list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,16 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POOLED_LIST_H -#define POOLED_LIST_H - -#include "core/templates/local_vector.h" +#pragma once // Simple template to provide a pool with O(1) allocate and free. // The freelist could alternatively be a linked list placed within the unused elements // to use less memory, however a separate freelist is probably more cache friendly. -// -// NOTE: Take great care when using this with non POD types. The construction and destruction + +// NOTE : Take great care when using this with non POD types. The construction and destruction // is done in the LocalVector, NOT as part of the pool. So requesting a new item does not guarantee // a constructor is run, and free does not guarantee a destructor. // You should generally handle clearing @@ -45,33 +42,60 @@ // This is by design for fastest use in the BVH. If you want a more general pool // that does call constructors / destructors on request / free, this should probably be // a separate template. -template <class T, bool force_trivial = false> + +// The zero_on_first_request feature is optional and is useful for e.g. pools of handles, +// which may use a ref count which we want to be initialized to zero the first time a handle is created, +// but left alone on subsequent allocations (as will typically be incremented). + +// Note that there is no function to compact the pool - this would +// invalidate any existing pool IDs held externally. +// Compaction can be done but would rely on a more complex method +// of preferentially giving out lower IDs in the freelist first. + +#include "core/templates/local_vector.h" + +template <class T, class U = uint32_t, bool force_trivial = false, bool zero_on_first_request = false> class PooledList { - LocalVector<T, uint32_t, force_trivial> list; - LocalVector<uint32_t, uint32_t, true> freelist; + LocalVector<T, U, force_trivial> list; + LocalVector<U, U, true> freelist; // not all list members are necessarily used - int _used_size; + U _used_size; public: PooledList() { _used_size = 0; } - int estimate_memory_use() const { - return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t)); + // Use with care, in most cases you should make sure to + // free all elements first (i.e. _used_size would be zero), + // although it could also be used without this as an optimization + // in some cases. + void clear() { + list.clear(); + freelist.clear(); + _used_size = 0; + } + + uint64_t estimate_memory_use() const { + return ((uint64_t)list.size() * sizeof(T)) + ((uint64_t)freelist.size() * sizeof(U)); } - const T &operator[](uint32_t p_index) const { + const T &operator[](U p_index) const { return list[p_index]; } - T &operator[](uint32_t p_index) { + T &operator[](U p_index) { return list[p_index]; } - int size() const { return _used_size; } + // To be explicit in a pool there is a distinction + // between the number of elements that are currently + // in use, and the number of elements that have been reserved. + // Using size() would be vague. + U used_size() const { return _used_size; } + U reserved_size() const { return list.size(); } - T *request(uint32_t &r_id) { + T *request(U &r_id) { _used_size++; if (freelist.size()) { @@ -79,19 +103,106 @@ public: int new_size = freelist.size() - 1; r_id = freelist[new_size]; freelist.resize(new_size); + return &list[r_id]; } r_id = list.size(); list.resize(r_id + 1); + + static_assert((!zero_on_first_request) || (__is_pod(T)), "zero_on_first_request requires trivial type"); + if (zero_on_first_request && __is_pod(T)) { + list[r_id] = {}; + } + return &list[r_id]; } - void free(const uint32_t &p_id) { + void free(const U &p_id) { // should not be on free list already - CRASH_COND(p_id >= list.size()); + ERR_FAIL_UNSIGNED_INDEX(p_id, list.size()); freelist.push_back(p_id); + ERR_FAIL_COND_MSG(!_used_size, "_used_size has become out of sync, have you double freed an item?"); _used_size--; } }; -#endif // POOLED_LIST_H +// a pooled list which automatically keeps a list of the active members +template <class T, class U = uint32_t, bool force_trivial = false, bool zero_on_first_request = false> +class TrackedPooledList { +public: + U pool_used_size() const { return _pool.used_size(); } + U pool_reserved_size() const { return _pool.reserved_size(); } + U active_size() const { return _active_list.size(); } + + // use with care, see the earlier notes in the PooledList clear() + void clear() { + _pool.clear(); + _active_list.clear(); + _active_map.clear(); + } + + U get_active_id(U p_index) const { + return _active_list[p_index]; + } + + const T &get_active(U p_index) const { + return _pool[get_active_id(p_index)]; + } + + T &get_active(U p_index) { + return _pool[get_active_id(p_index)]; + } + + const T &operator[](U p_index) const { + return _pool[p_index]; + } + T &operator[](U p_index) { + return _pool[p_index]; + } + + T *request(U &r_id) { + T *item = _pool.request(r_id); + + // add to the active list + U active_list_id = _active_list.size(); + _active_list.push_back(r_id); + + // expand the active map (this should be in sync with the pool list + if (_pool.used_size() > _active_map.size()) { + _active_map.resize(_pool.used_size()); + } + + // store in the active map + _active_map[r_id] = active_list_id; + + return item; + } + + void free(const U &p_id) { + _pool.free(p_id); + + // remove from the active list. + U list_id = _active_map[p_id]; + + // zero the _active map to detect bugs (only in debug?) + _active_map[p_id] = -1; + + _active_list.remove_unordered(list_id); + + // keep the replacement in sync with the correct list Id + if (list_id < _active_list.size()) { + // which pool id has been replaced in the active list + U replacement_id = _active_list[list_id]; + + // keep that replacements map up to date with the new position + _active_map[replacement_id] = list_id; + } + } + + const LocalVector<U, U> &get_active_list() const { return _active_list; } + +private: + PooledList<T, U, force_trivial, zero_on_first_request> _pool; + LocalVector<U, U> _active_map; + LocalVector<U, U> _active_list; +}; diff --git a/core/templates/rid.h b/core/templates/rid.h index 4c7119b4ea..679c43f906 100644 --- a/core/templates/rid.h +++ b/core/templates/rid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/rid_owner.cpp b/core/templates/rid_owner.cpp index 56f39ab779..7fc819e232 100644 --- a/core/templates/rid_owner.cpp +++ b/core/templates/rid_owner.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index 71d41eacc4..95632cdec2 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -292,43 +292,32 @@ public: _FORCE_INLINE_ uint32_t get_rid_count() const { return alloc_count; } - - _FORCE_INLINE_ T *get_ptr_by_index(uint32_t p_index) { - ERR_FAIL_UNSIGNED_INDEX_V(p_index, alloc_count, nullptr); + void get_owned_list(List<RID> *p_owned) { if (THREAD_SAFE) { spin_lock.lock(); } - uint64_t idx = free_list_chunks[p_index / elements_in_chunk][p_index % elements_in_chunk]; - T *ptr = &chunks[idx / elements_in_chunk][idx % elements_in_chunk]; - if (THREAD_SAFE) { - spin_lock.unlock(); - } - return ptr; - } - - _FORCE_INLINE_ RID get_rid_by_index(uint32_t p_index) { - ERR_FAIL_INDEX_V(p_index, alloc_count, RID()); - if (THREAD_SAFE) { - spin_lock.lock(); + for (size_t i = 0; i < max_alloc; i++) { + uint64_t validator = validator_chunks[i / elements_in_chunk][i % elements_in_chunk]; + if (validator != 0xFFFFFFFF) { + p_owned->push_back(_make_from_id((validator << 32) | i)); + } } - uint64_t idx = free_list_chunks[p_index / elements_in_chunk][p_index % elements_in_chunk]; - uint64_t validator = validator_chunks[idx / elements_in_chunk][idx % elements_in_chunk]; - - RID rid = _make_from_id((validator << 32) | idx); if (THREAD_SAFE) { spin_lock.unlock(); } - return rid; } - void get_owned_list(List<RID> *p_owned) { + //used for fast iteration in the elements or RIDs + void fill_owned_buffer(RID *p_rid_buffer) { if (THREAD_SAFE) { spin_lock.lock(); } + uint32_t idx = 0; for (size_t i = 0; i < max_alloc; i++) { uint64_t validator = validator_chunks[i / elements_in_chunk][i % elements_in_chunk]; if (validator != 0xFFFFFFFF) { - p_owned->push_back(_make_from_id((validator << 32) | i)); + p_rid_buffer[idx] = _make_from_id((validator << 32) | i); + idx++; } } if (THREAD_SAFE) { @@ -425,18 +414,14 @@ public: return alloc.get_rid_count(); } - _FORCE_INLINE_ RID get_rid_by_index(uint32_t p_index) { - return alloc.get_rid_by_index(p_index); - } - - _FORCE_INLINE_ T *get_ptr_by_index(uint32_t p_index) { - return *alloc.get_ptr_by_index(p_index); - } - _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) { return alloc.get_owned_list(p_owned); } + void fill_owned_buffer(RID *p_rid_buffer) { + alloc.fill_owned_buffer(p_rid_buffer); + } + void set_description(const char *p_descrption) { alloc.set_description(p_descrption); } @@ -485,17 +470,12 @@ public: return alloc.get_rid_count(); } - _FORCE_INLINE_ RID get_rid_by_index(uint32_t p_index) { - return alloc.get_rid_by_index(p_index); - } - - _FORCE_INLINE_ T *get_ptr_by_index(uint32_t p_index) { - return alloc.get_ptr_by_index(p_index); - } - _FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) { return alloc.get_owned_list(p_owned); } + void fill_owned_buffer(RID *p_rid_buffer) { + alloc.fill_owned_buffer(p_rid_buffer); + } void set_description(const char *p_descrption) { alloc.set_description(p_descrption); diff --git a/core/templates/ring_buffer.h b/core/templates/ring_buffer.h index e7b77440f1..742f9462fb 100644 --- a/core/templates/ring_buffer.h +++ b/core/templates/ring_buffer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/safe_list.h b/core/templates/safe_list.h index d8f010663b..e850f3bd5e 100644 --- a/core/templates/safe_list.h +++ b/core/templates/safe_list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -75,8 +75,8 @@ public: class Iterator { friend class SafeList; - SafeListNode *cursor; - SafeList *list; + SafeListNode *cursor = nullptr; + SafeList *list = nullptr; Iterator(SafeListNode *p_cursor, SafeList *p_list) : cursor(p_cursor), list(p_list) { @@ -203,7 +203,7 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = nullptr; SafeListNode *new_graveyard_head = nullptr; do { @@ -212,7 +212,7 @@ public: if (active_iterator_count.load() != 0) { // It's not safe to clean up with an active iterator, because that iterator // could be pointing to an element that we want to delete. - return; + return false; } // Any iterator created after this point will never point to a deleted node. // Swap it out with the current graveyard head. @@ -225,6 +225,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator<SafeListNode, A>(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; @@ -253,8 +264,8 @@ public: class Iterator { friend class SafeList; - SafeListNode *cursor; - SafeList *list; + SafeListNode *cursor = nullptr; + SafeList *list = nullptr; public: Iterator(SafeListNode *p_cursor, SafeList *p_list) : @@ -353,11 +364,11 @@ public: } // Calling this will cause zero to many deallocations. - void maybe_cleanup() { + bool maybe_cleanup() { SafeListNode *cursor = graveyard_head; if (active_iterator_count != 0) { // It's not safe to clean up with an active iterator, because that iterator could be pointing to an element that we want to delete. - return; + return false; } graveyard_head = nullptr; // Our graveyard list is now unreachable by any active iterators, detached from the main graveyard head and ready for deletion. @@ -367,6 +378,17 @@ public: tmp->deletion_fn(tmp->val); memdelete_allocator<SafeListNode, A>(tmp); } + return true; + } + + ~SafeList() { +#ifdef DEBUG_ENABLED + if (!maybe_cleanup()) { + ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug."); + } +#else + maybe_cleanup(); +#endif } }; diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h index e9e5695f80..76f76be96a 100644 --- a/core/templates/safe_refcount.h +++ b/core/templates/safe_refcount.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/search_array.h b/core/templates/search_array.h index 8efc32df82..e717a352d1 100644 --- a/core/templates/search_array.h +++ b/core/templates/search_array.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/self_list.h b/core/templates/self_list.h index e8d36ea358..719b5f2e63 100644 --- a/core/templates/self_list.h +++ b/core/templates/self_list.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -108,7 +108,7 @@ public: private: List *_root = nullptr; - T *_self; + T *_self = nullptr; SelfList<T> *_next = nullptr; SelfList<T> *_prev = nullptr; diff --git a/core/templates/set.h b/core/templates/set.h index 0a80ceefb5..a8a0a77712 100644 --- a/core/templates/set.h +++ b/core/templates/set.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -328,7 +328,7 @@ private: void _insert_rb_fix(Element *p_new_node) { Element *node = p_new_node; Element *nparent = node->parent; - Element *ngrand_parent; + Element *ngrand_parent = nullptr; while (nparent->color == RED) { ngrand_parent = nparent->parent; @@ -482,7 +482,7 @@ private: Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; - Element *sibling; + Element *sibling = nullptr; if (rp == rp->parent->left) { rp->parent->left = node; sibling = rp->parent->right; @@ -582,6 +582,9 @@ public: } Element *lower_bound(const T &p_value) const { + if (!_data._root) { + return nullptr; + } return _lower_bound(p_value); } diff --git a/core/templates/simple_type.h b/core/templates/simple_type.h index 80bfa83fde..9352b500a2 100644 --- a/core/templates/simple_type.h +++ b/core/templates/simple_type.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/sort_array.h b/core/templates/sort_array.h index 1656d2991d..6cf9368056 100644 --- a/core/templates/sort_array.h +++ b/core/templates/sort_array.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/thread_work_pool.cpp b/core/templates/thread_work_pool.cpp index 710f043a4a..a75fd06b9b 100644 --- a/core/templates/thread_work_pool.cpp +++ b/core/templates/thread_work_pool.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index 19096c496a..b0cebf04f1 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,7 +52,7 @@ class ThreadWorkPool { C *instance; M method; U userdata; - virtual void work() { + virtual void work() override { while (true) { uint32_t work_index = index->fetch_add(1, std::memory_order_relaxed); if (work_index >= max_elements) { @@ -68,7 +68,7 @@ class ThreadWorkPool { Semaphore start; Semaphore completed; std::atomic<bool> exit; - BaseWork *work; + BaseWork *work = nullptr; }; ThreadData *threads = nullptr; diff --git a/core/templates/vector.h b/core/templates/vector.h index a955d49101..d87e76139b 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,6 @@ /** * @class Vector - * @author Juan Linietsky * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays. */ @@ -43,6 +42,9 @@ #include "core/templates/search_array.h" #include "core/templates/sort_array.h" +#include <climits> +#include <initializer_list> + template <class T> class VectorWriteProxy { public: @@ -93,28 +95,31 @@ public: void append_array(Vector<T> p_other); - bool has(const T &p_val) const { - return find(p_val, 0) != -1; + _FORCE_INLINE_ bool has(const T &p_val) const { return find(p_val) != -1; } + + void sort() { + sort_custom<_DefaultComparator<T>>(); } - template <class C> - void sort_custom() { + template <class Comparator, bool Validate = SORT_ARRAY_VALIDATE_ENABLED, class... Args> + void sort_custom(Args &&...args) { int len = _cowdata.size(); if (len == 0) { return; } T *data = ptrw(); - SortArray<T, C> sorter; + SortArray<T, Comparator, Validate> sorter{ args... }; sorter.sort(data, len); } - void sort() { - sort_custom<_DefaultComparator<T>>(); + int bsearch(const T &p_value, bool p_before) { + return bsearch_custom<_DefaultComparator<T>>(p_value, p_before); } - int bsearch(const T &p_value, bool p_before) { - SearchArray<T> search; + template <class Comparator, class Value, class... Args> + int bsearch_custom(const Value &p_value, bool p_before, Args &&...args) { + SearchArray<T, Comparator> search{ args... }; return search.bisect(ptrw(), size(), p_value, p_before); } @@ -132,9 +137,8 @@ public: insert(i, p_val); } - inline Vector &operator=(const Vector &p_from) { + inline void operator=(const Vector &p_from) { _cowdata._ref(p_from._cowdata); - return *this; } Vector<uint8_t> to_byte_array() const { @@ -144,27 +148,32 @@ public: return ret; } - Vector<T> subarray(int p_from, int p_to) const { - if (p_from < 0) { - p_from = size() + p_from; + Vector<T> slice(int p_begin, int p_end = INT_MAX) const { + Vector<T> result; + + const int s = size(); + + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; } - if (p_to < 0) { - p_to = size() + p_to; + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; } - ERR_FAIL_INDEX_V(p_from, size(), Vector<T>()); - ERR_FAIL_INDEX_V(p_to, size(), Vector<T>()); + ERR_FAIL_COND_V(begin > end, result); + + int result_size = end - begin; + result.resize(result_size); - Vector<T> slice; - int span = 1 + p_to - p_from; - slice.resize(span); - const T *r = ptr(); - T *w = slice.ptrw(); - for (int i = 0; i < span; ++i) { - w[i] = r[p_from + i]; + const T *const r = ptr(); + T *const w = result.ptrw(); + for (int i = 0; i < result_size; ++i) { + w[i] = r[begin + i]; } - return slice; + return result; } bool operator==(const Vector<T> &p_arr) const { @@ -258,6 +267,15 @@ public: } _FORCE_INLINE_ Vector() {} + _FORCE_INLINE_ Vector(std::initializer_list<T> p_init) { + Error err = _cowdata.resize(p_init.size()); + ERR_FAIL_COND(err); + + int i = 0; + for (const T &element : p_init) { + _cowdata.set(i++, element); + } + } _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); } _FORCE_INLINE_ ~Vector() {} diff --git a/core/templates/vmap.h b/core/templates/vmap.h index 2aa22f97cf..37622258db 100644 --- a/core/templates/vmap.h +++ b/core/templates/vmap.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -142,6 +142,9 @@ public: } int find_nearest(const T &p_val) const { + if (_cowdata.is_empty()) { + return -1; + } bool exact; return _find(p_val, exact); } @@ -193,9 +196,8 @@ public: _FORCE_INLINE_ VMap() {} _FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); } - inline VMap &operator=(const VMap &p_from) { + inline void operator=(const VMap &p_from) { _cowdata._ref(p_from._cowdata); - return *this; } }; diff --git a/core/templates/vset.h b/core/templates/vset.h index 94e7a17061..09bddbbe69 100644 --- a/core/templates/vset.h +++ b/core/templates/vset.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |