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,
[0 .. 127]
? And thatchar
's signedness is implementation defined? Your current approach is very dangerous. Oh, and last but not least, the C++ standard doesn't demand ASCII encoding at all. It might aswell be EBCDIC. – Charleencharlemagnecctype
? cplusplus.com/reference/clibrary/cctype – Aqueductctype<char>
facet of a locale (and itsclassic_table
). It's not guaranteed to be ASCII (as Xeo pointed out) and is not constexpr. – Icaria((c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A))
fromIsAlphabet
-- this assumes the decimal ordering that is present in ASCII. The signedness is important since OP passes literals> 127
, which may map to negativechar
s. – Charleencharlemagnec
has been initialized byc = 0x41; // A
why shouldn't this work? I only see problems withc = 'A';
. – Icariais it possible
instead ofis this the best way to do it
. Thanks for your pointing out the range for ASCII though. I always group ASCII and extended ASCII together but I guess not. I was also not aware that C++ does not require ASCII encoding. – Empurple0x41
isn't mapped to any symbol at all, and letters have a strange place in the codepage. Just see here. – Charleencharlemagne