当前位置: 首页 > 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))

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

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

相关文章:

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

一、configor 先贴地址 configor&#xff0c;先看configor的特性&#xff1a; Header-only & STL-likeCustom type conversion & serializationComplete Unicode supportASCII & Wide-character support 说白了&#xff0c;这个工具用于自定义类型的转换和序列化…...

使用java调用python批处理将pdf转为图片

你可以使用Java中的ProcessBuilder来调用Python脚本&#xff0c;并将PDF转换为图片。以下是一个简单的Java代码示例&#xff0c;假设你的Python脚本名为pdf2img.py&#xff1a; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader…...

机器学习——自领域适应作业

任务 游戏里面的话有很多跟现实不一样的情况。 想办法让中间的特征更加的接近&#xff0c;让feat A适应feat B&#xff0c;产生相对正常的输出。 在有标签数据和没有数据的上面进行训练&#xff0c;并能预测绘画图像。 数据集 训练5000张总数&#xff0c;每类有500张测试100…...

ValidatorUtil字段验证工具类

字段验证工具类 package com.aa.bb.cc.common.utils;import com.aa.bb.cc.common.exception.BusinessException; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils;import javax.validation.ConstraintViolation; import…...

Python 自动化之处理图片(一)

图片美化与大小调整 文章目录 图片美化与大小调整前言一、基本结构二、引入库三、用户输入模块四、图片美化模块五、大小调整模块总结 前言 本文主要分为两部分。一是图片的美化吧算是&#xff0c;主要从亮度、对比、色彩饱和度、锐度四个方面进行美化&#xff1b;二是图片的像…...

Axure动态面板的应用与ERP系统登录界面、主页左侧菜单栏、公告栏的绘制

目录 一、动态面板 1.1 简介 1.2 使用动态面板的原因 二、动态面板之轮播图实现案例 2.1 完成步骤 2.2 最终效果 三、动态面版之多方式登录案例 四、动态面板之后台主界面左侧菜单栏 五、ERP登录界面 六、ERP主界面菜单栏 七、ERP公告栏 八、登录页面跳转公告栏 一…...

电机(按工作电源分类)介绍

文章目录 一、什么是电机&#xff1f;二、按工作电源分类直流电机1.直流有刷电机结构工作原理&#xff1a;直流减速电机 2.直流无刷电机结构工作原理&#xff1a; 3.总结结构和工作原理&#xff1a;效率和功率损耗&#xff1a;调速性能&#xff1a;寿命和可靠性&#xff1a;应用…...

Web前端JS通过使用AudioWorkletNode() 获取 Video/Audio 视音频声道(左右声道|多声道)

写在前面&#xff1a; 在之前的博文Web前端JS如何获取 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据中&#xff0c;介绍了通过使用AudioContext.createScriptProcessor()方法来获取视音频音轨&#xff08;声道&#xff09;数据。但由于W3C不再推荐使用该A…...

力扣LeetCode75题

为了面试&#xff0c;小伙伴们可以平时练下算法题&#xff0c;有备无患。 LeetCode 75 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台...

如何向领导汇报工作?一篇文章告诉你!

给领导汇报工作可以从两个方面考虑&#xff1a;一是工作汇报文件的制作&#xff1b;一是汇报方式。一份全面、清晰且准确的文件&#xff0c;加上一目了然的、科技满满的汇报方式&#xff0c;相比领导不满意都难&#xff5e;下面就让你全部get&#xff01; 一、工作汇报的文字内…...

GPT-4.5!!!

GPT-4 还没用明白&#xff0c;GPT-4.5 就要发布了。 最近&#xff0c;OpenAI 泄露了 GPT-4.5 的发布页面&#xff0c;除了进一步增强复杂推理和跨模态理解&#xff0c;GPT-4.5 增加了一个更加强大的功能——3D。 3D 功能的进一步支持&#xff0c;也就意味着多模态最后一块版图…...

kafka入门(四):kafka生产者发送消息

创建生产者实例和构建消息之后&#xff0c;就可以开始发送消息了。 发送消息主要有三种模式&#xff1a;发后即忘、同步、异步。 发后即忘&#xff1a; 就是直接调用 生产者的 send方法发送。 发后即完&#xff0c;只管往 kafka中发送消息&#xff0c;而不关心消息是否正确…...

redis集群模糊获取缓存redisKey

redis cluster集群删除指定模糊redisKey的信息 **public int deleteRedisKey(String key){AtomicReference<Integer> result new AtomicReference<>(0);busnessLogger.info("开始删除指定业务的模糊Key,deleteRedisKey:{}",key);try{Set<HostAndPor…...

100GPTS计划-AI翻译TransLingoPro

地址 https://poe.com/TransLingoPro https://chat.openai.com/g/g-CfT8Otig6-translingo-pro 测试 输入: 我想吃中国菜。 预期翻译: I want to eat Chinese food. 输入: 请告诉我最近的医院在哪里。 预期翻译: Please tell me where the nearest hospital is. 输入: 明天…...

Linux install manual 1Panel

前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。1Panel 的功能和优势包括: 快速建站:深度集成 Wordpress 和 Halo,域名绑定、SSL 证书配置等一键搞定;高效管理:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等;安全可…...

母婴服务品牌网站的效果如何

随着三胎政策落实及人们生活水平提升&#xff0c;母婴市场发展迅速上升&#xff0c;加之以90后、00后适龄生育的人群悦己消费加强&#xff0c;孕前孕后及婴儿本身就会使用相当好的服务&#xff0c;这也为市场带来了较大机会。 近几年&#xff0c;老品牌在不断加力&#xff0c;…...

C语言--有一个3*4的矩阵,求出其中最大值的那个元素的值,以及其所在的行号和列号

一.题目描述 有一个3*4的矩阵&#xff0c;要求求出其中最大值的那个元素的值&#xff0c;以及其所在的行号和列号 比如&#xff1a;给定一个3*4的矩阵如下 输出结果&#xff1a;最大值为 12 &#xff0c;行号为3&#xff0c; 列号为2 二.思路分析 打擂台算法&#xff1a; 先思考…...

安全算法(二):共享密钥加密、公开密钥加密、混合加密和迪菲-赫尔曼密钥交换

安全算法&#xff08;二&#xff09;&#xff1a;共享密钥加密、公开密钥加密、混合加密和迪菲-赫尔曼密钥交换 本章介绍了共享密钥加密、公开密钥加密&#xff0c;和两种加密方法混合使用的混合加密方法&#xff1b;最后介绍了迪菲-赫尔曼密钥交换。 加密数据的方法可以分为…...

MYSQL练题笔记-高级字符串函数 / 正则表达式 / 子句-简单3题

这个系列先写了三题&#xff0c;比较简单写在一起。 1.修复表中的名字相关的表和题目如下 看题目就知道是有关字符串函数的&#xff0c;于是在书里查询相关的函数&#xff0c;如下图&#xff0c;但是没有完全对口的函数&#xff0c;所以我还是去百度了。 然后发现结合上面的4个…...

vue扭蛋机抽奖游戏

简易扭蛋机demo 这是一个使用CSS3和JavaScript实现的扭蛋机抽奖游戏。该游戏的主要功能是通过点击按钮进行抽奖,抽奖过程中会显示滚动的小球,最终随机停止并显示一个中奖小球。 该游戏的抽奖过程如下: 当用户点击抽奖按钮时,首先检查当前是否正在进行抽奖任务或者当前有小…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...