Boost预处理器中的迭代限制

问题描述:

我正在编写使用Boost :: Test框架进行比较函数的单元测试。对于每个测试用例,我创建一系列输入元素并将它们配对,以检查每对比较函数的返回值。我可以手动写出它或写一个函数。编写一个函数在单元测试中不是很好,因为在出​​现故障时我们得到的实用信息较少。手动写出每项检查会导致非常长的单元测试。所以我决定使用宏遍历要检查的元素。它看起来像这样:Boost预处理器中的迭代限制

#define CHECK_NODE_LESS(less, more) do {\ 
     BOOST_CHECK_EQUAL(compareQueueUnderTest((less), (more)), true); \ 
     BOOST_CHECK_EQUAL(compareQueueUnderTest((more), (less)), false); \ 
} while (false) 

#define CHECK_NODE_ORDER_ELEMENT(r, elem1, elem2) CHECK_NODE_LESS(elem1, elem2); 

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \ 
     BOOST_PP_SEQ_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \ 
         BOOST_PP_SEQ_REST_N(i, list)) 

#define CHECK_NODE_ORDER(nodes) \ 
     BOOST_PP_SEQ_FOR_EACH_I(CHECK_NODE_ORDER_INNER_LOOP, \ 
         BOOST_PP_SEQ_TAIL(nodes), nodes) 

在测试用例部分,但没有全序我用适当的元素CHECK_NODE_LESS宏来检查是有序的元素,并能正常工作。在总订购的测试案例中,我使用宏CHECK_NODE_ORDER。例如:

CHECK_NODE_ORDER((node1)(rootNode1)(node2)(rootNode2)); 

现在这一个不编译。我测试的第一件事是注释掉CHECK_NODE_LESS宏,并运行预处理器来查看生成的内容。这是我的预期:CHECK_NODE_LESS被称为正确的元素。然后我重新引入了CHECK_NODE_LESS并运行预处理器来查看会发生什么。由于Boost测试中使用的宏,结果非常难看,但可以看出一些宏未扩展。

最后,我改变CHECK_NODE_LESS以下,现在它工作正常:

#define CHECK_NODE_LESS(less, more) do {\ 
     BOOST_CHECK(compareQueueUnderTest((less), (more))); \ 
     BOOST_CHECK(!compareQueueUnderTest((more), (less))); \ 
} while (false) 

我认为问题是,要么存在于Boost预处理器库一些重复极限,当我使用BOOST_CHECK_EQUAL在一起超过与其他宏,或者编译器中有预处理器深度限制(我使用Clang 3.4)。这个限制是多少?如何增加限制?

好主。

在Boost.Test上工作的人很可能没有考虑过你想要做什么。问题不在于编译器限制,而在于BOOST_PP_SEQ_FOR_EACH不可重入,BOOST_CHECK_EQUAL使用它。因此,在BOOST_PP_SEQ_FOR_EACH内使用BOOST_CHECK_EQUAL是不可能的。 BOOST_CHECK工作,因为它不使用BOOST_PP_SEQ_FOR_EACH

我建议这种解决方法:

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \ 
    BOOST_PP_LIST_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \ 
          BOOST_PP_SEQ_TO_LIST(BOOST_PP_SEQ_REST_N(i, list))) 

我知道序列转换成一个列表嵌套循环的唯一目的是比较难看。在我的辩护中,这是我能想到的最不丑陋的方法。

+0

谢谢,您的解决方案的工作原理。尽管如此,我更喜欢我的解决方法,至少在我检查'bool'的时候。 – petersohn 2014-11-26 06:39:50