libco 宏分析

// 下面是从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));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值