This commit is contained in:
UnknownObject
2026-06-30 17:49:51 +08:00
commit 292c09619e
200 changed files with 23718 additions and 0 deletions
+254
View File
@@ -0,0 +1,254 @@
#pragma once
#include <ctime>
#include <string>
#include <vector>
#include <chrono>
#include <variant>
#include "Export.h"
#include <functional>
#include <string_view>
#include <type_traits>
namespace uns
{
// 前置声明捕获器
struct RangeCapturer;
struct PairCapturer;
struct FuncCapturer;
struct TimeCapturer;
// 终极 Variant 池:容纳所有可能解包出的原子形态
using LogVariant = std::variant<
bool, char, int, unsigned int, long long, unsigned long long, double, std::string_view, const void*,
std::string, // 专门用于承载宽字符转换后的 UTF-8 临时字符串
RangeCapturer, // 专门用于承载 std::vector / std::list 等容器
PairCapturer, // 专门用于承载 std::pair (支持 std::map)
FuncCapturer, //承载 std::function
TimeCapturer //承载时间
>;
// --- 编译期类型推导工具链 ---
template <typename T, typename = void>
struct is_container : std::false_type
{
};
// 识别标准容器(排除字符串本身)
template <typename T>
struct is_container<T, std::void_t<typename T::value_type, decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())>> : std::integral_constant<bool, !std::is_same_v<T, std::string> && !std::is_same_v<T, std::string_view>>
{
};
template <typename T> struct is_pair : std::false_type
{
};
template <typename F, typename S> struct is_pair<std::pair<F, S>> : std::true_type
{
};
// --- 延迟桥接结构体 ---
struct LogArg;
struct RangeCapturer
{
const void* ptr;
void (*to_log_args)(const void*, std::vector<LogArg>&);
};
struct PairCapturer
{
const void* ptr;
void (*to_log_args)(const void*, std::vector<LogArg>&);
};
struct FuncCapturer
{
const void* code_ptr; // 真正改变:这里存真正的函数代码地址
bool is_closure; // 标记:这究竟是个纯函数,还是个 Lambda 闭包
};
// 升级版 Trait:不仅识别,还提取原生函数指针类型(R(*)(Args...))
template <typename T> struct function_traits
{
static constexpr bool is_func = false;
using pointer_type = void*;
};
template <typename R, typename... Args>
struct function_traits<std::function<R(Args...)>>
{
static constexpr bool is_func = true;
using pointer_type = R(*)(Args...); // 提取出原生函数指针类型
};
enum class TimeMode
{
Point,
TMPoint,
Duration
};
struct TimeCapturer
{
TimeMode mode{ TimeMode::Point };
std::tm _tm{};
std::chrono::system_clock::time_point tp{};
std::chrono::nanoseconds duration{ 0 };
std::string format_spec; // "%Y-%m-%d %H:%M:%S" or empty
// 可选:单位策略控制
bool smart_unit = true;
};
template<typename T>
struct is_time_point : std::false_type
{
};
template<typename Clock, typename Dur>
struct is_time_point<std::chrono::time_point<Clock, Dur>> : std::true_type
{
};
template<>
struct is_time_point<std::tm> : std::true_type
{
};
template<typename T>
inline constexpr bool is_time_point_v = is_time_point<T>::value;
template<typename T>
struct is_duration : std::false_type
{
};
template<typename Rep, typename Period>
struct is_duration<std::chrono::duration<Rep, Period>> : std::true_type
{
};
template<typename T>
inline constexpr bool is_duration_v = is_duration<T>::value;
inline TimeCapturer MakeTimeCapturer(std::chrono::system_clock::time_point tp)
{
TimeCapturer c;
c.mode = TimeMode::Point;
c.tp = tp;
return c;
}
template<typename Rep, typename Period>
inline TimeCapturer MakeTimeCapturer(std::chrono::duration<Rep, Period> d)
{
TimeCapturer c;
c.mode = TimeMode::Duration;
c.duration = std::chrono::duration_cast<std::chrono::nanoseconds>(d);
c.smart_unit = true;
return c;
}
inline TimeCapturer MakeTimeCapturer(const std::tm& tm)
{
TimeCapturer c;
c.mode = TimeMode::TMPoint;
c._tm = tm;
return c;
}
// --- 宽字符转换声明(实现卸载到 .cpp) ---
std::string UNSWSC_DLL_EXPORT ConvertWStringToUtf8(std::wstring_view wstr);
// --- 核心包装类 ---
struct LogArg
{
LogVariant value;
template<typename T>
LogArg(T&& val)
{
using D = std::decay_t<T>;
// 1. 窄字符串系列(0拷贝)
if constexpr (std::is_same_v<D, std::string> || std::is_same_v<D, std::string_view>)
value = std::string_view(val);
else if constexpr (std::is_same_v<D, const char*> || std::is_same_v<D, char*>)
value = val ? std::string_view(val) : std::string_view("<null>");
// 2. 宽字符串系列(特殊处理:触发内部 UTF-8 转换)
else if constexpr (std::is_same_v<D, std::wstring> || std::is_same_v<D, std::wstring_view>)
value = ConvertWStringToUtf8(val);
else if constexpr (std::is_same_v<D, const wchar_t*> || std::is_same_v<D, wchar_t*>)
value = val ? ConvertWStringToUtf8(val) : std::string("<null>");
// 3. 基础原子类型(防范 wchar_t 被误判为整数)
else if constexpr (std::is_same_v<D, wchar_t> || std::is_same_v<D, char16_t> || std::is_same_v<D, char32_t>)
value = ConvertWStringToUtf8(std::wstring_view((const wchar_t*)&val, 1));
else if constexpr (std::is_same_v<D, bool>)
value = static_cast<bool>(val);
else if constexpr (std::is_same_v<D, char> || std::is_same_v<D, signed char>)
value = static_cast<char>(val);
// 3.5 时间点类型系列(防止时间对象退化为未知类型)
else if constexpr (is_time_point_v<D>)
value = MakeTimeCapturer(val);
else if constexpr (is_duration_v<D>)
value = MakeTimeCapturer(val);
// 4. 全整型变种矩阵 (short, int, long, long long, unsigned...)
else if constexpr (std::is_integral_v<D> && std::is_signed_v<D>)
{
if constexpr (sizeof(D) <= sizeof(int))
value = static_cast<int>(val);
else
value = static_cast<long long>(val);
}
else if constexpr (std::is_integral_v<D> && std::is_unsigned_v<D>)
{
if constexpr (sizeof(D) <= sizeof(unsigned int))
value = static_cast<unsigned int>(val);
else
value = static_cast<unsigned long long>(val);
}
// 5. 浮点矩阵
else if constexpr (std::is_floating_point_v<D>)
value = static_cast<double>(val);
// 6. 指针
else if constexpr (std::is_pointer_v<D>)
value = static_cast<const void*>(val);
// 7. 标准库容器(关键点:利用 Lambda 闭包在不引入 fmt 的情况下擦除容器类型!)
else if constexpr (is_container<D>::value)
{
value = RangeCapturer{ &val, [] (const void* p, std::vector<LogArg>& out)
{
for (const auto& item : *static_cast<const D*>(p))
out.emplace_back(item); // 递归包装子元素
}
};
}
// 8. 键值对(支持 Map 展开)
else if constexpr (is_pair<D>::value)
{
value = PairCapturer{ &val, [] (const void* p, std::vector<LogArg>& out)
{
const auto& pair = *static_cast<const D*>(p);
out.emplace_back(pair.first);
out.emplace_back(pair.second);
}
};
}
else if constexpr (function_traits<D>::is_func)
{
using TargetPtr = typename function_traits<D>::pointer_type;
// 关键点:尝试用 target() 拿底层指针
// std::function::target<T>() 返回的是 T*,所以如果 T 是函数指针,返回的就是“函数指针的指针”
if (auto* const* func_ptr = val.template target<TargetPtr>()) // 情况 A:内部装的是普通纯函数或静态成员函数
value = FuncCapturer{ reinterpret_cast<const void*>(*func_ptr), false };
else // 情况 B:内部装的是 Lambda 表达式或带状态的仿函数, 此时它在堆/栈上有一个闭包实体,我们退而求其次,打印这个闭包对象的地址
value = FuncCapturer{ static_cast<const void*>(&val), true };
}
else
value = std::string_view("<unsupported type>");
}
};
}