libco 宏分析

news2024/11/27 21:08:12
// 下面是从libco中导出的宏
#include <iostream>
using namespace std;

/*
	以下是计算参数的个数,最多支持7个参数
*/
#define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ )
#define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N
#define comac_args_seqs() 7,6,5,4,3,2,1,0
#define comac_join_1( x,y ) x##y // 将两个名字变成一个字符串"xy"

#define comac_argc( ... ) comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs() )
#define comac_join( x,y) comac_join_1( x,y )

// 以下是用作重复,fun是下面typeof中的一种,重复次数取决去参数个数
#define repeat_0( fun,a,... ) 
#define repeat_1( fun,a,... ) fun( 1,a,__VA_ARGS__ ) repeat_0( fun,__VA_ARGS__ )
#define repeat_2( fun,a,... ) fun( 2,a,__VA_ARGS__ ) repeat_1( fun,__VA_ARGS__ )
#define repeat_3( fun,a,... ) fun( 3,a,__VA_ARGS__ ) repeat_2( fun,__VA_ARGS__ )
#define repeat_4( fun,a,... ) fun( 4,a,__VA_ARGS__ ) repeat_3( fun,__VA_ARGS__ )
#define repeat_5( fun,a,... ) fun( 5,a,__VA_ARGS__ ) repeat_4( fun,__VA_ARGS__ )
#define repeat_6( fun,a,... ) fun( 6,a,__VA_ARGS__ ) repeat_5( fun,__VA_ARGS__ )

#define repeat( n,fun,... ) comac_join( repeat_,n )( fun,__VA_ARGS__)

// 以下是功能
/*
	decl_typeof宏的作用是为参数类型取别名
	impl_typeof 是创建对应类型的引用
	impl_typeof_cpy 是创建类型对象
	con_param_typeof 是创建变量名
	param_init_typeof 是通过初始化列表初始化变量
*/
#if __cplusplus <= 199711L
#define decl_typeof( i,a,... ) typedef typeof( a ) typeof_##a;
#else
#define decl_typeof( i,a,... ) typedef decltype( a ) typeof_##a;
#endif
#define impl_typeof( i,a,... ) typeof_##a & a;
#define impl_typeof_cpy( i,a,... ) typeof_##a a;
#define con_param_typeof( i,a,... ) typeof_##a & a##r,
#define param_init_typeof( i,a,... ) a(a##r),


#define co_ref( name,... ) \
repeat( comac_argc(__VA_ARGS__) ,decl_typeof,__VA_ARGS__ ) \
class type_##name \
{ \
public: \
	repeat( comac_argc(__VA_ARGS__) ,impl_typeof,__VA_ARGS__ ) \
	int _member_cnt; \
	type_##name( \
		repeat( comac_argc(__VA_ARGS__),con_param_typeof,__VA_ARGS__ ) ... ): \
		repeat( comac_argc(__VA_ARGS__),param_init_typeof,__VA_ARGS__ ) _member_cnt(comac_argc(__VA_ARGS__)) \
	{} \
} name( __VA_ARGS__ )


int main(int argc, char **argv)
{
    int total = 100;
	co_ref(ref, total);

    cout << ref.total << endl;
    cout << comac_argc( 0, 1, 2) << endl;
    return 0;
}

运行后结果
在这里插入图片描述

// 预处理后
typedef decltype( total ) typeof_total;
class type_ref {
public: 
  typeof_total & total; 
  int _member_cnt; 
  type_ref( typeof_total & totalr, ... ): total(totalr), _member_cnt(1) {}
} ref( total );

cout << ref.total << endl;
cout << 3 << endl;

下面详细解释下如何计算参数个数的

// 重点就在这三个宏
#define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ )
#define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N
#define comac_args_seqs() 7,6,5,4,3,2,1,0

// 这个宏是为了方便使用而写的
#define comac_argc( ... ) comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs())

原理就是占位,前面的参数占位后,会将comac_args_seqs()往后移动,占用几位会移动几位
这样就会使用N永远对应着正确的数字,如果想要在增加想要计算的参数个数,可以如下
#define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,_8, N,...) N
#define comac_args_seqs() 8,7,6,5,4,3,2,1,0
comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs())这个宏的第一个参数是0,意味着当无参数时会主动占用一位,此时N对应的正好是0

// 下面一步一步的展示预处理结果
comac_argc(); // 无参情况下计算参数个数
// 预处理
comac_get_args_cnt(0, comac_args_seqs())
// 预处理
//comac_arg_n(_0,_1,_2,_3,_4,_5,_6,_7, N,...)
  comac_arg_n( 0, 7, 6, 5, 4, 3, 2, 1, 0);
