Merge pull request #1150 from dsnopek/charstring-full

Attempt to fully implement CharString
This commit is contained in:
David Snopek
2023-07-22 09:04:27 -05:00
committed by GitHub
6 changed files with 208 additions and 166 deletions

View File

@@ -38,117 +38,121 @@
#include <godot_cpp/godot.hpp>
#include <cmath>
#include <string>
namespace godot {
int CharString::length() const {
return _length;
}
template <typename L, typename R>
_FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) {
while (true) {
const char32_t l = *l_ptr;
const char32_t r = *r_ptr;
const char *CharString::get_data() const {
return _data;
}
if (l == 0 && r == 0) {
return false;
} else if (l == 0) {
return true;
} else if (r == 0) {
return false;
} else if (l < r) {
return true;
} else if (l > r) {
return false;
}
CharString::CharString(CharString &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
void CharString::operator=(CharString &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
CharString::CharString(const char *str, int length) :
_data(str), _length(length) {}
CharString::~CharString() {
if (_data != nullptr) {
memdelete_arr(_data);
l_ptr++;
r_ptr++;
}
}
int Char16String::length() const {
return _length;
template <class T>
bool CharStringT<T>::operator<(const CharStringT<T> &p_right) const {
if (length() == 0) {
return p_right.length() != 0;
}
return is_str_less(get_data(), p_right.get_data());
}
const char16_t *Char16String::get_data() const {
return _data;
template <class T>
CharStringT<T> &CharStringT<T>::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] = 0;
return *this;
}
Char16String::Char16String(Char16String &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
template <class T>
void CharStringT<T>::operator=(const T *p_cstr) {
copy_from(p_cstr);
}
void Char16String::operator=(Char16String &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
Char16String::Char16String(const char16_t *str, int length) :
_data(str), _length(length) {}
Char16String::~Char16String() {
if (_data != nullptr) {
memdelete_arr(_data);
template <>
const char *CharStringT<char>::get_data() const {
if (size()) {
return &operator[](0);
} else {
return "";
}
}
int Char32String::length() const {
return _length;
}
const char32_t *Char32String::get_data() const {
return _data;
}
Char32String::Char32String(Char32String &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
void Char32String::operator=(Char32String &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
Char32String::Char32String(const char32_t *str, int length) :
_data(str), _length(length) {}
Char32String::~Char32String() {
if (_data != nullptr) {
memdelete_arr(_data);
template <>
const char16_t *CharStringT<char16_t>::get_data() const {
if (size()) {
return &operator[](0);
} else {
return u"";
}
}
int CharWideString::length() const {
return _length;
}
const wchar_t *CharWideString::get_data() const {
return _data;
}
CharWideString::CharWideString(CharWideString &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
void CharWideString::operator=(CharWideString &&p_str) {
SWAP(_length, p_str._length);
SWAP(_data, p_str._data);
}
CharWideString::CharWideString(const wchar_t *str, int length) :
_data(str), _length(length) {}
CharWideString::~CharWideString() {
if (_data != nullptr) {
memdelete_arr(_data);
template <>
const char32_t *CharStringT<char32_t>::get_data() const {
if (size()) {
return &operator[](0);
} else {
return U"";
}
}
template <>
const wchar_t *CharStringT<wchar_t>::get_data() const {
if (size()) {
return &operator[](0);
} else {
return L"";
}
}
template <class T>
void CharStringT<T>::copy_from(const T *p_cstr) {
if (!p_cstr) {
resize(0);
return;
}
size_t len = std::char_traits<T>::length(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);
}
template class CharStringT<char>;
template class CharStringT<char16_t>;
template class CharStringT<char32_t>;
template class CharStringT<wchar_t>;
// Custom String functions that are not part of bound API.
// It's easier to have them written in C++ directly than in a Python script that generates them.
@@ -228,56 +232,61 @@ String rtoss(double p_val) {
CharString String::utf8() const {
int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char *cstr = memnew_arr(char, size);
internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), cstr, length);
CharString str;
str.resize(size);
internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), str.ptrw(), length);
cstr[length] = '\0';
str[length] = '\0';
return CharString(cstr, length);
return str;
}
CharString String::ascii() const {
int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char *cstr = memnew_arr(char, size);
internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), cstr, length);
CharString str;
str.resize(size);
internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), str.ptrw(), length);
cstr[length] = '\0';
str[length] = '\0';
return CharString(cstr, length);
return str;
}
Char16String String::utf16() const {
int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char16_t *cstr = memnew_arr(char16_t, size);
internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), cstr, length);
Char16String str;
str.resize(size);
internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), str.ptrw(), length);
cstr[length] = '\0';
str[length] = '\0';
return Char16String(cstr, length);
return str;
}
Char32String String::utf32() const {
int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
char32_t *cstr = memnew_arr(char32_t, size);
internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), cstr, length);
Char32String str;
str.resize(size);
internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), str.ptrw(), length);
cstr[length] = '\0';
str[length] = '\0';
return Char32String(cstr, length);
return str;
}
CharWideString String::wide_string() const {
int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
int size = length + 1;
wchar_t *cstr = memnew_arr(wchar_t, size);
internal::gdextension_interface_string_to_wide_chars(_native_ptr(), cstr, length);
CharWideString str;
str.resize(size);
internal::gdextension_interface_string_to_wide_chars(_native_ptr(), str.ptrw(), length);
cstr[length] = '\0';
str[length] = '\0';
return CharWideString(cstr, length);
return str;
}
String &String::operator=(const char *p_str) {