Selaa lähdekoodia

Merge pull request #98439 from Repiteo/core/charstringt

Core: Integrate `CharStringT`
Thaddeus Crews 4 kuukautta sitten
vanhempi
commit
ac073c64dc
2 muutettua tiedostoa jossa 92 lisäystä ja 220 poistoa
  1. 0 134
      core/string/ustring.cpp
  2. 92 86
      core/string/ustring.h

+ 0 - 134
core/string/ustring.cpp

@@ -57,11 +57,6 @@ static _FORCE_INLINE_ char32_t lower_case(char32_t c) {
 	return (is_ascii_upper_case(c) ? (c + ('a' - 'A')) : c);
 }
 
-const char CharString::_null = 0;
-const char16_t Char16String::_null = 0;
-const char32_t String::_null = 0;
-const char32_t String::_replacement_char = 0xfffd;
-
 bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
 	const String &s = p_s;
 	int beg = CLAMP(p_col, 0, s.length());
@@ -90,135 +85,6 @@ bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
 	}
 }
 
-/*************************************************************************/
-/*  Char16String                                                         */
-/*************************************************************************/
-
-bool Char16String::operator<(const Char16String &p_right) const {
-	if (length() == 0) {
-		return p_right.length() != 0;
-	}
-
-	return str_compare(get_data(), p_right.get_data()) < 0;
-}
-
-Char16String &Char16String::operator+=(char16_t p_char) {
-	const int lhs_len = length();
-	resize(lhs_len + 2);
-
-	char16_t *dst = ptrw();
-	dst[lhs_len] = p_char;
-	dst[lhs_len + 1] = 0;
-
-	return *this;
-}
-
-void Char16String::operator=(const char16_t *p_cstr) {
-	copy_from(p_cstr);
-}
-
-const char16_t *Char16String::get_data() const {
-	if (size()) {
-		return &operator[](0);
-	} else {
-		return u"";
-	}
-}
-
-void Char16String::copy_from(const char16_t *p_cstr) {
-	if (!p_cstr) {
-		resize(0);
-		return;
-	}
-
-	const char16_t *s = p_cstr;
-	for (; *s; s++) {
-	}
-	size_t len = s - p_cstr;
-
-	if (len == 0) {
-		resize(0);
-		return;
-	}
-
-	Error err = resize(++len); // include terminating null char
-
-	ERR_FAIL_COND_MSG(err != OK, "Failed to copy char16_t string.");
-
-	memcpy(ptrw(), p_cstr, len * sizeof(char16_t));
-}
-
-/*************************************************************************/
-/*  CharString                                                           */
-/*************************************************************************/
-
-bool CharString::operator<(const CharString &p_right) const {
-	if (length() == 0) {
-		return p_right.length() != 0;
-	}
-
-	return str_compare(get_data(), p_right.get_data()) < 0;
-}
-
-bool CharString::operator==(const CharString &p_right) const {
-	if (length() == 0) {
-		// True if both have length 0, false if only p_right has a length
-		return p_right.length() == 0;
-	} else if (p_right.length() == 0) {
-		// False due to unequal length
-		return false;
-	}
-
-	return strcmp(ptr(), p_right.ptr()) == 0;
-}
-
-CharString &CharString::operator+=(char p_char) {
-	const int lhs_len = length();
-	resize(lhs_len + 2);
-
-	char *dst = ptrw();
-	dst[lhs_len] = p_char;
-	dst[lhs_len + 1] = 0;
-
-	return *this;
-}
-
-void CharString::operator=(const char *p_cstr) {
-	copy_from(p_cstr);
-}
-
-const char *CharString::get_data() const {
-	if (size()) {
-		return &operator[](0);
-	} else {
-		return "";
-	}
-}
-
-void CharString::copy_from(const char *p_cstr) {
-	if (!p_cstr) {
-		resize(0);
-		return;
-	}
-
-	size_t len = strlen(p_cstr);
-
-	if (len == 0) {
-		resize(0);
-		return;
-	}
-
-	Error err = resize(++len); // include terminating null char
-
-	ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string.");
-
-	memcpy(ptrw(), p_cstr, len);
-}
-
-/*************************************************************************/
-/*  String                                                               */
-/*************************************************************************/
-
 Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const {
 	// Splits the URL into scheme, host, port, path, fragment. Strip credentials when present.
 	String base = *this;

+ 92 - 86
core/string/ustring.h

@@ -38,6 +38,10 @@
 #include "core/typedefs.h"
 #include "core/variant/array.h"
 
+class String;
+template <typename T>
+class CharStringT;
+
 /*************************************************************************/
 /*  Utility Functions                                                    */
 /*************************************************************************/
@@ -97,19 +101,33 @@ constexpr size_t _strlen_clipped(const char32_t *p_str, int p_clip_to_len) {
 	return len;
 }
 
+template <typename L, typename R>
+constexpr int64_t str_compare(const L *l_ptr, const R *r_ptr) {
+	while (true) {
+		const char32_t l = *l_ptr;
+		const char32_t r = *r_ptr;
+
+		if (l == 0 || l != r) {
+			return static_cast<int64_t>(l) - static_cast<int64_t>(r);
+		}
+
+		l_ptr++;
+		r_ptr++;
+	}
+}
+
 /*************************************************************************/
 /*  CharProxy                                                            */
 /*************************************************************************/
 
 template <typename T>
 class CharProxy {
-	friend class Char16String;
-	friend class CharString;
-	friend class String;
+	friend String;
+	friend CharStringT<T>;
 
 	const int _index;
 	CowData<T> &_cowdata;
-	static const T _null = 0;
+	static constexpr T _null = 0;
 
 	_FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) :
 			_index(p_index),
@@ -142,97 +160,100 @@ public:
 };
 
 /*************************************************************************/
