将#define匹配到模式

时间:2016-06-09 16:19:19

标签: c++ c-preprocessor

我有一个包含大量#define s的标题,如下所示:

#define XY_ABC_FOO 1
#define XY_ABC_BAR 3
#define XY_ABC_PIPPO 5
#define XY_ABC_PLUTO 7
#define XY_ABC_ETC 19
...

依此类推。

我想将所有这些放在载体中。我可以手工完成(几分钟内)。

std::vector<int> defs = { 1, 3, 5, 7, 19 , ... } 

但是,接下来,在标题中添加了下一个定义,有人必须记住在我的代码中添加它们。

是否有任何非常聪明的预处理程序/元编程技巧可以在编译时捕获它们? 我并不特别关心快速编译,它的测试代码很少被编译,大部分是在一夜之间编译。

2 个答案:

答案 0 :(得分:1)

您可以使用awk执行此操作:

awk '/^#define XY_ABC_\w+ \d+$/ { 
    if(line) {
        line = line ", " $2
    } else {
        line = "std::vector<int> defs = { " $2
    }
    END { print line " };" }' < header.hpp > defs.hpp

然后在您的主程序中使用#include defs.hpp来获取声明。

答案 1 :(得分:0)

您似乎只想使用#define来实现这一目标,但我几乎完全确定它是不可能的。

但如果您允许这些值为constexpr s,那么您就可以执行以下操作。 (如果没有外部工具,它可能是最好的选择。)

#define DEFS \
    C(XY_ABC_FOO,    1) \
    C(XY_ABC_BAR,    3) \
    C(XY_ABC_PIPPO,  5) \
    C(XY_ABC_PLUTO,  7) \
    C(XY_ABC_ETC,   19)

#define C(name, value) constexpr int name = value;
DEFS 
#undef C

/* ... */

#define C(name, value) value,
std::vector<int> defs = {DEFS};
#undef C