ArrayString.hpp 8.0 KB

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