当前位置: 首页 > news >正文

源码赏析: 数据结构转换工具 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 configorCONFIGOR_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))

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

先下班,后面再续上~~😂

http://www.lryc.cn/news/262456.html

相关文章:

  • 使用java调用python批处理将pdf转为图片
  • 机器学习——自领域适应作业
  • ValidatorUtil字段验证工具类
  • Python 自动化之处理图片(一)
  • Axure动态面板的应用与ERP系统登录界面、主页左侧菜单栏、公告栏的绘制
  • 电机(按工作电源分类)介绍
  • Web前端JS通过使用AudioWorkletNode() 获取 Video/Audio 视音频声道(左右声道|多声道)
  • 力扣LeetCode75题
  • 如何向领导汇报工作?一篇文章告诉你!
  • GPT-4.5!!!
  • kafka入门(四):kafka生产者发送消息
  • redis集群模糊获取缓存redisKey
  • 100GPTS计划-AI翻译TransLingoPro
  • Linux install manual 1Panel
  • 母婴服务品牌网站的效果如何
  • C语言--有一个3*4的矩阵,求出其中最大值的那个元素的值,以及其所在的行号和列号
  • 安全算法(二):共享密钥加密、公开密钥加密、混合加密和迪菲-赫尔曼密钥交换
  • MYSQL练题笔记-高级字符串函数 / 正则表达式 / 子句-简单3题
  • vue扭蛋机抽奖游戏
  • 代码随想录27期|Python|Day16|二叉树|104.二叉树的最大深度|111.二叉树的最小深度|222.完全二叉树的节点个数
  • ༺༽༾ཊ—设计-简介-模式—ཏ༿༼༻
  • Matplotlib快速入门,Python通用的绘图工具库上手
  • Linux 基本语句_16_Udp网络聊天室
  • 使用ffmpeg命令进行视频格式转换
  • Mac安装Adobe AE/pr/LR/ai/ps/au/dw/id 2024/2023报错问题解决(常见错误:已损坏/2700/146/130/127)
  • Python三级 每周练习题31
  • 【DataSophon】大数据服务组件之Flink升级
  • Android笔记(十八):面向Compose组件结合Retrofit2和Rxjava3实现网络访问
  • mybatis中oracle的sql没走索引导致特别慢(未加jdbcType的)
  • QT自带打包问题:无法定位程序输入点?metaobject@qsound