// 此时N对应的数字正好是0,所以comac_argc()返回的结果就是0
// 当为一个参数时
comac_argc("Hello World");

comac_get_args_cnt(0,"Hello World", comac_args_seqs());

//comac_arg_n(_0,            _1,_2,_3,_4,_5,_6,_7, N,...)
  comac_arg_n( 0, "Hello World", 7, 6, 5, 4, 3, 2, 1, 0);

// 此时N对应的数字正好是1

后记
当第一次看见这个宏时还不清楚是干什么的,所以未在意,但是在读源码过程中发现必须得先清楚的了解这个宏后才能继续读,所以进行了分析。起初是先自行分析,发现进展不大,就写代码,预处理
但是对于comac_argc这个宏来说预处理结果就是一个数字,所以自己只能通过一步一步的替换来分析,好在功夫不负有心人,弄明白了。最后再说下libco写下这个宏的作用,其实上述是经过我删减的,libco中co_func是一个函数宏,就是给定函数名,函数体由自己实现,这个宏的作用是为协程创建闭包用的

int total = 100;
vector<int> v2;
co_ref(ref, total, v2, m);
for (int i = 0; i < 10; i++)
{
	co_func(f, ref, i)
	{
		printf("tid: %d; ref.total %d i %d\n", gettid(), ref.total, i);
		// lock
		pthread_mutex_lock(&ref.m);
		ref.v2.push_back(i);
		pthread_mutex_unlock(&ref.m);
		// unlock
	}
	co_func_end;
	v.push_back(new f(ref, i));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/92002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

完整的PCB生产工艺到底是怎样的?华秋告诉你

前面&#xff0c;与朋友们分享了一些关于PCB生产工艺的事情。 有的朋友看了后非常感兴趣&#xff0c;私信说——现在的各种PCB资料满天飞&#xff0c;经常彼此间相互不一致&#xff0c;甚至对立&#xff0c;能给我们再讲讲&#xff0c;完整的PCB生产工艺到底是怎样的吗&#x…

Java 8函数式编程

函数式接口 一个接口中&#xff0c;有且只有一个抽象方法&#xff0c;这个接口就叫做函数式接口。常常使用FunctionalInterface注解作为编译校验。满足函数式接口的要求&#xff0c;才能校验通过&#xff0c;否则会在校验阶段失败。 接口中有且只能有一个抽象方法&#xff0c;…

STM32F4 | 外部中断实验

文章目录一、STM32F4 外部中断简介二、硬件设计三、软件设计四、实验现象五、STM32CubeMX 配置外部中断本章我们将介绍如何将 STM32F429 的 IO 口作为外部中断输入。一、STM32F4 外部中断简介 这里首先介绍STM32F4 IO 口中断的一些基础概念。STM32F4 的每个 IO 都可以作为外部…

实验五图形用户界面编程

目录 一、目的与任务 二、内容、要求与安排方式 三、实验设备 四、实验步骤 一、目的与任务 掌握常用事件及其处理模型&#xff1b;掌握常用GUI控制组件的使用及其事件的处理&#xff1b;掌握菜单的使用以及对话框的使用。 二、内容、要求与安排方式 1、实验内容与要求&…

SpringCloud系列(五)Nacos 注册中心配置管理的设置及使用

介绍几种 Nacos 常用的配置, 如统一配置管理的步骤, 如何配置自动刷新及多环境配置优先级问题. Nacos 配置管理⚽️ 统一配置管理⚽️⚽️配置自动刷新⚽️⚽️⚽️ 多环境配置优先级⚽️ 统一配置管理 步骤一: 在 Nacos 中添加配置信息, 如添加时间格式的配置内容; 步骤二: …

Ribbon实战与原理剖析

一、ribbon概述 1、ribbon简介 目前主流的负载方案分为以下两种&#xff1a; 集中式负载均衡&#xff0c;在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如 F5&#xff09;&#xff0c;也有软件的&#xff08;比如 Nginx&#xff0…

读写锁的学习与实验

目录 目录 1&#xff0c;场景 2&#xff0c;接口 3&#xff0c;场景模拟 1&#xff0c;场景 有一种场景&#xff0c;读者多&#xff0c;写者少&#xff0c;绝大多数的情况下我们都是在进行读取而不修改&#xff0c;只有少数的情况下我们才会修改。 场景一&#xff1a;比如…

解决jenkins构建失败,空间不足问题

随着构建次数过多&#xff0c;之后jenkins构建会出现空间不足的问题&#xff0c;解决方式如下&#xff1a; 目录 1.配置时&#xff0c;去除旧的构建任务 2.使用脚本&#xff0c;删除历史构建 3.清理磁盘空间 4.重新加载服务器节点 1.配置时&#xff0c;去除旧的构建任务 2…

计算机网络(自顶向下)学习笔记——路由选择算法

第五章—路由选择算法 5.1、路由的概念 路由:按照某种指标(传输延迟,所经过的站点数目等)找到一条 从源节点到目标节点的较好路径 较好路径: 按照某种指标较小的路径指标:站数, 延迟,费用,队列长度等, 或者是一些单纯指标的加权平均采用什么样的指标,表示网络使用者希望网络…

m基于优化算法的多车辆的路径规划matlab仿真,对比GA,PSO以及烟花算法

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 路径规划是运动规划的主要研究内容之一。运动规划由路径规划和轨迹规划组成&#xff0c;连接起点位置和终点位置的序列点或曲线称之为路径&#xff0c;构成路径的策略称之为路径规划。路径规划在…

微软12月多个安全漏洞修复解决方案

安全狗应急响应中心监测到&#xff0c;微软发布了2022年12月份安全更新&#xff0c;事件等级&#xff1a;严重&#xff0c;事件评分&#xff1a;10.0。此次安全更新发布了52个漏洞的补丁&#xff0c;主要覆盖了以下组件&#xff1a;Azure; Office and Office Components; SysIn…

提高电网的稳态稳定性(Matlab代码实现)

目录 1 概述 2 稳态稳定性分析 2.1 系统模型 2.2 稳态稳定性 2.3 问题说明 3 仿真结果 4 一点小智慧 5 Matlab代码实现 1 概述 随着电力系统的复杂性和规模的增加&#xff0c;电力系统的有效控制变得越来越困难。我们提出了一种自动控制策略&#xff0c;该策略基于通过…

如何使用typeScript实现贪吃蛇游戏?

1.配置文件 配置文件写过一次之后&#xff0c;可以复制粘贴使用&#xff0c;修改部分细节就可以了。 package.json {"name": "snake","version": "1.0.0","description": "","main": "index.js&q…

网络协议——RPC协议综述

拿最简单的场景&#xff0c;客户端调用一个加法函数&#xff0c;将两个整数加起来&#xff0c;返回它们的和。 如果放在本地调用&#xff0c;那是简单的不能再简单了&#xff0c;。但是一旦变成了远程调用&#xff0c;门槛一下子就上去了。 如何解决这五个问题&#xff1f; …

秦力洪复盘2022:蔚来的长板和误判

作者 | 张祥威 编辑 | 王博最初我们看蔚来&#xff0c;觉得它是中国的特斯拉。后来它主动挑战宝马&#xff0c;以46万的平均单价在高端品牌阵营厮杀&#xff0c;看上去又具备成为宝马的潜力。再到后来&#xff0c;蔚来宣布将推出全新品牌&#xff0c;喊话月销5万辆&#xff0c;…

[附源码]Nodejs计算机毕业设计基于大数据的高校国有固定资产管理及绩效自动评价系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Django学习15 -- 验证码

1. 验证码 验证码&#xff08;CAPTCHA&#xff0c;Completely Automated Public Turing test to tell Computers and Humans Apart&#xff09;&#xff0c;全自动区分计算机和人类的图灵测试的简称&#xff0c;一种区分用户是计算机还是人的公共全自动程序。防止恶意破解密码、…

Java+Swing+mysql实现学生选课管理系统

JavaSwing实现学生选课管理系统一、系统介绍二、系统展示1.课程查询2.课程添加3.退课三、系统实现四、其他1.其它系统2.获取源码一、系统介绍 本系统实现了学生登录和管理员登录&#xff0c;学生实现选课&#xff0c;查看已选课程&#xff0c;修改密码&#xff0c;查看学生信息…

Vue.use 与 Vue.prototype 在注册插件时,使用上有什么区别

很多使用Vue开发的童鞋&#xff0c;可能对Vue的原型对象prototype有了解过&#xff0c;但对于Vue.use只知如何使用&#xff0c;却不知其背后的含义。那么&#xff0c;今天我们就来瞧一瞧Vue.use()背后的逻辑。 &#x1f388; 首先&#xff0c;Vue.use()是什么&#xff1f; 官方…

外汇天眼:投资200美元起 每天收益7%!千万别被蒙蔽双眼!

12月14日&#xff0c;英国金融行为监管局( FCA )首次对 GoldVest FX 发出警告&#xff0c;提示投资者警惕与这家未经授权的公司打交道。 FCA警告称&#xff1a;GoldVest FX 在未经我们授权的情况下在英国提供金融服务或产品&#xff0c;如果一旦遭受资金损失&#xff0c;您将无…