ArrayString.hpp 8.1 KB

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