ToString.cppm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. export module Core.ToString;
  2. import Core.Math;
  3. import Core.Meta;
  4. import Core.Types;
  5. export import Core.StringFormat;
  6. #define TO_STRING(type) \
  7. size_t toString(type t, char* s, size_t n, const StringFormat& format = {})
  8. export namespace Core {
  9. TO_STRING(signed char);
  10. TO_STRING(char);
  11. TO_STRING(short);
  12. TO_STRING(int);
  13. TO_STRING(long);
  14. TO_STRING(long long);
  15. TO_STRING(unsigned char);
  16. TO_STRING(unsigned short);
  17. TO_STRING(unsigned int);
  18. TO_STRING(unsigned long);
  19. TO_STRING(unsigned long long);
  20. TO_STRING(float);
  21. TO_STRING(double);
  22. TO_STRING(const char*);
  23. TO_STRING(const unsigned char*);
  24. TO_STRING(unsigned char*);
  25. TO_STRING(bool);
  26. template<typename T>
  27. void addString(
  28. const T& t, char*& s, size_t& n, size_t& total,
  29. const StringFormat& format = {});
  30. template<Core::Iterable T>
  31. size_t toString(
  32. const T& t, char* s, size_t n, const StringFormat& format = {}) {
  33. (void)format;
  34. size_t total = 0;
  35. addString("[", s, n, total);
  36. auto current = t.begin();
  37. auto end = t.end();
  38. if(current != end) {
  39. addString(*current, s, n, total);
  40. ++current;
  41. }
  42. while(current != end) {
  43. addString(", ", s, n, total);
  44. addString(*current, s, n, total);
  45. ++current;
  46. }
  47. addString("]", s, n, total);
  48. return total;
  49. }
  50. template<typename T>
  51. concept ToString =
  52. requires(const T& t, char* s, size_t n) { t.toString(s, n); };
  53. template<ToString T>
  54. size_t toString(
  55. const T& t, char* s, size_t n, const StringFormat& format = {}) {
  56. (void)format;
  57. return t.toString(s, n);
  58. }
  59. template<typename T>
  60. void addString(
  61. const T& t, char*& s, size_t& n, size_t& total,
  62. const StringFormat& format) {
  63. size_t w = toString(t, s, n, format);
  64. total += w;
  65. w = Core::min(n, w);
  66. s += w;
  67. n -= w;
  68. }
  69. size_t copyFormatUntil(
  70. const char*& format, char*& s, size_t& n, StringFormat& f);
  71. template<typename T, typename... Args>
  72. void formatR(
  73. const char*& format, char*& s, size_t& n, size_t& total, const T& t,
  74. Args&&... args) {
  75. StringFormat f;
  76. total += copyFormatUntil(format, s, n, f);
  77. addString(t, s, n, total, f);
  78. if constexpr(sizeof...(args) > 0) {
  79. formatR(format, s, n, total, Core::forward<Args>(args)...);
  80. }
  81. }
  82. template<typename... Args>
  83. size_t formatBuffer(char* s, size_t n, const char* format, Args&&... args) {
  84. StringFormat f;
  85. size_t total = 0;
  86. if constexpr(sizeof...(args) > 0) {
  87. formatR(format, s, n, total, Core::forward<Args>(args)...);
  88. }
  89. return total + copyFormatUntil(format, s, n, f);
  90. }
  91. struct StringBase {
  92. size_t index = 0;
  93. size_t capacity = 0;
  94. char* buffer = nullptr;
  95. StringBase() {
  96. }
  97. StringBase(StringBase&& other) = default;
  98. StringBase(const StringBase& other) = delete;
  99. StringBase& operator=(StringBase&& other) = default;
  100. StringBase& operator=(const StringBase& other) = delete;
  101. template<typename... Args>
  102. size_t format(const char* format, Args&&... args) {
  103. size_t total = formatBuffer(
  104. buffer + index, capacity - index, format,
  105. Core::forward<Args>(args)...);
  106. index = Core::min(index + total, capacity);
  107. return total;
  108. }
  109. template<typename T>
  110. size_t add(const T& t) {
  111. size_t total = toString(t, buffer + index, capacity - index);
  112. index = Core::min(index + total, capacity);
  113. return total;
  114. }
  115. void print();
  116. };
  117. template<size_t N>
  118. struct String : public StringBase {
  119. char data[N]{};
  120. String() {
  121. buffer = data;
  122. capacity = N;
  123. }
  124. };
  125. template<typename... Args>
  126. void print(const char* format, Args&&... args) {
  127. String<256> s;
  128. s.format(format, Core::forward<Args>(args)...);
  129. s.print();
  130. }
  131. }