I'm working with a map of functions for a simple language I'm developing, everything works fine but I'd like to provide a better way to define the numerical operators which works on numerical values in a more concise way.
The main problem is that I have something like:
using BinaryFunction = std::function<StackValue(StackValue,StackValue)>;
registerFunction("+", Type::FLOAT, {Type::FLOAT, Type::FLOAT}, BinaryFunction([](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<float>()); }));
registerFunction("+", Type::FLOAT, {Type::FLOAT, Type::INT}, BinaryFunction([](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<s32>()); }));
..
So basically for each operator that supports both float and int data types I must provide 4 functions which works with the possible combinations
int, int -> int
int, float -> float
float, int -> float
float, float -> float
Now I don't want to provide implicit type conversion so I'm fine in having 4 different functions for each combination but I'd like a way to define them all at once without having to repeat the code.
The problem is how I could do it, the main problem resides in the lambda:
[](StackValue v1, StackValue v2) { return StackValue(v1.as<float>() + v2.as<float>()); };
To be able to do what I need I'd need a way to parametrize the code with a template, something like
return StackValue(v1.as<T1>() + v2.as<T2>())
Then the correct specialization of StackValue<T>(T) takes care of the rest.
so that I can then do something like
registerNumericFunction(...)
{
registerTemplate<float, float>(...);
registerTemplate<s32, float>(...);
..
}
But I'm not finding a clever way to do it because I need to pass a lambda to the method which should be parametric. I don't know if it is possible at all.
enum Type : u8, that's not a problem since I can usestd::conditionalto choose the correct one according to the two operator types.