#pragma once #include "../Base/global_include.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "3rd/magic_enum/export.h" #include "magic_enum/magic_enum.hpp" #define PSC_LOAD_LIBRARY_PARAMS(M, SEP) \ M(const std::string&, library_path) #define PSC_LOAD_FUNCTION_PARAMS(M, SEP) \ M(void*, library) SEP() \ M(const std::string&, 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(const std::string& 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, const std::string& function_name); std::string get_home_dir(); std::string get_exe_path(); std::string get_exe_dir(); std::string get_abs_path(const std::string& path); std::string to_upper_case(const std::string& input); std::string base64_encode(const std::string& data); std::string base64_decode(const std::string& 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(const std::string& 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(const std::string& file_name); void create_dir_if_not_exists(const std::string& dir_name); void init_signal_config(std::set normal_quit = {SIGINT, SIGTERM}, std::set 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(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& list) { std::lock_guard g(mtx); for (auto* li : list) { if (li) { li->clear(); free_.push(li); } } } private: std::deque strings_; std::stack 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 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 list; std::string* buf{}; }; template 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()); return enum_name + "【" + Psc::to_string(nerr) + " native:" + get_error_message(native.value()) + "】"; } }; } // namespace Psc