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.
Well, I don't know if you are going to be able to do what you want. Make a code that creates a perfect hash function for any input seems to me pretty ... not doable.
Anyway, here is a simple solution to write the code. It's C++17 but can be made to work with C++11 with a bit of trickery.
The above code translates to just a simple jump because
5
is a compile time constant:If the argument is a runtime variable, then it does a series of compares:
The solution can be improved to perform a binary search, but it is not trivial.