Просмотр исходного кода

Merge pull request #104286 from Ivorforce/localvector-find

Harmonize `String`, `Vector` and `LocalVector` `find` and `rfind`.
Rémi Verschelde 5 месяцев назад
Родитель
Сommit
64bd03269f
4 измененных файлов с 42 добавлено и 26 удалено
  1. 12 0
      core/string/ustring.cpp
  2. 7 6
      core/templates/local_vector.h
  3. 5 18
      core/templates/span.h
  4. 18 2
      core/templates/vector.h

+ 12 - 0
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);
 }
 

+ 7 - 6
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;
+		}
+		if (p_from < 0 || p_from >= size()) {
+			return -1;
 		}
-		return -1;
+		return span().find(p_val, p_from);
 	}
 
 	bool has(const T &p_val) const {

+ 5 - 18
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 <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;

+ 18 - 2
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).