ArrayString.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #ifndef CORE_ARRAY_STRING_HPP
  2. #define CORE_ARRAY_STRING_HPP
  3. #include "core/math/Math.hpp"
  4. #include "core/utils/Check.hpp"
  5. #include "core/utils/Error.hpp"
  6. #include "core/utils/Meta.hpp"
  7. #include "core/utils/Types.hpp"
  8. #include "core/utils/Utility.hpp"
  9. namespace Core {
  10. namespace Internal {
  11. template<typename String, typename T>
  12. CError genericAppend(String& s, const T& t) {
  13. if constexpr(requires { t.toString(s); }) {
  14. return t.toString(s);
  15. } else {
  16. char buffer[64];
  17. CORE_RETURN_ERROR(toString(t, buffer, CORE_SIZE(buffer)));
  18. return s.append(static_cast<const char*>(buffer));
  19. }
  20. }
  21. template<typename S, typename T, typename... Args>
  22. CError formatR(const S& f, S& s, int index, const T& t,
  23. Args&&... args) {
  24. i32 l = f.getLength();
  25. while(index < l) {
  26. auto u = f[index++];
  27. if(u == '#') {
  28. if(index >= l || f[index] != '#') {
  29. break;
  30. }
  31. index++;
  32. }
  33. CORE_RETURN_ERROR(s.append(u));
  34. }
  35. CORE_RETURN_ERROR(s.append(t));
  36. if constexpr(sizeof...(args) > 0) {
  37. return formatR(f, s, index, forward<Args>(args)...);
  38. }
  39. while(index < f.getLength()) {
  40. CORE_RETURN_ERROR(s.append(f[index++]));
  41. }
  42. return Error::NONE;
  43. }
  44. }
  45. template<typename String, typename... Args>
  46. CError copyFormat(String& result, String& s, Args&&... args) {
  47. if constexpr(sizeof...(args) > 0) {
  48. Error e = Internal::formatR(result, s, 0, forward<Args>(args)...);
  49. if(e == Error::NONE) {
  50. return result.copyFrom(s);
  51. } else if(e == Error::CAPACITY_REACHED) {
  52. (void)result.copyFrom(s);
  53. }
  54. return e;
  55. }
  56. return Error::NONE;
  57. }
  58. class Char32String;
  59. class CharString {
  60. protected:
  61. i32 length;
  62. i32 capacity;
  63. u32 hash;
  64. char* data;
  65. public:
  66. CharString(char* buffer, i32 bufferSize);
  67. CharString(const CharString&) = delete;
  68. CharString& operator=(const CharString&) = delete;
  69. CError copyFrom(const CharString& s);
  70. bool operator==(const char* s) const;
  71. bool operator==(const CharString& other) const;
  72. bool operator!=(const char* s) const;
  73. bool operator!=(const CharString& other) const;
  74. char operator[](int index) const;
  75. int getLength() const;
  76. int getCapacity() const;
  77. CError append(char c);
  78. CError append(signed char c);
  79. CError append(unsigned char c);
  80. CError append(wchar_t c);
  81. CError append(c32 c);
  82. CError append(const char* s);
  83. CError append(const c32* s);
  84. CError append(const signed char* s);
  85. CError append(const unsigned char* s);
  86. CError append(bool b);
  87. CError append(Error e);
  88. template<typename T>
  89. CError append(const T& t) {
  90. return Internal::genericAppend(*this, t);
  91. }
  92. CError toString(CharString& s) const;
  93. CError toString(Char32String& s) const;
  94. void clear();
  95. u32 hashCode() const;
  96. CError print() const;
  97. CError printLine() const;
  98. template<typename... Args>
  99. CError format(CharString& s, Args&&... args) {
  100. return copyFormat(*this, s, Core::forward<Args>(args)...);
  101. }
  102. bool startsWidth(const CharString& other, int from = 0) const;
  103. int search(const CharString& other, int from = 0) const;
  104. bool contains(const CharString& other, int from = 0) const;
  105. int search(char u, int from = 0) const;
  106. bool contains(char u, int from = 0) const;
  107. CError substring(CharString& s, int from, int to) const;
  108. CError substring(CharString& s, int from = 0) const;
  109. CError replace(CharString& s, const CharString& search,
  110. const CharString& replace);
  111. void replace(char search, char replace);
  112. operator const char*() const;
  113. private:
  114. void addToHash(c32 u);
  115. };
  116. class Char32String {
  117. protected:
  118. i32 length;
  119. i32 capacity;
  120. u32 hash;
  121. c32* data;
  122. public:
  123. Char32String(c32* buffer, i32 bufferSize);
  124. Char32String(const Char32String&) = delete;
  125. Char32String& operator=(const Char32String&) = delete;
  126. Error copyFrom(const Char32String& s);
  127. bool operator==(const c32* s) const;
  128. bool operator==(const Char32String& other) const;
  129. bool operator!=(const c32* s) const;
  130. bool operator!=(const Char32String& other) const;
  131. c32 operator[](int index) const;
  132. int getLength() const;
  133. int getCapacity() const;
  134. CError append(char c);
  135. CError append(signed char c);
  136. CError append(unsigned char c);
  137. CError append(wchar_t c);
  138. CError append(c32 c);
  139. CError append(const char* s);
  140. CError append(const c32* s);
  141. CError append(const signed char* s);
  142. CError append(const unsigned char* s);
  143. CError append(bool b);
  144. CError append(Error e);
  145. template<typename T>
  146. CError append(const T& t) {
  147. return Internal::genericAppend(*this, t);
  148. }
  149. CError toString(CharString& s) const;
  150. CError toString(Char32String& s) const;
  151. void clear();
  152. u32 hashCode() const;
  153. CError print() const;
  154. CError printLine() const;
  155. template<typename... Args>
  156. CError format(Char32String& s, Args&&... args) {
  157. return copyFormat(*this, s, Core::forward<Args>(args)...);
  158. }
  159. bool startsWidth(const Char32String& other, int from = 0) const;
  160. int search(const Char32String& other, int from = 0) const;
  161. bool contains(const Char32String& other, int from = 0) const;
  162. int search(c32 u, int from = 0) const;
  163. bool contains(c32 u, int from = 0) const;
  164. CError substring(Char32String& s, int from, int to) const;
  165. CError substring(Char32String& s, int from = 0) const;
  166. CError replace(Char32String& s, const Char32String& search,
  167. const Char32String& replace);
  168. void replace(c32 search, c32 replace);
  169. operator const c32*() const;
  170. private:
  171. void addToHash(c32 u);
  172. };
  173. template<int N, typename C, typename B>
  174. class ArrayString final : public B {
  175. static_assert(N > 0, "size of array string must be positive");
  176. C data[static_cast<unsigned int>(N)];
  177. public:
  178. ArrayString() : B(data, N) {
  179. }
  180. ArrayString(const ArrayString& other) : B(data, N) {
  181. Core::memoryCopy(data, other.data, sizeof(data));
  182. B::length = other.length;
  183. B::hash = other.hash;
  184. }
  185. ArrayString& operator=(const ArrayString& other) {
  186. if(this != &other) {
  187. Core::memoryCopy(data, other.data, sizeof(data));
  188. B::length = other.length;
  189. B::hash = other.hash;
  190. }
  191. return *this;
  192. }
  193. template<typename... Args>
  194. CError format(Args&&... args) {
  195. ArrayString s;
  196. return B::format(s, Core::forward<Args>(args)...);
  197. }
  198. CError replace(const B& search, const B& replace) {
  199. ArrayString s;
  200. return B::replace(s, search, replace);
  201. }
  202. using B::replace;
  203. };
  204. template<typename String, typename Iterable>
  205. CError toString(String& s, const Iterable& i) {
  206. CORE_RETURN_ERROR(s.append("["));
  207. auto current = i.begin();
  208. auto end = i.end();
  209. while(current != end) {
  210. CORE_RETURN_ERROR(s.append(*current));
  211. ++current;
  212. if(current != end) {
  213. CORE_RETURN_ERROR(s.append(", "));
  214. }
  215. }
  216. return s.append("]");
  217. }
  218. template<int N>
  219. using String8 = ArrayString<N, char, CharString>;
  220. template<int N>
  221. using String32 = ArrayString<N, c32, Char32String>;
  222. }
  223. inline bool operator==(const c32* cs, const Core::Char32String& s) {
  224. return s == cs;
  225. }
  226. inline bool operator!=(const c32* cs, const Core::Char32String& s) {
  227. return s != cs;
  228. }
  229. inline bool operator==(const char* cs, const Core::CharString& s) {
  230. return s == cs;
  231. }
  232. inline bool operator!=(const char* cs, const Core::CharString& s) {
  233. return s != cs;
  234. }
  235. #endif