From 999294d77aa2a2b70997323ae55cf36310ca148e Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Tue, 22 Oct 2024 17:08:05 -0500 Subject: [PATCH] Core: Integrate `CharStringT` --- core/string/ustring.cpp | 134 ---------------------------- core/string/ustring.h | 188 +++++++++++++++++++++------------------- 2 files changed, 97 insertions(+), 225 deletions(-) diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c2f6c3b45c..cad7d9a834 100644 --- a/core/string/ustring.cpp +++ b/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; diff --git a/core/string/ustring.h b/core/string/ustring.h index 7ecf130879..2a006de8d1 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -38,6 +38,10 @@ #include "core/typedefs.h" #include "core/variant/array.h" +class String; +template +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 +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(l) - static_cast(r); + } + + l_ptr++; + r_ptr++; + } +} + /*************************************************************************/ /* CharProxy */ /*************************************************************************/ template class CharProxy { - friend class Char16String; - friend class CharString; - friend class String; + friend String; + friend CharStringT; const int _index; CowData &_cowdata; - static const T _null = 0; + static constexpr T _null = 0; _FORCE_INLINE_ CharProxy(const int &p_index, CowData &p_cowdata) : _index(p_index), @@ -142,106 +160,109 @@ public: }; /*************************************************************************/ -/* Char16String */ +/* CharStringT */ /*************************************************************************/ -class Char16String { - CowData _cowdata; - static const char16_t _null; +template +class CharStringT { + CowData _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() const { return Span(ptr(), length()); } - _FORCE_INLINE_ Span span() const { return Span(ptr(), length()); } + _FORCE_INLINE_ operator Span() const { return Span(ptr(), length()); } + _FORCE_INLINE_ Span 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 operator[](int p_index) { return CharProxy(p_index, _cowdata); } + _FORCE_INLINE_ CharProxy operator[](int p_index) { return CharProxy(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 &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 &p_other) const { return !(*this == p_other); } + _FORCE_INLINE_ bool operator<(const CharStringT &p_other) const { + if (length() == 0) { + return p_other.length() != 0; + } + return str_compare(get_data(), p_other.get_data()) < 0; + } + _FORCE_INLINE_ CharStringT &operator+=(T p_char) { + const int lhs_len = length(); + resize(lhs_len + 2); + + T *dst = ptrw(); + dst[lhs_len] = p_char; + dst[lhs_len + 1] = _null; + + return *this; + } + + _FORCE_INLINE_ int length() const { return size() ? size() - 1 : 0; } + _FORCE_INLINE_ const T *get_data() const { + if (size()) { + return &operator[](0); + } + return &_null; + } protected: - void copy_from(const char16_t *p_cstr); -}; - -/*************************************************************************/ -/* CharString */ -/*************************************************************************/ - -class CharString { - CowData _cowdata; - static const char _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(); } - - _FORCE_INLINE_ operator Span() const { return Span(ptr(), length()); } - _FORCE_INLINE_ Span span() const { return Span(ptr(), length()); } - - Error resize(int p_size) { return _cowdata.resize(p_size); } - - _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; + void copy_from(const T *p_cstr) { + if (!p_cstr) { + resize(0); + return; } - return _cowdata.get(p_index); + 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 * sizeof(T)); } - _FORCE_INLINE_ CharProxy operator[](int p_index) { return CharProxy(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; - -protected: - void copy_from(const char *p_cstr); }; +template +struct is_zero_constructible> : std::true_type {}; + +using CharString = CharStringT; +using Char16String = CharStringT; + /*************************************************************************/ /* String */ /*************************************************************************/ class String { CowData _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 -_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(l) - static_cast(r); - } - - l_ptr++; - r_ptr++; - } -} - /* end of namespace */ // Tool translate (TTR and variants) for the editor UI,