I want to save and access at runtime the types and default values of inputs and outputs of a function.
I have some structs to hold what I need for now in FunDeclaration
and FunParam
and an example function foo
to reflect. Live code here: https://onlinegdb.com/H10-Pq-7D
Here the full source:
#include <iostream>
#include <string>
#include <unordered_map>
#include <any>
struct FunParam {
// This will be a custom identifier (string for now) "int", "string", etc...
std::string type;
// Default value for that parameter
std::any default_value;
};
struct FunDeclaration {
// Function input params
std::unordered_map<std::string, FunParam> ins;
// Function output params
std::unordered_map<std::string, FunParam> outs;
};
using FunctionsMap = std::unordered_map<std::string, FunDeclaration>;
void print(FunctionsMap &fmap) {
auto printParam = [](FunParam& p) {
if (p.type == "int") {
std::cout << "type: " << p.type << " default_value: " << std::any_cast<int>(p.default_value);
} else if (p.type == "double") {
std::cout << "type: " << p.type << " default_value: " << std::any_cast<double>(p.default_value);
} else if (p.type == "float") {
std::cout << "type: " << p.type << " default_value: " << std::any_cast<float>(p.default_value);
} else if (p.type == "std::string") {
std::cout << "type: " << p.type << " default_value: " << std::any_cast<std::string>(p.default_value);
}
};
for (auto& f : fmap) {
std::cout << "Fun: " << f.first << std::endl;
for (auto& in: f.second.ins) {
std::cout << "\t[in] name: " << in.first << " ";
printParam(in.second);
std::cout << std::endl;
}
for (auto& f : fmap) {
for (auto& in : f.second.outs) {
std::cout << "\t[out] name: " << in.first << " ";
printParam(in.second);
std::cout << std::endl;
}
}
}
}
// Just an example function to work with, multiple inputs (default values), and multiple outputs
std::tuple<double, float> foo(int a = 10, std::string b = "HelloWorld") {
return { a * 10.0, b.size() };
}
int main() {
FunctionsMap gFuns;
gFuns["foo"].ins =
{
{"a", {"int", std::any(int(10))} },
{"b", {"std::string", std::any(std::string("HelloWorld"))} }
};
gFuns["foo"].outs = {
{"out0", {"double", std::any(double())} },
{"out1", {"float", std::any(float())} }
};
print(gFuns);
return 1;
}
How would you define a macro that spits this glue code(suppose gFuns is a global), and with multiple inputs/outputs? Is this possible with just one macro? Or I have to make a macro to each possibility of in/out param numbers?
gFuns["foo"].ins =
{
{"a", {"int", std::any(int(10))} },
{"b", {"std::string", std::any(std::string("HelloWorld"))} }
};
gFuns["foo"].outs = {
{"out0", {"double", std::any(double())} },
{"out1", {"float", std::any(float())} }
};
I was thinking about something like this:
#define ADD_FUN_DECL(name, in_types, in_defaultvalues, out_types, out_defaultvalues)