290 lines
9.1 KiB
C++
290 lines
9.1 KiB
C++
/*
|
||
* 说明:通用宏定义和枚举
|
||
*
|
||
* 作者: 杨海洋
|
||
* 日期: 2023-03-14
|
||
*/
|
||
|
||
#ifndef HDEFINE_H
|
||
#define HDEFINE_H
|
||
|
||
#include "HSystem.h"
|
||
#include "CleverHelper.h"
|
||
|
||
//字面量转化为字符串的宏定义
|
||
#define JUDGE_STR(x) #x
|
||
|
||
#define JUDGE_EXPAND(x) x
|
||
|
||
//可变参数列表
|
||
#define JUDGE_VA_ARGS(...) __VA_ARGS__
|
||
|
||
#ifndef JUDGE_TEMPLATE_DELETE
|
||
# define JUDGE_TEMPLATE_DELETE = delete
|
||
#endif
|
||
|
||
//汉字字符编码统一转换,防止后面有需要
|
||
#define UTF8S(str) u8##str
|
||
#define UTF8RS(str) u8R"(str)"
|
||
|
||
//字符转数字
|
||
#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; //当前进程占用(只针对内存有效,磁盘空间无效)
|
||
};
|
||
|
||
|
||
enum CharsetType
|
||
{
|
||
CharsetTypeUTF8,
|
||
CharsetTypeGBK
|
||
};
|
||
|
||
//============================================================
|
||
using ILock = std::lock_guard<std::mutex>;
|
||
using ULock = std::unique_lock<std::mutex>;
|
||
using IMutex = std::mutex;
|
||
#define IAutoLock(__mtx__) ILock __lock__(__mtx__);
|
||
//============================================================
|
||
|
||
// 辅助模板,用于检测类 T 是否具有名为 is_agree 的成员函数,且该函数接受 const char* 类型参数并返回 bool 类型
|
||
template <typename T, typename = std::void_t<>>
|
||
struct has_member_function_is_agree : std::false_type {};
|
||
|
||
#define has_member_declval decltype(std::declval<T>().is_agree(std::declval<const nlohmann::json&>(),std::declval<const char*>()))
|
||
// 特化模板,使用 SFINAE 检测成员函数
|
||
template <typename T>
|
||
struct has_member_function_is_agree<T, std::void_t<has_member_declval>> : std::is_same<has_member_declval, bool>::type {};
|
||
|
||
// 调用成员函数的模板
|
||
template <typename T>
|
||
bool call_is_agree_if_exists(T& obj, const nlohmann::json& jsonn, const char* param)
|
||
{
|
||
if constexpr (has_member_function_is_agree<T>::value)
|
||
{
|
||
return obj.is_agree(jsonn, param); // 调用成员函数并获取返回值
|
||
}
|
||
else
|
||
{
|
||
//static_assert(has_is_agree<T>::value, "T must have a member function 'is_agree' that accepts a const char* and returns short.");
|
||
}
|
||
return true;
|
||
}
|
||
|
||
class JudgeJsonCheckException : public std::exception //public std::exception nlohmann::json::exception
|
||
{
|
||
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;
|
||
|
||
#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)) \
|
||
{ nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); }
|
||
|
||
#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)) \
|
||
{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
|