ArrayString.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. class BufferString {
  10. protected:
  11. size_t length;
  12. size_t capacity;
  13. char* data;
  14. public:
  15. BufferString(char* buffer, size_t bufferSize);
  16. BufferString(const BufferString&) = delete;
  17. BufferString& operator=(const BufferString&);
  18. BufferString(BufferString&&) = delete;
  19. BufferString& operator=(BufferString&&) = delete;
  20. bool operator==(const char* s) const;
  21. bool operator==(const BufferString& other) const;
  22. bool operator!=(const char* s) const;
  23. bool operator!=(const BufferString& other) const;
  24. char operator[](size_t index) const;
  25. size_t getLength() const;
  26. size_t getCapacity() const;
  27. BufferString& append(char c);
  28. BufferString& append(signed char c);
  29. BufferString& append(unsigned char c);
  30. BufferString& append(wchar_t c);
  31. BufferString& append(c32 c);
  32. BufferString& append(const char* s);
  33. BufferString& append(const c32* s);
  34. BufferString& append(const signed char* s);
  35. BufferString& append(const unsigned char* s);
  36. BufferString& append(bool b);
  37. template<typename T>
  38. BufferString& append(const T& t) {
  39. if constexpr(requires { t.toString(*this); }) {
  40. (void)t.toString(*this);
  41. } else if constexpr(requires { static_cast<const char*>(t); }) {
  42. append(static_cast<const char*>(t));
  43. } else {
  44. char buffer[64];
  45. Core::toString(t, buffer, sizeof(buffer));
  46. append(static_cast<const char*>(buffer));
  47. }
  48. return *this;
  49. }
  50. void toString(BufferString& s) const;
  51. void clear();
  52. void print() const;
  53. void printLine() const;
  54. template<typename... Args>
  55. BufferString& format(BufferString& s, Args&&... args) {
  56. if constexpr(sizeof...(args) > 0) {
  57. formatR(s, 0, forward<Args>(args)...);
  58. *this = s;
  59. }
  60. return *this;
  61. }
  62. bool startsWith(const BufferString& other, size_t from = 0) const;
  63. size_t search(const BufferString& other, size_t from = 0) const;
  64. bool contains(const BufferString& other, size_t from = 0) const;
  65. size_t search(char u, size_t from = 0) const;
  66. bool contains(char u, size_t from = 0) const;
  67. void substring(BufferString& s, size_t from, size_t to) const;
  68. void substring(BufferString& s, size_t from = 0) const;
  69. void replace(BufferString& s, const BufferString& search,
  70. const BufferString& replace);
  71. void replace(char search, char replace);
  72. operator const char*() const;
  73. private:
  74. template<typename T, typename... Args>
  75. void formatR(BufferString& s, size_t index, const T& t,
  76. Args&&... args) const {
  77. size_t l = getLength();
  78. while(index < l) {
  79. char u = data[index++];
  80. if(u == '#') {
  81. if(index >= l || data[index] != '#') {
  82. break;
  83. }
  84. index++;
  85. }
  86. s.append(u);
  87. }
  88. s.append(t);
  89. if constexpr(sizeof...(args) > 0) {
  90. formatR(s, index, forward<Args>(args)...);
  91. return;
  92. }
  93. while(index < l) {
  94. s.append(data[index++]);
  95. }
  96. }
  97. };
  98. template<size_t N>
  99. class ArrayString final : public BufferString {
  100. char data[N];
  101. public:
  102. ArrayString() : BufferString(data, N) {
  103. }
  104. ArrayString(const ArrayString& other) : BufferString(data, N) {
  105. memcpy(data, other.data, sizeof(data));
  106. length = other.length;
  107. }
  108. ArrayString& operator=(const ArrayString& other) {
  109. if(this != &other) {
  110. memcpy(data, other.data, sizeof(data));
  111. length = other.length;
  112. }
  113. return *this;
  114. }
  115. template<typename... Args>
  116. ArrayString& format(Args&&... args) {
  117. ArrayString s;
  118. BufferString::format(s, Core::forward<Args>(args)...);
  119. return *this;
  120. }
  121. void replace(const BufferString& search, const BufferString& replace) {
  122. ArrayString s;
  123. BufferString::replace(s, search, replace);
  124. }
  125. using BufferString::replace;
  126. };
  127. template<typename String, typename Iterable>
  128. void toString(String& s, const Iterable& i) {
  129. s.append("[");
  130. auto current = i.begin();
  131. auto end = i.end();
  132. while(current != end) {
  133. s.append(*current);
  134. ++current;
  135. if(current != end) {
  136. s.append(", ");
  137. }
  138. }
  139. s.append("]");
  140. }
  141. }
  142. inline bool operator==(const char* cs, const Core::BufferString& s) {
  143. return s == cs;
  144. }
  145. inline bool operator!=(const char* cs, const Core::BufferString& s) {
  146. return s != cs;
  147. }
  148. #endif