-/*  Char16String                                                         */
+/*  CharStringT                                                          */
 /*************************************************************************/
 
-class Char16String {
-	CowData<char16_t> _cowdata;
-	static const char16_t _null;
+template <typename T>
+class CharStringT {
+	CowData<T> _cowdata;
+	static constexpr T _null = 0;
 
 public:
-	_FORCE_INLINE_ char16_t *ptrw() { return _cowdata.ptrw(); }
-	_FORCE_INLINE_ const char16_t *ptr() const { return _cowdata.ptr(); }
+	_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
+	_FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
 	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
 
-	_FORCE_INLINE_ operator Span<char16_t>() const { return Span(ptr(), length()); }
-	_FORCE_INLINE_ Span<char16_t> span() const { return Span(ptr(), length()); }
+	_FORCE_INLINE_ operator Span<T>() const { return Span(ptr(), length()); }
+	_FORCE_INLINE_ Span<T> span() const { return Span(ptr(), length()); }
 
-	Error resize(int p_size) { return _cowdata.resize(p_size); }
+	_FORCE_INLINE_ Error resize(int p_size) { return _cowdata.resize(p_size); }
 
-	_FORCE_INLINE_ char16_t get(int p_index) const { return _cowdata.get(p_index); }
-	_FORCE_INLINE_ void set(int p_index, const char16_t &p_elem) { _cowdata.set(p_index, p_elem); }
-	_FORCE_INLINE_ const char16_t &operator[](int p_index) const {
+	_FORCE_INLINE_ T get(int p_index) const { return _cowdata.get(p_index); }
+	_FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
+	_FORCE_INLINE_ const T &operator[](int p_index) const {
 		if (unlikely(p_index == _cowdata.size())) {
 			return _null;
 		}
-
 		return _cowdata.get(p_index);
 	}
-	_FORCE_INLINE_ CharProxy<char16_t> operator[](int p_index) { return CharProxy<char16_t>(p_index, _cowdata); }
+	_FORCE_INLINE_ CharProxy<T> operator[](int p_index) { return CharProxy<T>(p_index, _cowdata); }
 
-	_FORCE_INLINE_ Char16String() {}
-	_FORCE_INLINE_ Char16String(const Char16String &p_str) = default;
-	_FORCE_INLINE_ Char16String(Char16String &&p_str) = default;
-	_FORCE_INLINE_ void operator=(const Char16String &p_str) { _cowdata = p_str._cowdata; }
-	_FORCE_INLINE_ void operator=(Char16String &&p_str) { _cowdata = std::move(p_str._cowdata); }
-	_FORCE_INLINE_ Char16String(const char16_t *p_cstr) { copy_from(p_cstr); }
+	_FORCE_INLINE_ CharStringT() = default;
+	_FORCE_INLINE_ CharStringT(const CharStringT &p_str) = default;
+	_FORCE_INLINE_ CharStringT(CharStringT &&p_str) = default;
+	_FORCE_INLINE_ void operator=(const CharStringT &p_str) { _cowdata = p_str._cowdata; }
+	_FORCE_INLINE_ void operator=(CharStringT &&p_str) { _cowdata = std::move(p_str._cowdata); }
+	_FORCE_INLINE_ CharStringT(const T *p_cstr) { copy_from(p_cstr); }
+	_FORCE_INLINE_ void operator=(const T *p_cstr) { copy_from(p_cstr); }
 
-	void operator=(const char16_t *p_cstr);
-	bool operator<(const Char16String &p_right) const;
-	Char16String &operator+=(char16_t p_char);
-	int length() const { return size() ? size() - 1 : 0; }
-	const char16_t *get_data() const;
+	_FORCE_INLINE_ bool operator==(const CharStringT<T> &p_other) const {
+		if (length() != p_other.length()) {
+			return false;
+		}
+		return memcmp(ptr(), p_other.ptr(), length() * sizeof(T)) == 0;
+	}
+	_FORCE_INLINE_ bool operator!=(const CharStringT<T> &p_other) const { return !(*this == p_other); }
+	_FORCE_INLINE_ bool operator<(const CharStringT<T> &p_other) const {
+		if (length() == 0) {
+			return p_other.length() != 0;
+		}
+		return str_compare(get_data(), p_other.get_data()) < 0;
+	}
+	_FORCE_INLINE_ CharStringT<T> &operator+=(T p_char) {
+		const int lhs_len = length();
+		resize(lhs_len + 2);
 
-protected:
-	void copy_from(const char16_t *p_cstr);
-};
+		T *dst = ptrw();
+		dst[lhs_len] = p_char;
+		dst[lhs_len + 1] = _null;
 
-/*************************************************************************/
-/*  CharString                                                           */
-/*************************************************************************/
+		return *this;
+	}
 
-class CharString {
-	CowData<char> _cowdata;
-	static const char _null;
+	_FORCE_INLINE_ int length() const { return size() ? size() - 1 : 0; }
+	_FORCE_INLINE_ const T *get_data() const {
+		if (size()) {
+			return &operator[](0);
+		}
+		return &_null;
+	}
 
-public:
-	_FORCE_INLINE_ char *ptrw() { return _cowdata.ptrw(); }
-	_FORCE_INLINE_ const char *ptr() const { return _cowdata.ptr(); }
-	_FORCE_INLINE_ int size() const { return _cowdata.size(); }
+protected:
+	void copy_from(const T *p_cstr) {
+		if (!p_cstr) {
+			resize(0);
+			return;
+		}
 
-	_FORCE_INLINE_ operator Span<char>() const { return Span(ptr(), length()); }
-	_FORCE_INLINE_ Span<char> span() const { return Span(ptr(), length()); }
+		size_t len = strlen(p_cstr);
+		if (len == 0) {
+			resize(0);
+			return;
+		}
 
-	Error resize(int p_size) { return _cowdata.resize(p_size); }
+		Error err = resize(++len); // include terminating null char.
 
-	_FORCE_INLINE_ char get(int p_index) const { return _cowdata.get(p_index); }
-	_FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
-	_FORCE_INLINE_ const char &operator[](int p_index) const {
-		if (unlikely(p_index == _cowdata.size())) {
-			return _null;
-		}
+		ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string.");
 
-		return _cowdata.get(p_index);
+		memcpy(ptrw(), p_cstr, len * sizeof(T));
 	}
-	_FORCE_INLINE_ CharProxy<char> operator[](int p_index) { return CharProxy<char>(p_index, _cowdata); }
-
-	_FORCE_INLINE_ CharString() {}
-	_FORCE_INLINE_ CharString(const CharString &p_str) = default;
-	_FORCE_INLINE_ CharString(CharString &&p_str) = default;
-	_FORCE_INLINE_ void operator=(const CharString &p_str) { _cowdata = p_str._cowdata; }
-	_FORCE_INLINE_ void operator=(CharString &&p_str) { _cowdata = std::move(p_str._cowdata); }
-	_FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
+};
 
-	void operator=(const char *p_cstr);
-	bool operator<(const CharString &p_right) const;
-	bool operator==(const CharString &p_right) const;
-	CharString &operator+=(char p_char);
-	int length() const { return size() ? size() - 1 : 0; }
-	const char *get_data() const;
+template <typename T>
+struct is_zero_constructible<CharStringT<T>> : std::true_type {};
 
-protected:
-	void copy_from(const char *p_cstr);
-};
+using CharString = CharStringT<char>;
+using Char16String = CharStringT<char16_t>;
 
 /*************************************************************************/
 /*  String                                                               */
@@ -240,8 +261,8 @@ protected:
 
 class String {
 	CowData<char32_t> _cowdata;
-	static const char32_t _null;
-	static const char32_t _replacement_char;
+	static constexpr char32_t _null = 0;
+	static constexpr char32_t _replacement_char = 0xfffd;
 
 	// Known-length copy.
 	void copy_from_unchecked(const char32_t *p_char, int p_length);
@@ -684,21 +705,6 @@ struct FileNoCaseComparator {
 	}
 };
 
-template <typename L, typename R>
-_FORCE_INLINE_ int64_t str_compare(const L *l_ptr, const R *r_ptr) {
-	while (true) {
-		const char32_t l = *l_ptr;
-		const char32_t r = *r_ptr;
-
-		if (l == 0 || l != r) {
-			return static_cast<int64_t>(l) - static_cast<int64_t>(r);
-		}
-
-		l_ptr++;
-		r_ptr++;
-	}
-}
-
 /* end of namespace */
 
 // Tool translate (TTR and variants) for the editor UI,