I'm trying to implement a fast function dispatcher using compile time generated arrays to being able to use it at runtime in O(1).
Some lines of code just to clarify:
template<int i>
void f()
{
// do stuff
}
// specialized for every managed integer
template<>
void f<1>
{
// do stuff
}
Dispatcher<1,5,100,300> dispatcher;
dispatcher.execute(5); // this should call f<5>()
Let's call N the number of inputs of the dispatcher (4 in this case) and M the maximum value of the dispatcher input (300) in this case.
I've been able to make it work creating an array with size equal to M. This exploits the fact that at runtime you can do something like:
dispatcher.execute(5) -> internalArray[5]();
This works of course, but it is not feasible for arrays of big dimensions.
The best thing would be to generate an array of N elements only, and do some math trick to transform the input index into the index of the second array.
In the example, something that translates 1,5,100,300 respectively into 0,1,2,3. I have been able to do a kind of pre-processing method to transform them, but I'm looking for a way to avoid this step.
In other words I think I'm looking for some kind of minimal perfect hashing that can be used at compile time for my specific case in a very efficient way (ideally without any overhead, something like: goto: MyInstruction).
I'm not looking for alternatives that use virtual functions, std::map or complex operations.
Please ask if there is something is not clear.
PS I'm using C++11 but any idea is welcome
[Edit] I'm aware of the labels as values language extension of GCC. With those I would be maybe able to achieve my goal, but need a portable solution.
dispatcher.execute(4)
? – Australorp.execute()
argument is also supposed to be compile time, when why not just make it a template argument? thenexecute<N>()
would callf<N>
, though I still don't understand why would you want a dispatcher in this particular case instead of direct call. If you wantexecute
to accept run-time arguments then it's not clear what you want by dispatch. – Mylesexecute
method need to have runtime parameter? Or will it always be compile time? – Concettaconcettinastd::unordered_map
? It is expressly designed to solve problems like this efficiently. – Cilla