91 lines
2.6 KiB
C++
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
|