Files
CPP_Core/Core/system/export.h
T
2026-07-24 10:54:45 +08:00

199 lines
6.7 KiB
C++

#pragma once
#include <algorithm>
#include <atomic>
#include <cassert>
#include <csignal>
#include <cstdint>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <mutex>
#include <set>
#include <stack>
#include <string>
#include <string_view>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
#include "../Base/global_include.h"
#include "3rd/magic_enum/export.h"
#include "magic_enum/magic_enum.hpp"
#define PSC_LOAD_LIBRARY_PARAMS(M, SEP) M(std::string_view, library_path)
#define PSC_LOAD_FUNCTION_PARAMS(M, SEP) \
M(void*, library) \
SEP() \
M(std::string_view, function_name)
#define DELETE_COPY(Class) \
Class(const Class&) = delete; \
Class& operator=(const Class&) = delete;
namespace Psc {
void set_console_utf8();
std::string get_stack_trace();
std::string get_computer_serial_number();
PSC_DECLARE_TRIPLE_API(void*, load_library, PSC_LOAD_LIBRARY_PARAMS);
void* load_library_fail_fast(std::string_view library_path);
void free_library(void* library);
PSC_DECLARE_TRIPLE_API(void*, load_function, PSC_LOAD_FUNCTION_PARAMS);
void* load_function_fail_fast(void* library, std::string_view function_name);
std::string get_home_dir();
std::string get_exe_path();
std::string get_exe_dir();
std::string get_abs_path(std::string_view path);
std::string to_upper_case(std::string_view input);
std::string base64_encode(std::string_view data);
std::string base64_decode(std::string_view data);
// strftime 格式,例如 "%Y-%m-%d %H:%M:%S" / "%H:%M:%S"。
std::string utc_2_local_time(std::time_t us_timestamp,
const char* format = "%H:%M:%S");
std::uint64_t get_current_millisecond_timestamp();
void set_current_thread_name(std::string_view name);
using Main_Function_Type = int (*)(int, char**);
// 接管 main 函数,联通 gtest。
int redict_main_with_gtest(int argc, char* argv[],
Main_Function_Type main_func);
// 设置给定 std::thread 的优先级。
// Windows: void* 版本要求传 Win32 HANDLE。
// Linux: void* 版本要求传 pthread_t*,例如 pthread_t pt = pthread_self();
// set_thread_priority(&pt, ...)。
bool set_thread_priority(void* thread, int priority, bool realtime);
bool set_thread_priority(std::thread* thread, int priority, bool realtime);
// 设置给定线程的 CPU 亲和性。
// Windows: void* 版本要求传 Win32 HANDLE。
// Linux: void* 版本要求传 pthread_t*。
bool set_thread_affinity(void* thread, unsigned cpu_index);
bool set_thread_affinity(std::thread* thread, unsigned cpu_index);
size_t get_system_memory();
size_t get_process_memory();
std::string get_memory_info();
std::string signal_to_string(int signal);
std::string get_current_time_as_string();
void create_file_if_not_exists(std::string_view file_name);
void create_dir_if_not_exists(std::string_view dir_name);
void init_signal_config(std::set<int> normal_quit = {SIGINT, SIGTERM},
std::set<int> ignore_signal = {});
class String_Pool {
public:
explicit String_Pool(size_t block_size, size_t pool_size) : block_size(block_size), pool_size(pool_size) {
grow(pool_size);
}
size_t remain_size() {
std::lock_guard g(mtx);
return strings_.size() * block_size;
}
size_t free_size() {
std::lock_guard g(mtx);
return free_.size() * block_size;
}
std::string* get() {
std::lock_guard g(mtx);
if (free_.empty()) {
const size_t grow_count =
strings_.empty() ? std::max<size_t>(pool_size, 1) : strings_.size();
std::cout << "String_Pool 扩容对象数 【" << grow_count
<< "】,理论容量 【" << grow_count * block_size << ""
<< std::endl;
grow(grow_count);
}
std::string* ptr = free_.top();
free_.pop();
return ptr;
}
[[nodiscard]] size_t capacity() const {
std::lock_guard g(mtx);
return strings_.size();
}
[[nodiscard]] size_t free_count() const {
std::lock_guard g(mtx);
return free_.size();
}
private:
void grow(size_t count) {
for (size_t i = 0; i < count; ++i) {
strings_.emplace_back();
std::string& str = strings_.back();
str.reserve(block_size);
free_.push(&str);
}
}
void release(std::string* ptr) {
std::lock_guard g(mtx);
if (ptr) {
ptr->clear();
free_.push(ptr);
}
}
void release(const std::vector<std::string*>& list) {
std::lock_guard g(mtx);
for (auto* li : list) {
if (li) {
li->clear();
free_.push(li);
}
}
}
private:
std::deque<std::string> strings_;
std::stack<std::string*> free_{};
mutable Spin_Lock mtx;
size_t block_size; // 每个 std::string 预留的容量。
size_t pool_size; // 初始创建多少个 string 对象。
friend struct Pool_Guard;
};
struct Pool_Guard {
Pool_Guard(String_Pool* pool, std::string* buf) : pool(pool), buf(buf) {
}
Pool_Guard(String_Pool* pool, std::vector<std::string*> list) : pool(pool), list(std::move(list)) {
}
~Pool_Guard() {
if (!pool) {
return;
}
if (buf) {
pool->release(buf);
}
if (!list.empty()) {
pool->release(list);
}
}
Pool_Guard(const Pool_Guard&) = delete;
Pool_Guard& operator=(const Pool_Guard&) = delete;
Pool_Guard(Pool_Guard&& other) noexcept
: pool(other.pool), list(std::move(other.list)), buf(other.buf) {
other.pool = nullptr;
other.buf = nullptr;
}
Pool_Guard& operator=(Pool_Guard&& other) noexcept {
if (this != &other) {
pool = other.pool;
list = std::move(other.list);
buf = other.buf;
other.pool = nullptr;
other.buf = nullptr;
}
return *this;
}
protected:
String_Pool* pool{};
std::vector<std::string*> list;
std::string* buf{};
};
template <typename Enum_Type>
class Enum_Err {
public:
explicit Enum_Err(Enum_Type errc) : nerr(errc), native(get_error_code(), std::system_category()) {
}
Enum_Err(Enum_Type errc, ERROR_CODE_TYPE code) : nerr(errc), native(std::error_code(code, std::system_category())) {
}
Enum_Type nerr;
std::error_code native;
std::string to_string() {
auto enum_name =
std::string(magic_enum::template enum_type_name<Enum_Type>());
return enum_name + "" + Psc::to_string(nerr) +
" native:" + get_error_message(native.value()) + "";
}
};
} // namespace Psc