|
@@ -1,49 +1,77 @@
|
|
|
-module;
|
|
|
|
|
-
|
|
|
|
|
-#include <cstdio>
|
|
|
|
|
-
|
|
|
|
|
module Core.ToString;
|
|
module Core.ToString;
|
|
|
|
|
|
|
|
import Core.Std;
|
|
import Core.Std;
|
|
|
|
|
|
|
|
-#define TO_STRING(type, format) \
|
|
|
|
|
- void Core::StringBase::toString(type v, const StringFormat& f) noexcept { \
|
|
|
|
|
- (void)f; \
|
|
|
|
|
- int e = snprintf(getCurrent(), getCapacity(), format, v); \
|
|
|
|
|
- index += e < 0 ? 0 : static_cast<size_t>(e); \
|
|
|
|
|
- }
|
|
|
|
|
#define TO_STRING_LINK(from, to) \
|
|
#define TO_STRING_LINK(from, to) \
|
|
|
void Core::StringBase::toString(from v, const StringFormat& f) noexcept { \
|
|
void Core::StringBase::toString(from v, const StringFormat& f) noexcept { \
|
|
|
toString(static_cast<to>(v), f); \
|
|
toString(static_cast<to>(v), f); \
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-TO_STRING(char, "%c")
|
|
|
|
|
-TO_STRING_LINK(signed char, char)
|
|
|
|
|
-TO_STRING(short, "%hd")
|
|
|
|
|
-TO_STRING(int, "%d")
|
|
|
|
|
-TO_STRING(long, "%ld")
|
|
|
|
|
-TO_STRING(long long, "%lld")
|
|
|
|
|
-TO_STRING(unsigned char, "%c")
|
|
|
|
|
-TO_STRING(unsigned short, "%hu")
|
|
|
|
|
-TO_STRING(unsigned int, "%u")
|
|
|
|
|
-TO_STRING(unsigned long, "%lu")
|
|
|
|
|
-TO_STRING(unsigned long long, "%llu")
|
|
|
|
|
|
|
+TO_STRING_LINK(short, long long)
|
|
|
|
|
+TO_STRING_LINK(int, long long)
|
|
|
|
|
+TO_STRING_LINK(long, long long)
|
|
|
|
|
+TO_STRING_LINK(unsigned short, unsigned long long)
|
|
|
|
|
+TO_STRING_LINK(unsigned int, unsigned long long)
|
|
|
|
|
+TO_STRING_LINK(unsigned long, unsigned long long)
|
|
|
TO_STRING_LINK(float, double)
|
|
TO_STRING_LINK(float, double)
|
|
|
-TO_STRING(const char*, "%s")
|
|
|
|
|
-TO_STRING(const unsigned char*, "%s")
|
|
|
|
|
-TO_STRING_LINK(unsigned char*, const unsigned char*)
|
|
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(char c, const StringFormat&) noexcept {
|
|
|
|
|
+ addChar(c);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(signed char c, const StringFormat&) noexcept {
|
|
|
|
|
+ addChar(static_cast<char>(c));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(unsigned char c, const StringFormat&) noexcept {
|
|
|
|
|
+ addChar(static_cast<char>(c));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(const char* s, const StringFormat&) noexcept {
|
|
|
|
|
+ while(*s != '\0') {
|
|
|
|
|
+ addChar(*(s++));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(
|
|
|
|
|
+ const unsigned char* s, const StringFormat& f) noexcept {
|
|
|
|
|
+ return toString(reinterpret_cast<const char*>(s), f);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+template<typename T, typename... Args>
|
|
|
|
|
+static void toBuffer(char* s, size_t n, T t, Args&&... args) {
|
|
|
|
|
+ std::to_chars_result r = std::to_chars(s, s + n, t, args...);
|
|
|
|
|
+ if(r.ec == std::errc()) {
|
|
|
|
|
+ *r.ptr = '\0';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ *(s++) = '?';
|
|
|
|
|
+ *s = '\0';
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(long long v, const StringFormat& f) noexcept {
|
|
|
|
|
+ char s[32];
|
|
|
|
|
+ toBuffer(s, sizeof(s), v, 10);
|
|
|
|
|
+ toString(s, f);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void Core::StringBase::toString(
|
|
|
|
|
+ unsigned long long v, const StringFormat& f) noexcept {
|
|
|
|
|
+ char s[32];
|
|
|
|
|
+ toBuffer(s, sizeof(s), v, 10);
|
|
|
|
|
+ toString(s, f);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
void Core::StringBase::toString(double v, const StringFormat& f) noexcept {
|
|
void Core::StringBase::toString(double v, const StringFormat& f) noexcept {
|
|
|
- int e = snprintf(
|
|
|
|
|
- getCurrent(), getCapacity(), "%.*f", f.precision < 0 ? 2 : f.precision,
|
|
|
|
|
- v);
|
|
|
|
|
- index += e < 0 ? 0 : static_cast<size_t>(e);
|
|
|
|
|
|
|
+ char s[64];
|
|
|
|
|
+ toBuffer(
|
|
|
|
|
+ s, sizeof(s), v, std::chars_format::fixed,
|
|
|
|
|
+ f.precision < 0 ? 2 : f.precision);
|
|
|
|
|
+ toString(s, f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Core::StringBase::toString(bool v, const StringFormat& f) noexcept {
|
|
void Core::StringBase::toString(bool v, const StringFormat& f) noexcept {
|
|
|
- (void)f;
|
|
|
|
|
- int e = snprintf(getCurrent(), getCapacity(), "%s", v ? "true" : "false");
|
|
|
|
|
- index += e < 0 ? 0 : static_cast<size_t>(e);
|
|
|
|
|
|
|
+ toString(v ? "true" : "false", f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int parseFormatNumber(const char*& from, const char* to) noexcept {
|
|
static int parseFormatNumber(const char*& from, const char* to) noexcept {
|
|
@@ -110,6 +138,14 @@ void Core::StringBase::print() const noexcept {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void Core::StringBase::addChar(char c) {
|
|
|
|
|
+ if(index + 1 < capacity) {
|
|
|
|
|
+ buffer[index] = c;
|
|
|
|
|
+ buffer[index + 1] = '\0';
|
|
|
|
|
+ }
|
|
|
|
|
+ index++;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void Core::StringBase::applyPostFormat(
|
|
void Core::StringBase::applyPostFormat(
|
|
|
size_t startIndex, size_t length, const StringFormat& format) noexcept {
|
|
size_t startIndex, size_t length, const StringFormat& format) noexcept {
|
|
|
if(format.width <= 0) {
|
|
if(format.width <= 0) {
|
|
@@ -118,7 +154,7 @@ void Core::StringBase::applyPostFormat(
|
|
|
size_t w = static_cast<size_t>(format.width);
|
|
size_t w = static_cast<size_t>(format.width);
|
|
|
if(format.alignment == StringAlignment::LEFT) {
|
|
if(format.alignment == StringAlignment::LEFT) {
|
|
|
while(length < w) {
|
|
while(length < w) {
|
|
|
- add(" ");
|
|
|
|
|
|
|
+ addChar(' ');
|
|
|
length++;
|
|
length++;
|
|
|
}
|
|
}
|
|
|
} else if(format.alignment == StringAlignment::RIGHT) {
|
|
} else if(format.alignment == StringAlignment::RIGHT) {
|