学习boost预编译–FOR循环

BOOST_PP_SEQ_FOR_EACH
最复杂就是这个BOOST_PP_SEQ_FOR_EACH
BOOST_PP_SEQ_FOR_EACH(macro,data,seq)表示对seq里一个元素,执行MACRO(n,data,e),其中e为元素,data为附加数据,n为循环次数+1.
首先BOOST_PP_SEQ_FOR_EACH会做一些检查,略过.
然后开始用BOOST_PP_SEQ_FOR_EACH_DETAILHECK_EXEC执行,然后调用BOOST_PP_FOR
FOR可能会被嵌套调用,BOOST_PP_FOR用BOOST_PP_AUTO_REC探测一个最小的序号.
如BOOST_PP_FOR_1
#define BOOST_PP_SEQ_FOR_EACH_DETAILHECK_EXEC(macro,data,seq) BOOST_PP_FOR((macro,data,seq,BOOST_PP_SEQ_SIZE(seq)),BOOST_PP_SEQ_FOR_EACH_P,BOOST_PP_SEQ_FOR_EACH_O,BOOST_PP_SEQ_FOR_EACH_M)
然后到BOOST_PP_FOR_1(s,p,o,m)//s为seq p,o,m为上面的BOOST_PP_SEQ_FOR_EACH_X
BOOST_PP_SEQ_FOR_EACH_P(r,x)=BOOST_PP_TUPLE_ELEM(4,3,x)//表示从tuple x中取出索引为3的元素,就是最后一个.
BOOST_PP_SEQ_FOR_EACH_O(r,x)=BOOST_PP_SEQ_FOR_EACH_O_I x=BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro,data,seq,BOOST_PP_DEC(sz))
BOOST_PP_DEC返回sz-1,作为循环终止条件,而这个sz通过之前我们说过的BOOST_PP_SEQ_SIZE传入的.
BOOST_PP_SEQ_FOR_EACH_O_I_DEC又会调用BOOST_PP_IF(sz,BOOST_PP_SEQ_FOR_EACH_O_I_TAIL,BOOST_PP_SEQ_FOR_EACH_O_I_NIL)
BOOST_PP_IF就是一个条件宏,当sz大于0返回前者,否则返回后者.
BOOST_PP_SEQ_FOR_EACH_M(r,x)=BOOST_PP_SEQ_FOR_EACH_M_IM(r,BOOST_PP_TUPLE_REM_4 x)
而BOOST_PP_TUPLE_REM_4的作用是去掉x的括号,如(a,b,c)→a,b,c
而BOOST_PP_SEQ_FOR_EACH_M_IM→BOOST_PP_SEQ_FOR_EACH_M_I
BOOST_PP_SEQ_FOR_EACH_M_I(r,macro,data,seq,sz) macro(r,data,BOOST_PP_SEQ_HEAD(seq))
BOOST_PP_SEQ_HEAD为取出seq中第一个元素.
这里可以看出之前打开的括号里的内容为macro,data,seq,sz.
归纳一下:
p取出未元素,后面可以p总是调用(macro,data,seq,sz),也就是说p取sz大小,而sz在循环中要dec的,所以p为取循环变量.
o将sz值减一然后判断
m执行传入的macro
可以看出靠着三者就可以完成一轮循环了.
介绍完成这些函数再来看FOR
BOOST_PP_FOR_1(s,p,o,m)=BOOST_PP_FOR_1(BOOST_PP_BOOL(p(2,s)),s,p,o,m)
注意此时s=(macro,data,seq,sz),p=BOOST_PP_SEQ_FOR_EACH_P,BOOST_PP_BOOL(p(2,s))表示把s中最后一个就是sz取bool值.
BOOST_PP_FOR_1_C(c,s,p,o,m)=BOOST_PP_IIF(c,m,BOOST_PP_TUPLE_EAT_2)(2,s) BOOST_PP_IIF(c,BOOST_PP_FOR_2,BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c,o)(2,s),p,o,m)
BOOST_PP_IIF(c,m,BOOST_PP_TUPLE_EAT_2)(2,s)//若c非0则为m(2,s),否则BOOST_PP_TUPLE_EAT_2(2,s),吃掉后面的文本.
此执行结果在最前,不会干扰后面迭代.
BOOST_PP_IIF(c,BOOST_PP_FOR_2,BOOST_PP_TUPLE_EAT_4)//)若c非0则为BOOST_PP_FOR_2进入第二次循环,否则吃掉后面文本.
BOOST_PP_EXPR_IIF(c,o)(2,s),p,o,m
BOOST_PP_EXPR_IIF为c非0则返回o,否则返回空.
这里我们看非0的情况,→o(2,s)→BOOST_PP_SEQ_FOR_EACH_O_I s→BOOST_PP_SEQ_FOR_EACH_O_I(macro,data,seq,sz)→BOOST_PP_SEQ_FOR_EACH_O_I_DEC(macro,data,seq,BOOST_PP_DEC(sz))→(macro,data,BOOST_PP_IF(sz,BOOST_PP_SEQ_FOR_EACH_O_I_TAIL,BOOST_PP_SEQ_FOR_EACH_O_I_NIL)(seq),sz)→(macro,data,BOOST_PP_SEQ_FOR_EACH_O_I_TAIL(seq),sz)→(macro,data,seqTail,sz)
BOOST_PP_SEQ_FOR_EACH_O_I_TAIL为取seq除了Head之后的部分,这里已经运行过m一次了.
最后为BOOST_PP_FOR_2((macro,data,seqTail,sz),p,o,m)
此宏和BOOST_PP_FOR_1唯一的区别为p(2,s)变成p(3,s),3为传入macro的循环变量.
再来看c=0的情况.

发表评论