Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate An Array Using Constexpr at Compile-time

Tags:

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,

like image 858
Jimmy Lu Avatar asked Nov 09 '12 18:11

Jimmy Lu


1 Answers

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.

like image 155
Xeo Avatar answered Oct 22 '22 04:10

Xeo