#ifndef CORE_STRING_H #define CORE_STRING_H #include "utils/Check.h" #include "utils/Types.h" #include "utils/Utility.h" namespace Core { class String final { int length; Hash hash; static constexpr int DATA_LENGTH = (1024 - (sizeof(length) >= sizeof(hash) ? sizeof(length) * 2 : sizeof(hash) * 2)) / sizeof(u32); u32 data[DATA_LENGTH]; public: String(); template String(const T& t) : String() { append(t); } bool operator==(const char* s) const; bool operator==(const String& other) const; bool operator!=(const char* s) const; bool operator!=(const String& other) const; u32 operator[](int index) const; int getLength() const; String& append(char c); String& append(signed char c); String& append(unsigned char c); String& append(const char* s); String& append(const signed char* s); String& append(const unsigned char* s); String& append(signed short s); String& append(unsigned short s); String& append(signed int i); String& append(unsigned int i); String& append(signed long l); String& append(unsigned long l); String& append(signed long long ll); String& append(unsigned long long ll); String& append(float f); String& append(double d); String& append(long double ld); String& append(bool b); String& appendUnicode(u32 c); check_format(2, 3) String& appendFormat(const char* format, ...); template String& append(const T& t) { t.toString(*this); return *this; } void toString(String& s) const; String& clear(); Hash hashCode() const; void print() const; void printLine() const; template static String format(const String& format, Args&&... args) { String s; formatBuffer(s, 0, format, Core::forward(args)...); return s; } private: void addToHash(u32 u); template static void formatBuffer(String& s, int index, const String& format, const T& t, Args&&... args) { while(index < format.getLength()) { u32 u = format[index++]; if(u == '#') { if(index < format.getLength() && format[index] != '#') { break; } index++; } s.appendUnicode(u); } s.append(t); formatBuffer(s, index, format, Core::forward(args)...); } static void formatBuffer(String& s, int index, const String& format) { while(index < format.getLength()) { s.appendUnicode(format[index++]); } } }; } static_assert(sizeof(Core::String) == 1024, "String should have a size of 1024 byte"); bool operator==(const char* cs, const Core::String& s); bool operator!=(const char* cs, const Core::String& s); #endif