Files
CPP_Core/3rd/magic_enum/export.h
T
2026-08-05 11:59:44 +08:00

302 lines
10 KiB
C++

#pragma once
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include "Core/Base/global_include.h"
#include "magic_enum/include/magic_enum/magic_enum.hpp"
#include "remove_const.hpp"
namespace Psc {
template <class T>
class Copyable_Atomic {
public:
using value_type = T;
Copyable_Atomic() = default;
Copyable_Atomic(T value) : value_(value) {
}
Copyable_Atomic(const Copyable_Atomic& other) : value_(other.load()) {
}
Copyable_Atomic& operator=(const Copyable_Atomic& other) {
store(other.load());
return *this;
}
Copyable_Atomic& operator=(T value) {
store(value);
return *this;
}
T load(std::memory_order order = std::memory_order_seq_cst) const {
return value_.load(order);
}
void store(T value, std::memory_order order = std::memory_order_seq_cst) {
value_.store(value, order);
}
operator T() const {
return load();
}
private:
std::atomic<T> value_{};
};
template <typename T>
using clean_t = std::remove_cv_t<std::remove_reference_t<T>>;
namespace PV {
template <typename T>
struct is_copyable_atomic_helper : std::false_type {};
template <typename U>
struct is_copyable_atomic_helper<Copyable_Atomic<U>> : std::true_type {};
template <typename T>
struct is_copyable_atomic : is_copyable_atomic_helper<clean_t<T>> {};
template <typename T>
struct copyable_atomic_value;
template <typename U>
struct copyable_atomic_value<Copyable_Atomic<U>> {
using type = U;
};
} // namespace PV
template <typename T>
constexpr bool is_copyable_atomic_v = PV::is_copyable_atomic<T>::value;
template <typename T>
using copyable_atomic_value_t = typename PV::copyable_atomic_value<clean_t<T>>::type;
template <typename T>
struct always_false : std::false_type {};
template <typename T>
using clean_t = std::remove_cv_t<std::remove_reference_t<T>>;
namespace PV {
template <typename T>
struct is_optional_helper : std::false_type {};
template <typename U>
struct is_optional_helper<std::optional<U>> : std::true_type {};
template <typename T>
struct is_optional : is_optional_helper<clean_t<T>> {};
template <typename T>
struct optional_value;
template <typename U>
struct optional_value<std::optional<U>> {
using type = U;
};
} // namespace PV
template <typename T>
constexpr bool is_optional_v = PV::is_optional<T>::value;
template <typename T>
using optional_value_t = typename PV::optional_value<clean_t<T>>::type;
namespace PV {
template <typename T>
struct is_atomic_helper : std::false_type {};
template <typename U>
struct is_atomic_helper<std::atomic<U>> : std::true_type {};
template <typename T>
struct is_atomic : is_atomic_helper<clean_t<T>> {};
template <typename T>
struct atomic_value;
template <typename U>
struct atomic_value<std::atomic<U>> {
using type = U;
};
} // namespace PV
template <typename T>
constexpr bool is_atomic_v = PV::is_atomic<T>::value;
template <typename T>
using atomic_value_t = typename PV::atomic_value<clean_t<T>>::type;
namespace PV {
template <typename T>
struct is_shared_ptr_helper : std::false_type {};
template <typename U>
struct is_shared_ptr_helper<std::shared_ptr<U>> : std::true_type {};
template <typename T>
struct is_shared_ptr : is_shared_ptr_helper<clean_t<T>> {};
template <typename T>
struct shared_ptr_value;
template <typename U>
struct shared_ptr_value<std::shared_ptr<U>> {
using type = U;
};
} // namespace PV
template <typename T>
constexpr bool is_shared_ptr_v = PV::is_shared_ptr<T>::value;
template <typename T>
using shared_ptr_value_t = typename PV::shared_ptr_value<clean_t<T>>::type;
// 泛型函数:将枚举类型和所有值转换为字符串,并返回
template <typename EnumType>
std::string get_enum_def_str() {
std::string result;
result += "enum " + std::string(magic_enum::enum_type_name<EnumType>());
result += "{\n";
for (auto e : magic_enum::enum_values<EnumType>()) {
result += "\t";
result += magic_enum::enum_name(e); // 获取枚举值的名字
result += "\n";
}
result += "}\n";
return result;
}
template <typename EnumType>
EnumType to_enum(const std::string& str) {
auto opt = magic_enum::enum_cast<EnumType>(str);
if (opt.has_value()) {
return opt.value(); // 返回枚举值
}
std::cerr << std::string(magic_enum::enum_type_name<EnumType>()) + " 字符串转换枚举值错误!str:[" + str + "]\n" +
get_enum_def_str<EnumType>() + "\n";
Psc::fail_fast("");
return EnumType();
}
template <typename EnumType>
std::optional<EnumType> to_enum2(const std::string& str) {
auto opt = magic_enum::enum_cast<EnumType>(str);
if (opt.has_value()) {
return opt.value(); // 返回枚举值
}
return std::nullopt;
}
// 其余未考虑到的类型直接实现 other_to_string(T) 就可以了。
template <typename, typename = void>
struct has_free_to_string : std::false_type {};
template <typename T>
struct has_free_to_string<T, std::void_t<decltype(other_to_string(std::declval<T>()))>> : std::true_type {};
template <typename, typename = void>
struct has_member_to_string : std::false_type {};
template <typename T>
struct has_member_to_string<T, std::void_t<decltype(std::declval<T>().to_string())>> : std::true_type {};
template <typename T, typename decay = std::decay_t<T>,
typename C = remove_recursive_top_const_t<remove_recursive_low_const_t<decay>>>
std::string to_string(T&& v) {
// 处理 std::string
if constexpr (std::is_same_v<C, std::string>) {
return std::forward<T>(v);
}
else if constexpr (std::is_same_v<C, void*>) {
std::stringstream ss;
ss << "0x" << std::setw(sizeof(void*) * 2) << std::setfill('0') << std::hex
<< reinterpret_cast<std::uintptr_t>(v);
return ss.str();
}
// 处理 char* 类型
else if constexpr (std::is_same_v<C, char*>) {
return std::string(v);
}
else if constexpr (std::is_same_v<C, const char*>) {
return std::string(v);
}
// 处理 wchar_t* 类型
else if constexpr (std::is_same_v<C, wchar_t*>) {
std::wstring ws(v);
return std::string(ws.begin(), ws.end()); // 简单转换为 std::string
}
else if constexpr (std::is_same_v<C, const wchar_t*>) {
std::wstring ws(v);
return std::string(ws.begin(), ws.end()); // 简单转换为 std::string
}
// 处理 std::wstring 类型
else if constexpr (std::is_same_v<C, std::wstring>) {
return std::string(v.begin(), v.end()); // 将 std::wstring 转为 std::string
}
// 处理枚举类型
else if constexpr (std::is_enum_v<C>) {
return std::string(magic_enum::enum_name(v)); // 使用 magic_enum 转换枚举
}
// 处理 bool 类型
else if constexpr (std::is_same_v<C, bool>) {
return v ? std::string("true") : std::string("false"); // 对 bool 类型进行自定义转换
}
// 处理 std::nullptr_t 类型
else if constexpr (std::is_same_v<C, std::nullptr_t>) {
return std::string("null"); // 对 nullptr 做特殊处理
}
// 处理算术类型(整数或浮点数)
else if constexpr (std::is_arithmetic_v<C>) {
return std::to_string(v); // 使用 std::to_string 转换数值类型
}
else if constexpr (is_atomic_v<C>) {
return to_string(v.load());
}
else if constexpr (is_copyable_atomic_v<C>) {
return to_string(v.load());
}
else if constexpr (is_optional_v<C>) {
return v.has_value() ? to_string(v.value()) : "nullopt";
}
else if constexpr (is_shared_ptr_v<C>) {
if (v) {
return v->to_string();
}
else {
return std::string("null");
}
}
else {
// 没有匹配上 最后走这条路径
if constexpr (has_free_to_string<C>::value) {
return other_to_string(v);
}
else if constexpr (has_member_to_string<C>::value) {
return v.to_string();
}
else {
static_assert(sizeof(C) == 0, "Psc to_string not available for this type");
}
}
return std::string("");
}
template <typename EnumType>
std::optional<EnumType> int_to_enum(int enum_value) {
// 静态断言,确保 EnumType 是枚举类型
static_assert(std::is_enum_v<EnumType>, "EnumType must be an enum type");
// 使用 magic_enum 获取所有的枚举值
auto enum_values = magic_enum::enum_values<EnumType>();
// 检查是否存在匹配的枚举值
for (auto value : enum_values) {
if (static_cast<int>(value) == enum_value) {
return value; // 返回匹配的枚举值
}
}
// 如果没有匹配的枚举值,返回 std::nullopt
return std::nullopt;
}
template <typename EnumType>
std::optional<std::string> enum_int_to_string(int enum_value) {
auto tmp = int_to_enum<EnumType>(enum_value);
if (!tmp.has_value())
return std::nullopt;
return to_string(tmp.value());
}
template <typename Enum>
std::vector<Enum> split_flags(Enum flags) {
static_assert(std::is_enum_v<Enum>, "Template parameter must be an enum type");
std::vector<Enum> setFlags;
for (auto flag : magic_enum::enum_values<Enum>()) {
if ((flags & flag) == flag) {
setFlags.push_back(flag);
}
}
return setFlags;
}
template <typename E>
class enum_error_category : public std::error_category {
static_assert(std::is_enum_v<E>, "E must be an enum");
public:
const char* name() const noexcept override {
// enum_type_name 返回 string_view,静态存储即可
static constexpr auto name_sv = magic_enum::enum_type_name<E>();
return name_sv.data();
}
std::string message(int ev) const override {
auto opt = magic_enum::enum_name(static_cast<E>(ev));
if (!opt.empty())
return std::string(opt);
Psc::fail_fast_core_dump();
return "unknown enum error";
}
};
template <typename E>
std::error_code make_ec(E e) {
static_assert(std::is_enum_v<E>, "E must be an enum");
static enum_error_category<E> cat;
return {static_cast<int>(e), cat};
}
inline std::error_code get_sys_ec() {
return std::error_code(get_error_code(), std::system_category());
}
inline unexpected<std::error_code> get_sys_ex() {
return unexpected<std::error_code>(get_sys_ec());
}
} // namespace Psc