在编译时使用Constexpr填充数组 [英] Populate An Array Using Constexpr at Compile-time

查看:190
本文介绍了在编译时使用Constexpr填充数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用constexpr填充一个枚举数组。
数组的内容遵循某种模式。



我有一个枚举将ASCII字符集分为四个类别。

 枚举类型{
字母,
数字,
符号,
其他,
}

constexpr类型表[128] = / * blah blah * /;

我想有一个数组128 Type 。他们可以在一个结构。
数组的索引将对应于ASCII字符,并且值将是每个字符的 Type



所以我可以查询这个数组来找出ASCII字符属于哪个类别。像

  char c = RandomFunction(); 
if(table [c] == Alphabet)
DoSomething();

我想知道如果没有一些冗长的宏攻击,这是可能的。



目前,我通过执行以下操作初始化表。

  constexpr bool IsAlphabet ){
return((c> = 0x41& c< = 0x5A)||
(c> = 0x61& c< = 0x7A)
}

constexpr bool IsNumber(char c){/ blah blah * /}

constexpr bool IsSymbol(char c){/ blah blah * }

constexpr类型whichCategory(char c){/ * blah blah * /}

constexpr类型表[128] = {INITIALIZE};

其中 INITIALIZE 非常漫长的宏黑客。

  #define INITIALIZE INIT(0)
#define INIT N
#define INIT_0 whichCategory(0),INIT_1
#define INIT_1 whichCategory(1),INIT_2
// ...
#define INIT_127 whichCategory(127)

我想要一种方法来填充此数组或包含数组的结构,而不需要这个宏hack。



也许像

  struct Table {
类型_ [128];
};

constexpr表table = MagicFunction();

所以,问题是如何写这个 MagicFunction 我知道cctype和喜欢,这个问题更多是一个这是可能的吗?

而不是这是最好的方法吗?





感谢,

解决方案

忽略 ALL 问题,索引可用于救援:

 模板< unsigned ... Is> struct seq {}; 
template< unsigned N,unsigned ... Is>
struct gen_seq:gen_seq< N-1,N-1,Is ...> {};
template< unsigned ... Is>
struct gen_seq< 0,Is ...> :seq< Is ...> {};

模板< unsigned ... Is>
constexpr Table MagicFunction(seq< Is ...>){
return {{whichCategory(Is)...}};
}

constexpr Table MagicFunction(){
return MagicFunction(gen_seq< 128> {});
}

现场示例。


I would like to populate an array of enum using constexpr. The content of the array follows a certain pattern.

I have an enum separating ASCII character set into four categories.

enum Type {
    Alphabet,
    Number,
    Symbol,
    Other,
};

constexpr Type table[128] = /* blah blah */;

I would like to have an array of 128 Type. They can be in a structure. The index of the array will be corresponding to the ASCII characters and the value will be the Type of each character.

So I can query this array to find out which category an ASCII character belongs to. Something like

char c = RandomFunction();
if (table[c] == Alphabet) 
    DoSomething();

I would like to know if this is possible without some lengthy macro hacks.

Currently, I initialize the table by doing the following.

constexpr bool IsAlphabet (char c) {
    return ((c >= 0x41 && c <= 0x5A) ||
            (c >= 0x61 && c <= 0x7A));
}

constexpr bool IsNumber (char c) { /* blah blah */ }

constexpr bool IsSymbol (char c) { /* blah blah */ }

constexpr Type whichCategory (char c) { /* blah blah */ }

constexpr Type table[128] = { INITIALIZE };

where INITIALIZE is the entry point of some very lengthy macro hacks. Something like

#define INITIALIZE INIT(0)
#define INIT(N) INIT_##N
#define INIT_0 whichCategory(0), INIT_1
#define INIT_1 whichCategory(1), INIT_2
//...
#define INIT_127 whichCategory(127)

I would like a way to populate this array or a structure containing the array without the need for this macro hack...

Maybe something like

struct Table {
    Type _[128];
};

constexpr Table table = MagicFunction();

So, the question is how to write this MagicFunction?

Note: I am aware of cctype and likes, this question is more of a Is this possible? rather than Is this the best way to do it?.

Any help would be appreciated.

Thanks,

解决方案

Ignoring ALL the issues, indices to the rescue:

template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};

template<unsigned... Is>
constexpr Table MagicFunction(seq<Is...>){
  return {{ whichCategory(Is)... }};
}

constexpr Table MagicFunction(){
  return MagicFunction(gen_seq<128>{});
}

Live example.

这篇关于在编译时使用Constexpr填充数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