Boost预处理器中的迭代限制

时间:2014-11-25 10:09:48

标签: c++ boost boost-test boost-preprocessor

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

#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_CHECK_EQUAL与其他宏一起使用时,Boost预处理器库中存在一些迭代限制,或者编译器中存在预处理器深度限制(我使用) Clang 3.4)。这个限制是什么?如何增加它?

1 个答案:

答案 0 :(得分:3)

好主。

很可能没有人在使用Boost.Test考虑过你正在尝试做什么。问题不在于编译器限制,BOOST_PP_SEQ_FOR_EACH不可重入且BOOST_CHECK_EQUAL使用它。因此,在BOOST_CHECK_EQUAL内使用BOOST_PP_SEQ_FOR_EACH是不可能的。 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)))

我知道将序列转换为列表仅用于嵌套循环的目的是相当丑陋的。在我的辩护中,这是我能想到的最难看的方法。