Attempt to fully implement CharString

(cherry picked from commit 4df112cd95)
This commit is contained in:
David Snopek
2023-06-20 10:03:15 -05:00
parent 1009da4d7e
commit 011965d864
6 changed files with 208 additions and 166 deletions

View File

@@ -31,82 +31,99 @@
#ifndef GODOT_CHAR_STRING_HPP
#define GODOT_CHAR_STRING_HPP
#include <godot_cpp/templates/cowdata.hpp>
#include <cstddef>
#include <cstdint>
namespace godot {
class CharString {
friend class String;
template <class T>
class CharStringT;
const char *_data = nullptr;
int _length = 0;
template <class T>
class CharProxy {
template <class TS>
friend class CharStringT;
CharString(const char *str, int length);
const int _index;
CowData<T> &_cowdata;
static inline const T _null = 0;
_FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) :
_index(p_index),
_cowdata(p_cowdata) {}
public:
int length() const;
const char *get_data() const;
_FORCE_INLINE_ CharProxy(const CharProxy<T> &p_other) :
_index(p_other._index),
_cowdata(p_other._cowdata) {}
CharString(CharString &&p_str);
void operator=(CharString &&p_str);
CharString() {}
~CharString();
_FORCE_INLINE_ operator T() const {
if (unlikely(_index == _cowdata.size())) {
return _null;
}
return _cowdata.get(_index);
}
_FORCE_INLINE_ const T *operator&() const {
return _cowdata.ptr() + _index;
}
_FORCE_INLINE_ void operator=(const T &p_other) const {
_cowdata.set(_index, p_other);
}
_FORCE_INLINE_ void operator=(const CharProxy<T> &p_other) const {
_cowdata.set(_index, p_other.operator T());
}
};
class Char16String {
template <class T>
class CharStringT {
friend class String;
const char16_t *_data = nullptr;
int _length = 0;
Char16String(const char16_t *str, int length);
CowData<T> _cowdata;
static inline const T _null = 0;
public:
int length() const;
const char16_t *get_data() const;
_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); }
Char16String(Char16String &&p_str);
void operator=(Char16String &&p_str);
Char16String() {}
~Char16String();
_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<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); }
void operator=(const T *p_cstr);
bool operator<(const CharStringT<T> &p_right) const;
CharStringT<T> &operator+=(T p_char);
int length() const { return size() ? size() - 1 : 0; }
const T *get_data() const;
operator const T *() const { return get_data(); };
protected:
void copy_from(const T *p_cstr);
};
class Char32String {
friend class String;
const char32_t *_data = nullptr;
int _length = 0;
Char32String(const char32_t *str, int length);
public:
int length() const;
const char32_t *get_data() const;
Char32String(Char32String &&p_str);
void operator=(Char32String &&p_str);
Char32String() {}
~Char32String();
};
class CharWideString {
friend class String;
const wchar_t *_data = nullptr;
int _length = 0;
CharWideString(const wchar_t *str, int length);
public:
int length() const;
const wchar_t *get_data() const;
CharWideString(CharWideString &&p_str);
void operator=(CharWideString &&p_str);
CharWideString() {}
~CharWideString();
};
typedef CharStringT<char> CharString;
typedef CharStringT<char16_t> Char16String;
typedef CharStringT<char32_t> Char32String;
typedef CharStringT<wchar_t> CharWideString;
} // namespace godot