Init commit

This commit is contained in:
2026-08-17 06:31:43 +09:00
commit 348d9275f6
428 changed files with 61806 additions and 0 deletions
+296
View File
@@ -0,0 +1,296 @@
#include "../include/tool.h"
#include <iostream>
#include <iomanip>
#include <vector>
#include <random>
#ifdef _WIN32
#include <Windows.h>
#elif defined(__linux__)
#include <locale>
#include <codecvt>
#include <unistd.h>
#include <limits.h>
#endif
#ifdef _WIN32
std::wstring Z::HResultToWString(HRESULT hr) {
LPWSTR buffer = nullptr;
DWORD flags =
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
DWORD len = FormatMessageW(
flags, nullptr, hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&buffer), 0, nullptr);
// 如果是 HRESULT_FROM_WIN32(...) 形式,尝试取低 16 位 Win32 error code
if (len == 0 && HRESULT_FACILITY(hr) == FACILITY_WIN32) {
len = FormatMessageW(
flags,
nullptr,
HRESULT_CODE(hr),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&buffer),
0,
nullptr
);
}
if (len == 0) {
wchar_t fallback[64];
swprintf_s(fallback, L"Unknown HRESULT: 0x%08X", static_cast<unsigned>(hr));
return fallback;
}
std::wstring message(buffer, len);
LocalFree(buffer);
return message;
}
#endif
namespace {
std::once_flag initflag{};
}
//region 字符串转换(UTF8 - WSTRING)
namespace Z {
#ifdef _WIN32
std::string wstring_to_u8(const std::wstring &wstr) {
if (wstr.empty())return {};
int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(),
static_cast<int>(wstr.size()),
nullptr, 0, nullptr, nullptr);
if (len <= 0) throw std::runtime_error("Z::wstring_to_u8 compute length error.");
std::string str(len, '\0');
len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(),
static_cast<int>(wstr.size()),
str.data(), len, nullptr, nullptr);
if (len <= 0)throw std::runtime_error("Z::wstring_to_u8 escape error.");
return str;
}
std::wstring u8_to_wstring(const std::string &u8str) {
if (u8str.empty())return {};
int len = MultiByteToWideChar(CP_UTF8, 0, u8str.c_str(), -1, nullptr, 0);
if (len <= 0) throw std::runtime_error("Z::u8_to_wstring compute length error.");
std::wstring ws(len, L'\0');
len = MultiByteToWideChar(CP_UTF8, 0, u8str.c_str(), -1, ws.data(), len);
if (len <= 0) throw std::runtime_error("Z::u8_to_wstring escape error.");
return ws;
}
#else
std::string wstring_to_u8(const std::wstring &wstr) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(wstr);
}
std::wstring u8_to_wstring(const std::string &u8str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.from_bytes(str);
}
#endif
}
//region filesystem相关
namespace Z {
std::filesystem::path get_module_path() {
#if defined(_WIN32)
#if defined(UNICODE) || defined(_UNICODE)
// Windows Unicode / wide char variant
std::wstring buffer(MAX_PATH, L'\0');
DWORD length = GetModuleFileNameW(
nullptr,
buffer.data(),
static_cast<DWORD>(buffer.size())
);
if (length == 0) {
throw std::runtime_error("GetModuleFileNameW failed");
}
// 如果路径长度刚好达到 buffer 大小,可能被截断,动态扩容
while (length == buffer.size()) {
buffer.resize(buffer.size() * 2);
length = GetModuleFileNameW(
nullptr,
buffer.data(),
static_cast<DWORD>(buffer.size())
);
if (length == 0) {
throw std::runtime_error("GetModuleFileNameW failed");
}
}
buffer.resize(length);
return std::filesystem::path(buffer);
#else
// Windows non-Unicode / narrow char variant
std::string buffer(MAX_PATH, '\0');
DWORD length = GetModuleFileNameA(
nullptr,
buffer.data(),
static_cast<DWORD>(buffer.size())
);
if (length == 0) {
throw std::runtime_error("GetModuleFileNameA failed");
}
// 如果路径长度刚好达到 buffer 大小,可能被截断,动态扩容
while (length == buffer.size()) {
buffer.resize(buffer.size() * 2);
length = GetModuleFileNameA(
nullptr,
buffer.data(),
static_cast<DWORD>(buffer.size())
);
if (length == 0) {
throw std::runtime_error("GetModuleFileNameA failed");
}
}
buffer.resize(length);
return std::filesystem::path(buffer);
#endif
#elif defined(__linux__)
// Linux / GCC variant
std::vector<char> buffer(PATH_MAX);
while (true) {
ssize_t length = readlink(
"/proc/self/exe",
buffer.data(),
buffer.size()
);
if (length == -1) {
throw std::runtime_error("readlink /proc/self/exe failed");
}
// readlink 不会自动追加 '\0'
if (static_cast<size_t>(length) < buffer.size()) {
return std::filesystem::path(
std::string(buffer.data(), static_cast<size_t>(length))
);
}
// 缓冲区不够,扩容重试
buffer.resize(buffer.size() * 2);
}
#else
#error "get_module_path is not implemented for this platform"
#endif
}
std::filesystem::path get_module_dir() {
return get_module_path().parent_path();
}
}
//region 其他
namespace Z {
void print_obj_memory(const void *obj, size_t len) {
auto bytes = static_cast<const unsigned char *>(obj);
int l = static_cast<int>(len);
int w = 1;
while ((l /= 10) > 0) {
w++;
}
for (size_t i = 0; i < len; i += 8) {
for (size_t j = 0; j < 8; ++j) {
auto sum = i + j;
if (sum == len) break;
std::cout << '[' << std::setfill('0') << std::setw(w) << sum << ']'
<< std::setw(3) << static_cast<int>(bytes[sum]) << ' ';
}
std::cout << '\n';
}
std::cout << std::flush;
}
bool Random::bInitialized = false;
void *Random::m_gen = nullptr;
uint32_t Random::m_seed = 0;
int Random::Get(int min, int max) {
InitOnce();
std::uniform_int_distribution dist(min, max);
return dist(*static_cast<std::mt19937 *>(m_gen));
}
float Random::Get(float min, float max) {
InitOnce();
std::uniform_real_distribution dist(min, max);
return dist(*static_cast<std::mt19937 *>(m_gen));
}
double Random::Get(double min, double max) {
InitOnce();
std::uniform_real_distribution dist(min, max);
return dist(*static_cast<std::mt19937 *>(m_gen));
}
void Random::GenerateSequence() {
if (!bInitialized) {
InitOnce();
} else {
GenSequence();
}
}
void Random::GenerateSequence(uint32_t seed) {
if (!bInitialized) {
InitOnce();
}
GenSequence(seed);
}
void Random::InitOnce() {
std::call_once(initflag, []() {
GenSequence();
std::atexit(CleanUp);
bInitialized = true;
});
}
void Random::GenSequence() {
if (m_gen) {
auto *_gen = static_cast<std::mt19937 *>(m_gen);
delete _gen;
}
std::random_device rd{};
m_seed = rd();
m_gen = new std::mt19937(m_seed);
}
void Random::GenSequence(uint32_t seed) {
m_seed = seed;
if (m_gen) {
auto *_gen = static_cast<std::mt19937 *>(m_gen);
delete _gen;
}
m_gen = new std::mt19937(seed);
}
void Random::CleanUp() {
if (m_gen) {
auto *_gen = static_cast<std::mt19937 *>(m_gen);
delete _gen;
m_gen = nullptr;
bInitialized = false;
}
}
}
//
+1368
View File
File diff suppressed because it is too large Load Diff