From 37e287d86dd8751f1d323053a2164adf322f492f Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 2 Mar 2024 12:01:27 +0100 Subject: [PATCH] Backported goodies to SelfList from Godot4. --- core/containers/self_list.h | 70 ++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/core/containers/self_list.h b/core/containers/self_list.h index 5e4a1fd84..d4558bfba 100644 --- a/core/containers/self_list.h +++ b/core/containers/self_list.h @@ -100,13 +100,78 @@ public: p_elem->_root = nullptr; } + void clear() { + while (_first) { + remove(_first); + } + } + + void sort() { + sort_custom>(); + } + + template + void sort_custom() { + if (_first == _last) { + return; + } + + SelfList *from = _first; + SelfList *current = from; + SelfList *to = from; + + while (current) { + SelfList *next = current->_next; + + if (from != current) { + current->_prev = nullptr; + current->_next = from; + + SelfList *find = from; + C less; + while (find && less(*find->_self, *current->_self)) { + current->_prev = find; + current->_next = find->_next; + find = find->_next; + } + + if (current->_prev) { + current->_prev->_next = current; + } else { + from = current; + } + + if (current->_next) { + current->_next->_prev = current; + } else { + to = current; + } + } else { + current->_prev = nullptr; + current->_next = nullptr; + } + + current = next; + } + _first = from; + _last = to; + } + _FORCE_INLINE_ SelfList *first() { return _first; } _FORCE_INLINE_ const SelfList *first() const { return _first; } + + // Forbid copying, which has broken behavior. + void operator=(const List &) = delete; + _FORCE_INLINE_ List() { _first = nullptr; _last = nullptr; } - _FORCE_INLINE_ ~List() { ERR_FAIL_COND(_first != nullptr); } + + _FORCE_INLINE_ ~List() { + // A self list must be empty on destruction. + DEV_ASSERT(_first == nullptr); + } }; private: @@ -128,6 +193,9 @@ public: _FORCE_INLINE_ const SelfList *prev() const { return _prev; } _FORCE_INLINE_ T *self() const { return _self; } + // Forbid copying, which has broken behavior. + void operator=(const SelfList &) = delete; + _FORCE_INLINE_ SelfList(T *p_self) { _self = p_self; _next = nullptr;