From f09949a4c0b2b6b6389076d0b4ed26a08e97eab5 Mon Sep 17 00:00:00 2001 From: apple1417 Date: Thu, 4 Jan 2024 22:45:39 +1300 Subject: [PATCH] add default constructors for iterators enables using them with `std::ranges` --- src/unrealsdk/unreal/classes/ustruct.cpp | 9 ++++++--- src/unrealsdk/unreal/classes/ustruct.h | 3 +++ src/unrealsdk/unreal/structs/tarray.h | 6 +++--- src/unrealsdk/unreal/wrappers/gobjects.cpp | 20 ++++++++++++-------- src/unrealsdk/unreal/wrappers/gobjects.h | 3 ++- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/unrealsdk/unreal/classes/ustruct.cpp b/src/unrealsdk/unreal/classes/ustruct.cpp index aa8f41e..1e854f2 100644 --- a/src/unrealsdk/unreal/classes/ustruct.cpp +++ b/src/unrealsdk/unreal/classes/ustruct.cpp @@ -12,6 +12,7 @@ namespace unrealsdk::unreal { #pragma region Field Iterator +UStruct::FieldIterator::FieldIterator(void) : this_struct(nullptr), field(nullptr) {} UStruct::FieldIterator::FieldIterator(const UStruct* this_struct, UField* field) : this_struct(this_struct), field(field) {} @@ -55,13 +56,14 @@ utils::IteratorProxy UStruct::fields(void) const { begin++; } - return {begin, {nullptr, nullptr}}; + return {begin, {}}; } #pragma endregion #pragma region Property Iterator +UStruct::PropertyIterator::PropertyIterator(void) : prop(nullptr) {} UStruct::PropertyIterator::PropertyIterator(UProperty* prop) : prop(prop) {} UStruct::PropertyIterator::reference UStruct::PropertyIterator::operator*() const { @@ -86,13 +88,14 @@ bool UStruct::PropertyIterator::operator!=(const UStruct::PropertyIterator& rhs) }; utils::IteratorProxy UStruct::properties(void) const { - return {{this->PropertyLink}, {nullptr}}; + return {{this->PropertyLink}, {}}; } #pragma endregion #pragma region SuperField Iterator +UStruct::SuperFieldIterator::SuperFieldIterator(void) : this_struct(nullptr) {} UStruct::SuperFieldIterator::SuperFieldIterator(const UStruct* this_struct) : this_struct(this_struct) {} @@ -118,7 +121,7 @@ bool UStruct::SuperFieldIterator::operator!=(const UStruct::SuperFieldIterator& }; utils::IteratorProxy UStruct::superfields(void) const { - return {{this}, {nullptr}}; + return {{this}, {}}; } #pragma endregion diff --git a/src/unrealsdk/unreal/classes/ustruct.h b/src/unrealsdk/unreal/classes/ustruct.h index 9e5db95..573afc5 100644 --- a/src/unrealsdk/unreal/classes/ustruct.h +++ b/src/unrealsdk/unreal/classes/ustruct.h @@ -98,6 +98,7 @@ class UStruct : public UField { UField* field; public: + FieldIterator(void); FieldIterator(const UStruct* this_struct, UField* field); reference operator*() const; @@ -120,6 +121,7 @@ class UStruct : public UField { UProperty* prop; public: + PropertyIterator(void); PropertyIterator(UProperty* prop); reference operator*() const; @@ -142,6 +144,7 @@ class UStruct : public UField { const UStruct* this_struct; public: + SuperFieldIterator(void); SuperFieldIterator(const UStruct* this_struct); reference operator*() const; diff --git a/src/unrealsdk/unreal/structs/tarray.h b/src/unrealsdk/unreal/structs/tarray.h index 34cd0ad..4ca59ea 100644 --- a/src/unrealsdk/unreal/structs/tarray.h +++ b/src/unrealsdk/unreal/structs/tarray.h @@ -129,6 +129,7 @@ struct TArray { size_t idx{}; public: + Iterator(void) : arr(nullptr) {} Iterator(const TArray* arr) : arr(arr) {} reference operator*() const { return (*this->arr)[this->idx]; }; @@ -136,8 +137,7 @@ struct TArray { Iterator& operator++() { ++this->idx; // Use `arr == nullptr` as the end condition, so we behave a little better if the array - // grows during iteration - we can't guarantee control over this iterator as well as - // the others + // grows during iteration if (this->idx >= (size_t)arr->count) { arr = nullptr; } @@ -179,7 +179,7 @@ struct TArray { template && std::negation_v>>> [[nodiscard]] static Iterator end(void) { - return {nullptr}; + return {}; } #pragma endregion }; diff --git a/src/unrealsdk/unreal/wrappers/gobjects.cpp b/src/unrealsdk/unreal/wrappers/gobjects.cpp index 5f9cccd..c3edc4c 100644 --- a/src/unrealsdk/unreal/wrappers/gobjects.cpp +++ b/src/unrealsdk/unreal/wrappers/gobjects.cpp @@ -15,6 +15,7 @@ namespace unrealsdk::unreal { #pragma region Iterator +GObjects::Iterator::Iterator(void) : gobjects(nullptr), idx(0) {} GObjects::Iterator::Iterator(const GObjects& gobjects, size_t idx) : gobjects(&gobjects), idx(idx) {} @@ -24,18 +25,18 @@ GObjects::Iterator::reference GObjects::Iterator::operator*() const { GObjects::Iterator& GObjects::Iterator::operator++() { do { - // If we're on the last object, increment to max index + // If we're on the last object, set gobjects to null to end the iterator if (this->idx >= (this->gobjects->size() - 1)) { - this->idx = std::numeric_limits::max(); + this->gobjects = nullptr; break; } ++this->idx; // If this index points to a null object, increment again - // We really should handle gc'd object entries better (in UE4), but this is a quick hack to - // get the iterator mostly working. In practice, you really shouldn't be iterating through - // all objects anyway. + // We really should handle gc'd object entries better (in UE4), but this is a quick hack + // to get the iterator mostly working. In practice, you really shouldn't be iterating + // through all objects anyway. } while (this->operator*() == nullptr); return *this; @@ -47,7 +48,10 @@ GObjects::Iterator GObjects::Iterator::operator++(int) { } bool GObjects::Iterator::operator==(const GObjects::Iterator& rhs) const { - return this->idx == rhs.idx; + if (this->gobjects == nullptr && rhs.gobjects == nullptr) { + return true; + } + return this->gobjects == rhs.gobjects && this->idx == rhs.idx; }; bool GObjects::Iterator::operator!=(const GObjects::Iterator& rhs) const { return !(*this == rhs); @@ -57,8 +61,8 @@ GObjects::Iterator GObjects::begin(void) const { return {*this, 0}; } -GObjects::Iterator GObjects::end(void) const { - return {*this, std::numeric_limits::max()}; +GObjects::Iterator GObjects::end(void) { + return {}; } #pragma endregion diff --git a/src/unrealsdk/unreal/wrappers/gobjects.h b/src/unrealsdk/unreal/wrappers/gobjects.h index 7cf3b70..cbf543d 100644 --- a/src/unrealsdk/unreal/wrappers/gobjects.h +++ b/src/unrealsdk/unreal/wrappers/gobjects.h @@ -37,6 +37,7 @@ class GObjects { size_t idx; public: + Iterator(void); Iterator(const GObjects& gobjects, size_t idx); reference operator*() const; @@ -83,7 +84,7 @@ class GObjects { * * @return The iterator. */ - [[nodiscard]] Iterator end(void) const; + [[nodiscard]] static Iterator end(void); /** * @brief Get the object behind a weak object pointer (or null if it's invalid).