Files
Renderive/Core/base/String_Format.h
T
2026-08-01 20:09:45 +08:00

91 lines
2.6 KiB
C++

#pragma once
#include <charconv>
#include <string>
#include <string_view>
#include "Time_Of_Day.h"
namespace renderive {
enum class Number_Notation : std::uint8_t {
Fixed,
Scientific,
General
};
struct Number_Format {
Number_Notation notation = Number_Notation::Fixed;
int precision = 2;
};
struct Number_Locale {
char decimal_separator = '.';
char group_separator = ',';
bool use_group_separator = false;
};
inline std::string format_number(double value, const Number_Format& format) {
char buf[64];
const char* fmt = "f";
if (format.notation == Number_Notation::Scientific)
fmt = "e";
else if (format.notation == Number_Notation::General)
fmt = "g";
int prec = format.precision;
if (prec < 0)
prec = 0;
if (prec > 20)
prec = 20;
auto result = std::to_chars(buf, buf + sizeof(buf) - 1, value,
fmt == "f" ? std::chars_format::fixed
: fmt == "e" ? std::chars_format::scientific
: std::chars_format::general, prec);
if (result.ec == std::errc{})
return std::string(buf, result.ptr);
return {};
}
inline std::string format_time(Time_Of_Day time, std::string_view pattern) {
if (!time.valid())
return {};
auto ms = static_cast<std::int64_t>(time.milliseconds);
auto hours = static_cast<int>((ms / (1000 * 60 * 60)) % 24);
auto minutes = static_cast<int>((ms / (1000 * 60)) % 60);
auto seconds = static_cast<int>((ms / 1000) % 60);
auto msecs = static_cast<int>(ms % 1000);
std::string result;
result.reserve(pattern.size() + 4);
for (std::size_t i = 0; i < pattern.size(); ++i) {
char c = pattern[i];
if (c == 'h' && i + 1 < pattern.size() && pattern[i + 1] == 'h') {
char buf[4];
snprintf(buf, sizeof(buf), "%02d", hours);
result += buf;
++i;
} else if (c == 'm' && i + 1 < pattern.size() && pattern[i + 1] == 'm') {
char buf[4];
snprintf(buf, sizeof(buf), "%02d", minutes);
result += buf;
++i;
} else if (c == 's' && i + 1 < pattern.size() && pattern[i + 1] == 's') {
char buf[4];
snprintf(buf, sizeof(buf), "%02d", seconds);
result += buf;
++i;
} else if (c == 'z' && i + 2 < pattern.size() && pattern[i + 1] == 'z' && pattern[i + 2] == 'z') {
char buf[6];
snprintf(buf, sizeof(buf), "%03d", msecs);
result += buf;
i += 2;
} else {
result += c;
}
}
return result;
}
} // namespace renderive