diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index f588d38129..00a2d4b2bb 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3347,6 +3347,12 @@ int String::find(const char *p_str, int p_from) const { } int String::find_char(char32_t p_char, int p_from) const { + if (p_from < 0) { + p_from = length() + p_from; + } + if (p_from < 0 || p_from >= length()) { + return -1; + } return span().find(p_char, p_from); } @@ -3584,6 +3590,12 @@ int String::rfind(const char *p_str, int p_from) const { } int String::rfind_char(char32_t p_char, int p_from) const { + if (p_from < 0) { + p_from = length() + p_from; + } + if (p_from < 0 || p_from >= length()) { + return -1; + } return span().rfind(p_char, p_from); } diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 89d3579573..ea7b8b5b6d 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -251,13 +251,14 @@ public: } } - int64_t find(const T &p_val, U p_from = 0) const { - for (U i = p_from; i < count; i++) { - if (data[i] == p_val) { - return int64_t(i); - } + int64_t find(const T &p_val, int64_t p_from = 0) const { + if (p_from < 0) { + p_from = size() + p_from; } - return -1; + if (p_from < 0 || p_from >= size()) { + return -1; + } + return span().find(p_val, p_from); } bool has(const T &p_val) const { diff --git a/core/templates/span.h b/core/templates/span.h index 5498a88eab..38c7a08a21 100644 --- a/core/templates/span.h +++ b/core/templates/span.h @@ -64,37 +64,24 @@ public: _FORCE_INLINE_ constexpr const T *end() const { return _ptr + _len; } // Algorithms. - constexpr int64_t find(const T &p_val, int64_t p_from = 0) const; - constexpr int64_t rfind(const T &p_val, int64_t p_from = 0) const; + constexpr int64_t find(const T &p_val, uint64_t p_from = 0) const; + constexpr int64_t rfind(const T &p_val, uint64_t p_from) const; + _FORCE_INLINE_ constexpr int64_t rfind(const T &p_val) const { return rfind(p_val, size() - 1); } constexpr uint64_t count(const T &p_val) const; }; template -constexpr int64_t Span::find(const T &p_val, int64_t p_from) const { - if (p_from < 0 || size() == 0) { - return -1; - } - +constexpr int64_t Span::find(const T &p_val, uint64_t p_from) const { for (uint64_t i = p_from; i < size(); i++) { if (ptr()[i] == p_val) { return i; } } - return -1; } template -constexpr int64_t Span::rfind(const T &p_val, int64_t p_from) const { - const int64_t s = size(); - - if (p_from < 0) { - p_from = s + p_from; - } - if (p_from < 0 || p_from >= s) { - p_from = s - 1; - } - +constexpr int64_t Span::rfind(const T &p_val, uint64_t p_from) const { for (int64_t i = p_from; i >= 0; i--) { if (ptr()[i] == p_val) { return i; diff --git a/core/templates/vector.h b/core/templates/vector.h index 01b7d00225..edc33b7beb 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -105,8 +105,24 @@ public: _FORCE_INLINE_ const T &operator[](Size p_index) const { return _cowdata.get(p_index); } // Must take a copy instead of a reference (see GH-31736). Error insert(Size p_pos, T p_val) { return _cowdata.insert(p_pos, p_val); } - Size find(const T &p_val, Size p_from = 0) const { return span().find(p_val, p_from); } - Size rfind(const T &p_val, Size p_from = -1) const { return span().rfind(p_val, p_from); } + Size find(const T &p_val, Size p_from = 0) const { + if (p_from < 0) { + p_from = size() + p_from; + } + if (p_from < 0 || p_from >= size()) { + return -1; + } + return span().find(p_val, p_from); + } + Size rfind(const T &p_val, Size p_from = -1) const { + if (p_from < 0) { + p_from = size() + p_from; + } + if (p_from < 0 || p_from >= size()) { + return -1; + } + return span().rfind(p_val, p_from); + } Size count(const T &p_val) const { return span().count(p_val); } // Must take a copy instead of a reference (see GH-31736).