123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #ifndef CORE_ARRAY_STRING_HPP
- #define CORE_ARRAY_STRING_HPP
- #include "core/math/Math.hpp"
- #include "core/utils/Check.hpp"
- #include "core/utils/Error.hpp"
- #include "core/utils/Meta.hpp"
- #include "core/utils/Types.hpp"
- #include "core/utils/Utility.hpp"
- namespace Core {
- namespace Internal {
- template<typename String, typename T>
- CError genericAppend(String& s, const T& t) {
- if constexpr(requires { t.toString(s); }) {
- return t.toString(s);
- } else {
- char buffer[64];
- CORE_RETURN_ERROR(toString(t, buffer, CORE_SIZE(buffer)));
- return s.append(static_cast<const char*>(buffer));
- }
- }
- template<typename S, typename T, typename... Args>
- CError formatR(const S& f, S& s, int index, const T& t,
- Args&&... args) {
- i32 l = f.getLength();
- while(index < l) {
- auto u = f[index++];
- if(u == '#') {
- if(index >= l || f[index] != '#') {
- break;
- }
- index++;
- }
- CORE_RETURN_ERROR(s.append(u));
- }
- CORE_RETURN_ERROR(s.append(t));
- if constexpr(sizeof...(args) > 0) {
- return formatR(f, s, index, forward<Args>(args)...);
- }
- while(index < f.getLength()) {
- CORE_RETURN_ERROR(s.append(f[index++]));
- }
- return Error::NONE;
- }
- }
- template<typename String, typename... Args>
- CError copyFormat(String& result, String& s, Args&&... args) {
- if constexpr(sizeof...(args) > 0) {
- Error e = Internal::formatR(result, s, 0, forward<Args>(args)...);
- if(e == Error::NONE) {
- return result.copyFrom(s);
- } else if(e == Error::CAPACITY_REACHED) {
- (void)result.copyFrom(s);
- }
- return e;
- }
- return Error::NONE;
- }
- class Char32String;
- class CharString {
- protected:
- i32 length;
- i32 capacity;
- u32 hash;
- char* data;
- public:
- CharString(char* buffer, i32 bufferSize);
- CharString(const CharString&) = delete;
- CharString& operator=(const CharString&) = delete;
- CError copyFrom(const CharString& s);
- bool operator==(const char* s) const;
- bool operator==(const CharString& other) const;
- bool operator!=(const char* s) const;
- bool operator!=(const CharString& other) const;
- char operator[](int index) const;
- int getLength() const;
- int getCapacity() const;
- CError append(char c);
- CError append(signed char c);
- CError append(unsigned char c);
- CError append(wchar_t c);
- CError append(c32 c);
- CError append(const char* s);
- CError append(const c32* s);
- CError append(const signed char* s);
- CError append(const unsigned char* s);
- CError append(bool b);
- CError append(Error e);
- template<typename T>
- CError append(const T& t) {
- return Internal::genericAppend(*this, t);
- }
- CError toString(CharString& s) const;
- CError toString(Char32String& s) const;
- void clear();
- u32 hashCode() const;
- CError print() const;
- CError printLine() const;
- template<typename... Args>
- CError format(CharString& s, Args&&... args) {
- return copyFormat(*this, s, Core::forward<Args>(args)...);
- }
- bool startsWidth(const CharString& other, int from = 0) const;
- int search(const CharString& other, int from = 0) const;
- bool contains(const CharString& other, int from = 0) const;
- int search(char u, int from = 0) const;
- bool contains(char u, int from = 0) const;
- CError substring(CharString& s, int from, int to) const;
- CError substring(CharString& s, int from = 0) const;
- CError replace(CharString& s, const CharString& search,
- const CharString& replace);
- void replace(char search, char replace);
- operator const char*() const;
- private:
- void addToHash(c32 u);
- };
- class Char32String {
- protected:
- i32 length;
- i32 capacity;
- u32 hash;
- c32* data;
- public:
- Char32String(c32* buffer, i32 bufferSize);
- Char32String(const Char32String&) = delete;
- Char32String& operator=(const Char32String&) = delete;
- Error copyFrom(const Char32String& s);
- bool operator==(const c32* s) const;
- bool operator==(const Char32String& other) const;
- bool operator!=(const c32* s) const;
- bool operator!=(const Char32String& other) const;
- c32 operator[](int index) const;
- int getLength() const;
- int getCapacity() const;
- CError append(char c);
- CError append(signed char c);
- CError append(unsigned char c);
- CError append(wchar_t c);
- CError append(c32 c);
- CError append(const char* s);
- CError append(const c32* s);
- CError append(const signed char* s);
- CError append(const unsigned char* s);
- CError append(bool b);
- CError append(Error e);
- template<typename T>
- CError append(const T& t) {
- return Internal::genericAppend(*this, t);
- }
- CError toString(CharString& s) const;
- CError toString(Char32String& s) const;
- void clear();
- u32 hashCode() const;
- CError print() const;
- CError printLine() const;
- template<typename... Args>
- CError format(Char32String& s, Args&&... args) {
- return copyFormat(*this, s, Core::forward<Args>(args)...);
- }
- bool startsWidth(const Char32String& other, int from = 0) const;
- int search(const Char32String& other, int from = 0) const;
- bool contains(const Char32String& other, int from = 0) const;
- int search(c32 u, int from = 0) const;
- bool contains(c32 u, int from = 0) const;
- CError substring(Char32String& s, int from, int to) const;
- CError substring(Char32String& s, int from = 0) const;
- CError replace(Char32String& s, const Char32String& search,
- const Char32String& replace);
- void replace(c32 search, c32 replace);
- operator const c32*() const;
- private:
- void addToHash(c32 u);
- };
- template<int N, typename C, typename B>
- class ArrayString final : public B {
- static_assert(N > 0, "size of array string must be positive");
- C data[static_cast<unsigned int>(N)];
- public:
- ArrayString() : B(data, N) {
- }
- ArrayString(const ArrayString& other) : B(data, N) {
- Core::memoryCopy(data, other.data, sizeof(data));
- B::length = other.length;
- B::hash = other.hash;
- }
- ArrayString& operator=(const ArrayString& other) {
- if(this != &other) {
- Core::memoryCopy(data, other.data, sizeof(data));
- B::length = other.length;
- B::hash = other.hash;
- }
- return *this;
- }
- template<typename... Args>
- CError format(Args&&... args) {
- ArrayString s;
- return B::format(s, Core::forward<Args>(args)...);
- }
- CError replace(const B& search, const B& replace) {
- ArrayString s;
- return B::replace(s, search, replace);
- }
- using B::replace;
- };
- template<typename String, typename Iterable>
- CError toString(String& s, const Iterable& i) {
- CORE_RETURN_ERROR(s.append("["));
- auto current = i.begin();
- auto end = i.end();
- while(current != end) {
- CORE_RETURN_ERROR(s.append(*current));
- ++current;
- if(current != end) {
- CORE_RETURN_ERROR(s.append(", "));
- }
- }
- return s.append("]");
- }
- template<int N>
- using String8 = ArrayString<N, char, CharString>;
- template<int N>
- using String32 = ArrayString<N, c32, Char32String>;
- }
- inline bool operator==(const c32* cs, const Core::Char32String& s) {
- return s == cs;
- }
- inline bool operator!=(const c32* cs, const Core::Char32String& s) {
- return s != cs;
- }
- inline bool operator==(const char* cs, const Core::CharString& s) {
- return s == cs;
- }
- inline bool operator!=(const char* cs, const Core::CharString& s) {
- return s != cs;
- }
- #endif
|