Harmonize String, Vector and LocalVector find and rfind.

Use `Span::find` for `LocalVector::find`, accepting negative `p_from`.
Return `-1` for invalid `p_from` values in `rfind`.
Accept negative values for `p_from` in `find`, starting from the back.
This commit is contained in:
Lukas Tenbrink 2025-03-17 20:37:46 +01:00
parent 9e6ee9c5c3
commit fde71e0382
4 changed files with 42 additions and 26 deletions

View File

@ -3329,6 +3329,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);
}
@ -3566,6 +3572,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);
}

View File

@ -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 {

View File

@ -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 <typename T>
constexpr int64_t Span<T>::find(const T &p_val, int64_t p_from) const {
if (p_from < 0 || size() == 0) {
return -1;
}
constexpr int64_t Span<T>::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 <typename T>
constexpr int64_t Span<T>::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<T>::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;

View File

@ -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).