pre-processor command to resolve string literal to individual char values

S

steve.lorimer

Thank you for taking the time to look at this:

I'm looking for a pre-processor command that will allow me to resolve
const strings into const char literals at compile time.

Looking at the code below, I can take 5 characters and create a const
uint64_t value at compile time.
I can then create a switch statement that has these const values as
the various cases.
Since each case resolves to an integer constant value at compile time,
this switch statement is valid.

const uint64_t val1 = (static_cast<uint64_t>('S') << 32) | // S
(static_cast<uint64_t>('T') << 24)
| // T
(static_cast<uint64_t>('A') << 16)
| // A
(static_cast<uint64_t>('R') << 8)
| // R

(static_cast<uint64_t>('T')); // T

const char c1 = 'S', c2 = 'T', c3 = 'O', c4 = 'P';
const uint64_t val2 = (static_cast<uint64_t>(c1) << 32) | // S
(static_cast<uint64_t>(c2) << 24)
| // T
(static_cast<uint64_t>(c3) << 16)
| // O
(static_cast<uint64_t>(c4) << 8)
| // P
(static_cast<uint64_t>(0));

uint64_t input = 0;
switch (input)
{
case val1: printf("input=val1\n"); break;
case val2: printf("input=val2\n"); break;
default: break;
}
//--------------------------------------------------------------------------

Now I attempt to repeat the above code, but instead of using literal
character values, I use a const string literal.
gcc returns the following error:

error: case label does not reduce to an integer constant

So I guess the compiler is not able to resolve the index into the char
array at compile time.


const char* const str1 = "START";
const uint64_t val1 = (static_cast<uint64_t>(str1[0]) << 32)
| // S
(static_cast<uint64_t>(str1[1]) <<
24) | // T
(static_cast<uint64_t>(str1[2]) <<
16) | // A
(static_cast<uint64_t>(str1[3]) <<
8) | // R

(static_cast<uint64_t>(str1[4])); // T

const char* const str2 = "STOP";
const uint64_t val2 = (static_cast<uint64_t>(str2[0]) << 32)
| // S
(static_cast<uint64_t>(str2[1]) <<
24) | // T
(static_cast<uint64_t>(str2[2]) <<
16) | // O
(static_cast<uint64_t>(str2[3]) <<
8) | // P
(static_cast<uint64_t>(str2[4]));

uint64_t input = 0;
switch (input)
{
case val1: printf("input=val1\n"); break;
case val2: printf("input=val2\n"); break;
default: break;
}
//--------------------------------------------------------------------------

The reason I want to do the above is as follows:

What I actually have is a text file containing many unique input
strings, each a maximum of 5 characters long.
Each of these input strings has a corresponding name and a value that
it maps to. I'd like to be able to create a switch statement with a
case for each of the possible input strings which returns the
associated value.
At run-time, I can create a uint64_t value from any 5 character input
string and run the value through my case statement to get a return
value. Obviously performance wise this is far better than:
if (strncmp(...))
return ...
else
if (strncmp(...))
return ...
else
ad infinitum


Please see my example data below:

<< input_values.txt >>
MACRO1(DO_START, "START", enum_val_start)
MACRO1(DO_STOP, "STOP", enum_val_stop)

// create const values
#undef MACRO1
#define MACRO1(NAME, INPUT, VALUE) \
const uint64_t val_##NAME = (static_cast<uint64_t>(INPUT[0])
<< 32) | \

(static_cast<uint64_t>(INPUT[1]) << 24) | \

(static_cast<uint64_t>(INPUT[2]) << 16) | \

(static_cast<uint64_t>(INPUT[3]) << 8) | \

(static_cast<uint64_t>(INPUT[4]));
#include "input_values.txt"

// create switch statement containing above const values
#undef MACRO1
#define MACRO1(NAME, INPUT, VALUE) \
case val_##NAME: return VALUE;

switch (val)
{
#include "input_value.txt"
default: break;
}
//--------------------------------------------------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top