菜鸟笔记
提升您的技术认知

nlohmann/json——nlohmann-ag真人官方网

nlohmann_json_serialize_enum 源码

/*!
@brief macro to briefly define a mapping between an enum and json
@def nlohmann_json_serialize_enum
@since version 3.4.0
*/
#define nlohmann_json_serialize_enum(enum_type, ...)                                    \
    template                                                    \
    inline void to_json(basicjsontype& j, const enum_type& e)                           \
    {                                                                                   \
        static_assert(std::is_enum::value, #enum_type " must be an enum!");  \
        static const std::pair m[] = __va_args__;             \
        auto it = std::find_if(std::begin(m), std::end(m),                              \
            [e](const std::pair& ej_pair) -> bool             \
        {                                                                               \
            return ej_pair.first == e;                                                  \
        });                                                                             \
        j = ((it != std::end(m)) ? it : std::begin(m))->second;                         \
    }                                                                                   \
    template                                                    \
    inline void from_json(const basicjsontype& j, enum_type& e)                         \
    {                                                                                   \
        static_assert(std::is_enum::value, #enum_type " must be an enum!");  \
        static const std::pair m[] = __va_args__;             \
        auto it = std::find_if(std::begin(m), std::end(m),                              \
            [&j](const std::pair& ej_pair) -> bool            \
        {                                                                               \
            return ej_pair.second == j;                                                 \
        });                                                                             \
        e = ((it != std::end(m)) ? it : std::begin(m))->first;                          \
    }

源码分析:

从注释看,nlohmann_json_serialize_enum宏是将用户定义的枚举类型与json进行映射。其实际上是定义了两个模板函数,to_json和from_json,宏的第一个参数enum_type是用户定义的枚举类型,后面携带了可变参数,即...符号。
// asset检查,看enum_type是否是枚举,其中#符号为宏中的特殊运算符,在预编译时期,用于将宏参数转换为字符串
static_assert(std::is_enum::value, #enum_type " must be an enum!");
// __va_args__为系统自定义变量,指向宏中的可变参数
static const std::pair m[] = __va_args__;
// 在可变参数指定的map中查找
auto it = std::find_if(std::begin(m), std::end(m),
    [e](const std::pair& ej_pair) -> bool
{
    return ej_pair.first == e;
});
j = ((it != std::end(m)) ? it : std::begin(m))->second;

使用示例:

enum class type
{
    ktype1 = 0,
    ktype2 = 1,
    ktype3 = 2,
    ktype4 = 3,
    ktype5 = 4
};
nlohmann_json_serialize_enum(type, {
    {type::ktype1, nullptr},
    {type::ktype2, "stopped"},
    {type::ktype3, "running"},
    {type::ktype4, "completed"},
    {type::ktype5, "completed"},
});
int main(int argc, char *argv[])
{
    type t = type::ktype4;
    nlohmann::json j = t;
    std::cout << "dump:" << j.dump() << std::endl;
    return 0;
}

运行结果:

dump:"completed"
网站地图