Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Integrate CharStringT #98439

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 32 additions & 90 deletions core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,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;

Expand Down Expand Up @@ -93,118 +91,61 @@ 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 {
template <typename T>
bool CharStringT<T>::operator<(const CharStringT<T> &p_other) const {
if (length() == 0) {
return p_right.length() != 0;
return p_other.length() != 0;
}

return is_str_less(get_data(), p_right.get_data());
}

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;
return is_str_less(get_data(), p_other.get_data());
}

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;
template <typename T>
bool CharStringT<T>::operator==(const CharStringT<T> &p_other) const {
if (length() != p_other.length()) {
return false;
}

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 true;
}

return is_str_less(get_data(), p_right.get_data());
}
size_t len = length();
const T *src = get_data();
const T *dst = p_other.get_data();

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;
/* Compare char by char */
for (size_t i = 0; i < len; i++) {
if (src[i] != dst[i]) {
return false;
}
}

return strcmp(ptr(), p_right.ptr()) == 0;
return true;
}

CharString &CharString::operator+=(char p_char) {
template <typename T>
CharStringT<T> &CharStringT<T>::operator+=(T p_char) {
const int lhs_len = length();
resize(lhs_len + 2);

char *dst = ptrw();
T *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) {
template <typename T>
void CharStringT<T>::copy_from(const T *p_cstr) {
if (!p_cstr) {
resize(0);
return;
}

size_t len = strlen(p_cstr);
const T *s = p_cstr;
for (; *s; s++) {
} // Iterate until null char reached.
size_t len = s - p_cstr;

if (len == 0) {
resize(0);
Expand All @@ -215,12 +156,13 @@ void CharString::copy_from(const char *p_cstr) {

ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string.");

memcpy(ptrw(), p_cstr, len);
memcpy(ptrw(), p_cstr, len * sizeof(T));
}

/*************************************************************************/
/* String */
/*************************************************************************/
template class CharStringT<char>;
template class CharStringT<char16_t>;
template class CharStringT<char32_t>;
template class CharStringT<wchar_t>;

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.
Expand Down
116 changes: 41 additions & 75 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@
#include "core/typedefs.h"
#include "core/variant/array.h"

/*************************************************************************/
/* CharProxy */
/*************************************************************************/
class String;
template <typename T>
class CharStringT;

template <typename T>
class CharProxy {
friend class Char16String;
friend class CharString;
friend class String;
template <typename TS>
friend class CharStringT;

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),
Expand Down Expand Up @@ -83,92 +83,58 @@ class CharProxy {
}
};

/*************************************************************************/
/* Char16String */
/*************************************************************************/
template <typename T>
class CharStringT {
friend class String;

class Char16String {
CowData<char16_t> _cowdata;
static const char16_t _null;
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(); }
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_ Char16String() {}
_FORCE_INLINE_ Char16String(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ void operator=(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ Char16String(const char16_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;
operator const char16_t *() const { return get_data(); }

protected:
void copy_from(const char16_t *p_cstr);
};

/*************************************************************************/
/* CharString */
/*************************************************************************/

class CharString {
CowData<char> _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(); }
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;
_FORCE_INLINE_ CharProxy<T> operator[](int p_index) { return CharProxy<T>(p_index, _cowdata); }

_FORCE_INLINE_ CharStringT() {}
_FORCE_INLINE_ CharStringT(const CharStringT<T> &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ void operator=(const CharStringT<T> &p_str) { _cowdata._ref(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); }

bool operator==(const CharStringT<T> &p_other) const;
_FORCE_INLINE_ bool operator!=(const CharStringT<T> &p_other) const { return !(*this == p_other); }
bool operator<(const CharStringT<T> &p_other) const;
CharStringT<T> &operator+=(T p_char);

_FORCE_INLINE_ int length() const { return size() ? size() - 1 : 0; }
_FORCE_INLINE_ const T *get_data() const {
if (size()) {
return &operator[](0);
}

return _cowdata.get(p_index);
return &_null;
}
_FORCE_INLINE_ CharProxy<char> operator[](int p_index) { return CharProxy<char>(p_index, _cowdata); }

_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ void operator=(const CharString &p_str) { _cowdata._ref(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;
operator const char *() const { return get_data(); }
_FORCE_INLINE_ operator const T *() const { return get_data(); }

protected:
void copy_from(const char *p_cstr);
void copy_from(const T *p_cstr);
};

/*************************************************************************/
/* String */
/*************************************************************************/
using CharString = CharStringT<char>;
using Char16String = CharStringT<char16_t>;
using Char32String = CharStringT<char32_t>;
using CharWideString = CharStringT<wchar_t>;

struct StrRange {
const char32_t *c_str;
Expand Down
8 changes: 4 additions & 4 deletions core/templates/cowdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
template <typename T>
class Vector;
class String;
class Char16String;
class CharString;
template <typename T>
class CharStringT;
template <typename T, typename V>
class VMap;

Expand All @@ -59,8 +59,8 @@ class CowData {
template <typename TV>
friend class Vector;
friend class String;
friend class Char16String;
friend class CharString;
template <typename TS>
friend class CharStringT;
template <typename TV, typename VV>
friend class VMap;

Expand Down
Loading