使用offset获取宏值的子集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用offset获取宏值的子集相关的知识,希望对你有一定的参考价值。

我有一个列表定义为预处理器值#define LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9。我想写一个获得索引0或1的宏并且计算为LIST的子集,使得对于索引0,它将评估为0, 2, 4, 6, 8,对于索引1,它将评估为1, 3, 5, 7, 9。保证LIST的长度是均匀的但我不提前知道内容(它是由我提供的库的用户自动生成的)。这个问题是对this question的跟进

#define LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
#define MACRO(index) 
use LIST and index

// For LIST that given in the example
printf("%d %d %d %d %d
", MACRO(0)); // print 0 2 4 6 8
printf("%d %d %d %d %d
", MACRO(1)); // print 1 3 5 7 9
答案

这应该在Boost.Preprocessor的帮助下可行:

#define OUTPUT_CORRECT_OFFSET(r, offset, idx, elem) 
  BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(BOOST_PP_MOD(idx, 2), offset), (elem))

#define MACRO(index) 
  BOOST_PP_SEQ_ENUM( 
    BOOST_PP_SEQ_FOR_EACH_I( 
      OUTPUT_CORRECT_OFFSET, 
      index, 
      BOOST_PP_TUPLE_TO_SEQ((LIST)) 
    ) 
  )

[Live example]

它的工作原理是将LIST转换为Boost.Preprocessor序列,然后迭代它并保留索引模2匹配indexMACRO参数的那些元素,最后将结果序列转换回逗号分隔列表。


请注意,Boost.Preprocessor元组的最大大小有限制。在版本1.66.0(撰写本文时的最新版本)中,它是64.如果你的LIST较大,则不能将其视为元组(上面的代码通过使用(LIST)在其周围放置一对括号来实现)。

如果您可以控制LIST的格式,您可以直接更改它是Boost.Preprocessor序列:

#define LIST (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)

虽然序列也有大小限制,但它要大得多(Boost 1.66.0中有256个)。然后宏将更改如下:

#define MACRO(index) 
  BOOST_PP_SEQ_ENUM( 
    BOOST_PP_SEQ_FOR_EACH_I( 
      OUTPUT_CORRECT_OFFSET, 
      index, 
      LIST 
    ) 
  )

如果序列限制仍然不够,则必须考虑更强大的代码生成技术,例如本机C ++框架之外的独立宏处理器。

以上是关于使用offset获取宏值的子集的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中运行时用#define 宏值替换字符串

具有获取 json 值的片段中的自定义适配器

在配置单元中,如何获取具有键,值的子集的映射

如何从每个区间 (0.0,0.2),(0.2,0.4),(0.4,0.8),(0.8,1.0) 中获取包含相等数量值的数组子集?

闪亮:从具有多个值的 textInput 中子集表

Pandas:根据条件为多索引数据帧的子集设置值的正确方法