源码赏析: 数据结构转换工具 configor (一)

一、configor

先贴地址 configor,先看configor的特性:

  • Header-only & STL-like
  • Custom type conversion & serialization
  • Complete Unicode support
  • ASCII & Wide-character support
    说白了,这个工具用于自定义类型的转换和序列化/反序列化。目前作者已经实现了任何自定义数据类型转换为流式数据,并可将流式数据转换为json,按照作者的plan,或许会增加ini、xml等格式转换。

二、使用代码示例

struct User
{
    std::string name;
    int age;

    // bind custom type to configor
    CONFIGOR_BIND(json::value, User, REQUIRED(name), OPTIONAL(age))
};

// User -> json
json::value j = User{"John", 18};
// json -> User
User u = json::object{{"name", "John"}, {"age", 18}};

// User -> string
std::string str = json::dump(User{"John", 18});
// string -> User
User u = json::parse("{\"name\": \"John\", \"age\": 18}");

// User -> stream
std::cout << json::wrap(User{"John", 18});
// stream -> User
User u;
std::cin >> json::wrap(u);

三、珠玉撷取

到不至于说这个工具非常强大,同类型的开源项目还有一些,如xpack msgpack,这两个开源项目我们再后面会分享。不过,在框架设计和代码实现上,configor绝对是顶级的,值得好好学习的。精读高级武学功法,勤奋精进,有助于我们彻底打开任督二脉,在c++编码世界里笑傲江湖。

我们关注自定义结构里面这样一个宏:

 CONFIGOR_BIND(json::value, User, REQUIRED(name), OPTIONAL(age))

CONFIGOR_BIND宏函数定义如下:

// Bind custom type to configor value
// e.g.
// CONFIGOR_BIND(json, myclass, REQUIRED(field1), REQUIRED(field2, "field2 name"))
// CONFIGOR_BIND(json, myclass, OPTIONAL(field1), OPTIONAL(field2, "field2 name"))
#define CONFIGOR_BIND(value_type, custom_type, ...)                                                                   \
    friend void to_value(value_type& c, const custom_type& v)                                                         \
    {                                                                                                                 \
        __CONFIGOR_EXPAND(__CONFIGOR_PASTE(__CONFIGOR_COMBINE_PASTE1, __CONFIGOR_TO_CONF_CALL_OVERLOAD, __VA_ARGS__)) \
    }                                                                                                                 \
    friend void from_value(const value_type& c, custom_type& v)                                                       \
    {                                                                                                                 \
        __CONFIGOR_EXPAND(                                                                                            \
            __CONFIGOR_PASTE(__CONFIGOR_COMBINE_PASTE1, __CONFIGOR_FROM_CONF_CALL_OVERLOAD, __VA_ARGS__))             \
    }

粗略一看,实际上就是实现了to_valuefrom_value实现 value_type 与 自定义类型 custom_type之间的转换(序列化与反序列化)。

#define __CONFIGOR_EXPAND(x) x
#define __CONFIGOR_PASTE(parse1, func, ...)                                                                 \
    __CONFIGOR_EXPAND(__CONFIGOR_GET_ARG_MAX50(                                                             \
        __VA_ARGS__, __CONFIGOR_PASTE50, __CONFIGOR_PASTE49, __CONFIGOR_PASTE48, __CONFIGOR_PASTE47,        \
        __CONFIGOR_PASTE46, __CONFIGOR_PASTE45, __CONFIGOR_PASTE44, __CONFIGOR_PASTE43, __CONFIGOR_PASTE42, \
        __CONFIGOR_PASTE41, __CONFIGOR_PASTE40, __CONFIGOR_PASTE39, __CONFIGOR_PASTE38, __CONFIGOR_PASTE37, \
        __CONFIGOR_PASTE36, __CONFIGOR_PASTE35, __CONFIGOR_PASTE34, __CONFIGOR_PASTE33, __CONFIGOR_PASTE32, \
        __CONFIGOR_PASTE31, __CONFIGOR_PASTE30, __CONFIGOR_PASTE29, __CONFIGOR_PASTE28, __CONFIGOR_PASTE27, \
        __CONFIGOR_PASTE26, __CONFIGOR_PASTE25, __CONFIGOR_PASTE24, __CONFIGOR_PASTE23, __CONFIGOR_PASTE22, \
        __CONFIGOR_PASTE21, __CONFIGOR_PASTE20, __CONFIGOR_PASTE19, __CONFIGOR_PASTE18, __CONFIGOR_PASTE17, \
        __CONFIGOR_PASTE16, __CONFIGOR_PASTE15, __CONFIGOR_PASTE14, __CONFIGOR_PASTE13, __CONFIGOR_PASTE12, \
        __CONFIGOR_PASTE11, __CONFIGOR_PASTE10, __CONFIGOR_PASTE9, __CONFIGOR_PASTE8, __CONFIGOR_PASTE7,    \
        __CONFIGOR_PASTE6, __CONFIGOR_PASTE5, __CONFIGOR_PASTE4, __CONFIGOR_PASTE3, __CONFIGOR_PASTE2,      \
        parse1)(parse1, func, __VA_ARGS__))

真吓人啊,别怕。我们心里要始终坚持一点,宏千变万化,本质也是字符串的替换。

#define __CONFIGOR_GET_ARG_MAX50(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
                                 _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36,  \
                                 _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, ARG, ...)       \
    ARG

#define __CONFIGOR_COUNT_ARGS_MAX50(...)                                                                               \
    __CONFIGOR_EXPAND(__CONFIGOR_GET_ARG_MAX50(__VA_ARGS__, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37,    \
                                               36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
                                               18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))

这是一个宏参数计数器,用于统计传入参数的个数。

先下班,后面再续上~~

你可能感兴趣的:(开源之美,C++,c++,数据结构,数据序列化,数据转换)