我正在尝试在其自身中插入一系列字节的大小。如果我想将大小作为前缀,那么这可行:
#define COUNT(...) sizeof((uint8_t[]){__VA_ARGS__})
#define PREPEND_COUNT(...) COUNT(__VA_ARGS__), __VA_ARGS__
uint8_t x[] = {PREPEND_COUNT(10, 20, 30, 40)};
// x = {4, 10, 20, 30, 40}
但是,我还希望能够在扩展中的其他位置插入大小。阅读this page提供了一系列可以实现的工具。
是否可以按照以下方式创建内容?
uint8_t x[] = {ADD_COUNT(10, 20, THE_COUNT, 30, 40)};
// x = {10, 20, 4, 30, 40}
这是我的天真和不成功的方法:
#define ADD_COUNT2(THE_COUNT, ...) __VA_ARGS__
#define ADD_COUNT(...) ADD_COUNT2(COUNT(__VA_ARGS__), OBSTRUCT(__VA_ARGS__)))
答案 0 :(得分:1)
此方法使用boost预处理器。你的规范中有一些含糊之处;为简单起见,我将假设THE_COUNT
应该简单地替换为列表的大小减一。
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/tuple/eat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(F,S,...) S
#define THE_COUNT_MATCHES_THE_COUNT ,PRED_OF_COUNT
#define PRED_OF_COUNT(...) BOOST_PP_DEC(BOOST_PP_TUPLE_SIZE((__VA_ARGS__)))
#define ELEM_OR_COUNT(z,n,data) \
SECOND(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(n,data),_MATCHES_THE_COUNT), \
BOOST_PP_TUPLE_ELEM(n,data) BOOST_PP_TUPLE_EAT())data
#define ADD_COUNT(...) BOOST_PP_ENUM(BOOST_PP_TUPLE_SIZE((__VA_ARGS__)),ELEM_OR_COUNT,(__VA_ARGS__))
这需要一些解释。
SECOND
宏使用与检测部分中的网站CHECK
宏类似的技术。我使用它来提供可以被覆盖的默认值;为此,我构建了一个“匹配器”标记作为第一个参数。对于我想要不同扩展的东西,我定义了一个匹配的宏(类似于该部分中的PROBE
),它通过包含逗号来注入第二个参数。
在这种情况下,我希望THE_COUNT
扩展为PRED_OF_COUNT
,因此我构建了一个匹配令牌THE_COUNT_MATCHES_THE_COUNT
(我打算从THE_COUNT_MATCHES_
加上每个参数构建)要做到这一点。数据在争论之后,因此PRED_OF_COUNT
有正确的数字。对于默认情况(一个数字)我只是把那个数字;因为我之后推了数据,但是不想看到它,我添加了一个吃宏(这有点奇怪; BOOST_PP_TUPLE_EAT()
扩展为一个宏吃了一个元组;这不是宏本身。)
ELEM_OR_COUNT
是BOOST_PP_ENUM
的正文宏;看到那份文件。
ADD_COUNT
推动了这一机制。