[Edit]
By the way, in case any one is wondering, this problem is what makes the "Ultimate++" framework garbage for a lot of problems.
[/Edit]
So, yea, I decided to make a simple (the problem hasn't been generalized) example where the result (return type) didn't need to be accounted for just for a way of explanation.
This is all there is to the table. As you could probably guess, adding more types to the table is a trivial bit of code.
Code:
TABLE_ENTRY("One", One);
TABLE_ENTRY("Two", Two);
TABLE_ENTRY("Three", Three);
TABLE_ENTRY("Four", Four);
TABLE_ENTRY("Five", Five);
TABLE_ENTRY("Six", Six);
To resolve the type from the string I've implemented a strait forward recursive translation of a simple iterative linear search.
The interface to that routine is simple enough.
Code:
void Find<StartIndex, EndIndex>::execute(???); // Where "???" is relevant parameters.
The start and end index is important enough that it needs to be wrapped by convenience code. You can see how I've done that in the code.
Soma
Code:
#include <iostream>
#include <string>
#include <typeinfo>
struct ThisIsYourInterface
{
template
<
typename FTarget
>
void doSomething()
{
std::cout << "Type: " << typeid(FTarget).name() << '\n';
}
};
template
<
unsigned int FTarget
>
struct Typifier
{
};
template
<
unsigned int FTarget
>
struct Namer
{
};
struct One{};
struct Two{};
struct Three{};
struct Four{};
struct Five{};
struct Six{};
#define STUPID_OLD_SUN_CC(X) X
#define TABLE_ENTRY_IMPLEMENTATION(TARGET, NAME, TYPE) \
template <> struct Typifier<TARGET> {typedef TYPE Type;}; \
template <> struct Namer<TARGET> {static const char * Name;}; \
const char * Namer<TARGET>:: Name = NAME
#define TABLE_ENTRY(NAME, TYPE) TABLE_ENTRY_IMPLEMENTATION(STUPID_OLD_SUN_CC(__LINE__), NAME, TYPE)
static const unsigned long MyStart = __LINE__ + 1;
TABLE_ENTRY("One", One);
TABLE_ENTRY("Two", Two);
TABLE_ENTRY("Three", Three);
TABLE_ENTRY("Four", Four);
TABLE_ENTRY("Five", Five);
TABLE_ENTRY("Six", Six);
static const unsigned long MyEnd = __LINE__ - 1;
template
<
unsigned int FStart
, unsigned int FEnd
>
struct Find
{
static void execute
(
ThisIsYourInterface * fInterface
, const char * fName
)
{
if(std::string(fName) == Namer<FStart>::Name)
{
fInterface->doSomething<typename Typifier<FStart>::Type>();
}
else
{
Find<FStart + 1, FEnd>::execute(fInterface, fName);
}
}
};
template
<
unsigned int Match
>
struct Find<Match, Match>
{
static void execute
(
ThisIsYourInterface * fInterface
, const char * fName
)
{
if(std::string(fName) == Namer<Match>::Name)
{
fInterface->doSomething<typename Typifier<Match>::Type>();
}
}
};
struct MyFind
{
static void execute
(
ThisIsYourInterface * fInterface
, const char * fName
)
{
Find<MyStart, MyEnd>::execute(fInterface, fName);
}
};
int main
(
int argc
, char ** argv
)
{
ThisIsYourInterface l;
if(argc == 2)
{
MyFind::execute(&l, argv[1]);
}
return(0);
}