290 lines
9.1 KiB
C
Raw Normal View History

2024-09-13 11:17:58 +08:00
/*
* :
*
* :
* : 2023-03-14
*/
#ifndef HDEFINE_H
#define HDEFINE_H
#include "HSystem.h"
#include "CleverHelper.h"
//字面量转化为字符串的宏定义
2024-10-14 14:17:01 +08:00
#define JUDGE_STR(x) #x
2024-09-13 11:17:58 +08:00
2024-10-14 14:17:01 +08:00
#define JUDGE_EXPAND(x) x
2024-09-13 11:17:58 +08:00
//可变参数列表
#define JUDGE_VA_ARGS(...) __VA_ARGS__
#ifndef JUDGE_TEMPLATE_DELETE
# define JUDGE_TEMPLATE_DELETE = delete
#endif
//汉字字符编码统一转换,防止后面有需要
2024-10-14 10:08:35 +08:00
#define UTF8S(str) u8##str
#define UTF8RS(str) u8R"(str)"
2024-09-13 11:17:58 +08:00
//字符转数字
#define CHAR_TO_INT(c) ((c) - '0')
//无效的索引
#define INVALID_INDEX (-1)
#ifdef PI
#undef PI
#endif
#define PI double(3.14159265358979323846)
#ifdef RTOD
#undef RTOD
#endif
#define RTOD (180.0/PI)
#ifdef DTOR
#undef DTOR
#endif
#define DTOR (PI/180.0)
//float最大精度
#define FLOAT_EPSILON std::numeric_limits<float>::epsilon() //1.192092896e-07F
//double最大精度
#define DOUBLE_EPSILON std::numeric_limits<double>::epsilon() //2.2204460492503131e-016
#define EPSILON_F FLOAT_EPSILON
#define EPSILON_2F DOUBLE_EPSILON
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define sdk_usleep(x) std::this_thread::sleep_for(std::chrono::microseconds(x))
#define sdk_msleep(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
#define sdk_ssleep(x) std::this_thread::sleep_for(std::chrono::seconds(x))
//距离单位换算枚举(以毫米为基准单位)
enum DisUnit
{
MM = 1,
CM = MM*10, //centimeter = 1000,
DM = CM*10, //decimetre
MI = DM*10, //meter
KM = MI*1000, //kilometer
};
//时间单位换算枚举(以毫秒为基准单位)
enum TimeUnit
{
SECOND = 1000,
MINUTE = (60 * SECOND),
HOUR = (60 * MINUTE),
DAY = (24 * HOUR),
WEEK = ( 7 * DAY),
};
struct DateTimex
{
int year = 0; //年
int month = 0; //月
int day = 0; //日
int hour = 0; //时
int minute = 0; //分
int second = 0; //秒
int weekday = 0; //周几 周日是0
};
//内存和磁盘空间单位换算枚举(以字节为基准单位)
enum SpaceUnit
{
KB = 1024,
MB = (1024 * KB),
GB = (1024 * MB),
};
struct SpaceStorage
{
int64 spaceTotal = 0; //总的
int64 spaceFree = 0; //空闲
int64 spaceAvailable = 0; //可用
int64 spaceSelf = 0; //当前进程占用(只针对内存有效,磁盘空间无效)
};
2024-10-14 14:17:01 +08:00
enum CharsetType
{
CharsetTypeUTF8,
CharsetTypeGBK
};
2024-09-13 11:17:58 +08:00
//============================================================
using ILock = std::lock_guard<std::mutex>;
using ULock = std::unique_lock<std::mutex>;
using IMutex = std::mutex;
#define IAutoLock(__mtx__) ILock __lock__(__mtx__);
//============================================================
2024-10-14 10:08:35 +08:00
// 辅助模板,用于检测类 T 是否具有名为 is_agree 的成员函数,且该函数接受 const char* 类型参数并返回 bool 类型
template <typename T, typename = std::void_t<>>
struct has_member_function_is_agree : std::false_type {};
2024-09-13 11:17:58 +08:00
2024-10-14 10:08:35 +08:00
#define has_member_declval decltype(std::declval<T>().is_agree(std::declval<const nlohmann::json&>(),std::declval<const char*>()))
2024-09-13 11:17:58 +08:00
// 特化模板,使用 SFINAE 检测成员函数
template <typename T>
2024-10-14 10:08:35 +08:00
struct has_member_function_is_agree<T, std::void_t<has_member_declval>> : std::is_same<has_member_declval, bool>::type {};
2024-09-13 11:17:58 +08:00
// 调用成员函数的模板
template <typename T>
2024-10-14 10:08:35 +08:00
bool call_is_agree_if_exists(T& obj, const nlohmann::json& jsonn, const char* param)
2024-09-13 11:17:58 +08:00
{
2024-10-14 10:08:35 +08:00
if constexpr (has_member_function_is_agree<T>::value)
{
return obj.is_agree(jsonn, param); // 调用成员函数并获取返回值
}
else
2024-09-13 11:17:58 +08:00
{
2024-10-14 10:08:35 +08:00
//static_assert(has_is_agree<T>::value, "T must have a member function 'is_agree' that accepts a const char* and returns short.");
2024-09-13 11:17:58 +08:00
}
return true;
}
2024-10-14 10:08:35 +08:00
class JudgeJsonCheckException : public std::exception //public std::exception nlohmann::json::exception
2024-09-13 11:17:58 +08:00
{
public:
JudgeJsonCheckException() {}
JudgeJsonCheckException(const std::string& e) : m_exceptions(e) {}
virtual ~JudgeJsonCheckException() {}
virtual const char* what() const noexcept override { return m_exceptions.c_str(); }
bool has_exception() { return !m_exceptions.empty(); }
template<typename TMember, typename TFather>
inline bool json_check(const nlohmann::json& jsonn, const char* key, const TMember& child, const TFather& father)
{
nlohmann::json parent(father);
nlohmann::json member(child);
if(!jsonn.contains(key))
{
json_exception("'%s' member '%s' not has!!! \n", typeid(father).name(), key);
return false;
}
const nlohmann::json& jmember = jsonn.at(key);
if(jmember.is_null())
{
json_exception("'%s' member '%s' is null!!! \n", typeid(father).name(), key);
return false;
}
if(member.is_number_integer())
{
if(!jmember.is_number_integer())
{
json_exception("'%s' member '%s' type must be '%s', but is '%s'!!! \n",
typeid(father).name(), key, type_name(member), type_name(jmember));
return false;
}
}
else if(member.is_number_float())
{
if(!jmember.is_number())
{
json_exception("'%s' member '%s' type must be '%s', but is '%s'!!! \n",
typeid(father).name(), key, type_name(member), type_name(jmember));
return false;
}
}
else
{
if(jmember.type() != member.type())
{
json_exception("'%s' member '%s' type must be '%s', but is '%s'!!! \n",
typeid(father).name(), key, type_name(member), type_name(jmember));
return false;
}
}
return true;
}
template<typename... Args>
inline void json_exception(const char* format, Args... args) noexcept
{
char buf[256] = {0};
snprintf(buf, sizeof(buf), format, args...);
m_exceptions += buf;
}
const char* type_name(const nlohmann::json& jsonn) const noexcept
{
nlohmann::json::value_t type = jsonn.type();
switch (type)
{
case nlohmann::json::value_t::number_integer: return "integer";
case nlohmann::json::value_t::number_unsigned: return "unsigned";
case nlohmann::json::value_t::number_float: return "[double]float";
default: return jsonn.type_name(); //上面三个都会返回number所以加上区分下方便看
}
}
private:
std::string m_exceptions;
};
#ifdef JUDGE_USE_STRICT
#define JUDGE_JSON_EXCEPTION(e) throw JudgeJsonCheckException(e);
#else
#define JUDGE_JSON_EXCEPTION(e) logerror("error-json=%s", e.what());
#endif
#define JUDGE_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2024-10-14 10:08:35 +08:00
#define JUDGE_JSON_FROM(v1) \
if(call_is_agree_if_exists(nlohmann_json_t, nlohmann_json_j, #v1) && \
check.json_check(nlohmann_json_j, #v1, nlohmann_json_t.v1, nlohmann_json_t)) \
2024-09-13 11:17:58 +08:00
{ nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); }
2024-10-14 10:08:35 +08:00
#define JUDGE_JSON_FROM_DEFAULT(v1) \
if(call_is_agree_if_exists(nlohmann_json_t, nlohmann_json_j, #v1) && \
check.json_check(nlohmann_json_j, #v1, nlohmann_json_t.v1, nlohmann_json_t)) \
2024-09-13 11:17:58 +08:00
{nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);}
#define JUDGE_JSON_METHOD(mode,to,from,Type,...) \
mode void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(to, __VA_ARGS__)) \
} \
mode void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
Type nlohmann_json_default_obj{}; JudgeJsonCheckException check; \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(from, __VA_ARGS__)); \
if(check.has_exception()) { JUDGE_JSON_EXCEPTION(check); } \
}
/*
*
*/
#define JUDGE_JSON_INTRUSIVE(Type, ...) \
JUDGE_JSON_METHOD(friend, JUDGE_JSON_TO, JUDGE_JSON_FROM, Type, __VA_ARGS__)
#define JUDGE_JSON_INTRUSIVE_DEFAULT(Type, ...) \
JUDGE_JSON_METHOD(friend, JUDGE_JSON_TO, JUDGE_JSON_FROM_DEFAULT, Type, __VA_ARGS__)
/*
*
*/
#define JUDGE_JSON_NON_INTRUSIVE(Type, ...) \
JUDGE_JSON_METHOD(inline, JUDGE_JSON_TO, JUDGE_JSON_FROM, Type, __VA_ARGS__)
#define JUDGE_JSON_NON_INTRUSIVE_DEFAULT(Type, ...) \
JUDGE_JSON_METHOD(inline, JUDGE_JSON_TO, JUDGE_JSON_FROM_DEFAULT, Type, __VA_ARGS__)
#define JUDGE_JSON_DEFINE JUDGE_JSON_INTRUSIVE
#endif // HDEFINE_H