From 12a128366312da9fc6b6157b4bd3081b522e0104 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:45:15 +0200 Subject: [PATCH 1/2] [Core] Reduce and prevent unnecessary random-access to `List` Random-access access to `List` when iterating is `O(n^2)` (`O(n)` when accessing a single element) * Removed subscript operator, in favor of a more explicit `get` * Added conversion from `Iterator` to `ConstIterator` --- include/godot_cpp/templates/list.hpp | 56 ++++++++++++++++------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/include/godot_cpp/templates/list.hpp b/include/godot_cpp/templates/list.hpp index 376e3ea87..55e2c35f7 100644 --- a/include/godot_cpp/templates/list.hpp +++ b/include/godot_cpp/templates/list.hpp @@ -139,54 +139,58 @@ class List { typedef T ValueType; - struct Iterator { - _FORCE_INLINE_ T &operator*() const { + struct ConstIterator { + _FORCE_INLINE_ const T &operator*() const { return E->get(); } - _FORCE_INLINE_ T *operator->() const { return &E->get(); } - _FORCE_INLINE_ Iterator &operator++() { + _FORCE_INLINE_ const T *operator->() const { return &E->get(); } + _FORCE_INLINE_ ConstIterator &operator++() { E = E->next(); return *this; } - _FORCE_INLINE_ Iterator &operator--() { + _FORCE_INLINE_ ConstIterator &operator--() { E = E->prev(); return *this; } - _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } - Iterator(Element *p_E) { E = p_E; } - Iterator() {} - Iterator(const Iterator &p_it) { E = p_it.E; } + _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } + _FORCE_INLINE_ ConstIterator() {} + _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; } private: - Element *E = nullptr; + const Element *E = nullptr; }; - struct ConstIterator { - _FORCE_INLINE_ const T &operator*() const { + struct Iterator { + _FORCE_INLINE_ T &operator*() const { return E->get(); } - _FORCE_INLINE_ const T *operator->() const { return &E->get(); } - _FORCE_INLINE_ ConstIterator &operator++() { + _FORCE_INLINE_ T *operator->() const { return &E->get(); } + _FORCE_INLINE_ Iterator &operator++() { E = E->next(); return *this; } - _FORCE_INLINE_ ConstIterator &operator--() { + _FORCE_INLINE_ Iterator &operator--() { E = E->prev(); return *this; } - _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } - _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } - _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } - _FORCE_INLINE_ ConstIterator() {} - _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; } + Iterator(Element *p_E) { E = p_E; } + Iterator() {} + Iterator(const Iterator &p_it) { E = p_it.E; } + + operator ConstIterator() const { + return ConstIterator(E); + } private: - const Element *E = nullptr; + Element *E = nullptr; }; _FORCE_INLINE_ Iterator begin() { @@ -519,7 +523,9 @@ class List { } } - T &operator[](int p_index) { + // Random access to elements, use with care, + // do not use for iteration. + T &get(int p_index) { CRASH_BAD_INDEX(p_index, size()); Element *I = front(); @@ -532,7 +538,9 @@ class List { return I->get(); } - const T &operator[](int p_index) const { + // Random access to elements, use with care, + // do not use for iteration. + const T &get(int p_index) const { CRASH_BAD_INDEX(p_index, size()); const Element *I = front(); From d0bdd6096c0440542245fb37690e7ab8f3e34b29 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Tue, 7 May 2024 10:43:41 +0200 Subject: [PATCH 2/2] Optionaly add compatibility operators --- include/godot_cpp/templates/list.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/godot_cpp/templates/list.hpp b/include/godot_cpp/templates/list.hpp index 55e2c35f7..fa5960565 100644 --- a/include/godot_cpp/templates/list.hpp +++ b/include/godot_cpp/templates/list.hpp @@ -523,6 +523,11 @@ class List { } } + // Index operator, kept for compatibility. + _FORCE_INLINE_ T &operator[](int p_index) { + return get(p_index); + } + // Random access to elements, use with care, // do not use for iteration. T &get(int p_index) { @@ -538,6 +543,11 @@ class List { return I->get(); } + // Index operator, kept for compatibility. + _FORCE_INLINE_ const T &operator[](int p_index) const { + return get(p_index); + } + // Random access to elements, use with care, // do not use for iteration. const T &get(int p_index) const {