#include <iostream>
#include <functional>
#include <string>
#include <sstream>
struct Variant
{
template<typename T>
explicit Variant(T x) { std::stringstream ss; ss << x; impl = ss.str(); }
template<typename T>
friend T cast(Variant v) { std::stringstream ss(v.impl); T t; ss >> t; return t; }
private:
std::string impl;
};
namespace details
{
template<typename... Ts> struct type_seq {};
template<unsigned... Ns> struct num_seq {};
template<unsigned I, unsigned... Ns> struct gen_num_seq : gen_num_seq<I - 1, I - 1, Ns...> {};
template<unsigned... Ns> struct gen_num_seq<0, Ns...> { typedef num_seq<Ns...> type; };
template<typename F, unsigned... Is, typename... Ts>
Variant invoke2(F f, Variant* args, num_seq<Is...>, type_seq<Ts...>)
{
using namespace std; // workaround for a VC++ bug ('basic_string<...>' : undeclared identifier)
return Variant(f(cast<Ts>(args[Is])...));
}
template<typename F, typename... Ts>
Variant invoke(F f, Variant* args, type_seq<Ts...> argTypes)
{
return invoke2(f, args, typename gen_num_seq<sizeof...(Ts)>::type(), argTypes);
}
template<typename C, typename R, typename... A> auto get_arg_types_aux(R(C::*)(A...)) -> type_seq<A...>;
template<typename C, typename R, typename... A> auto get_arg_types_aux(R(C::*)(A...) const) -> type_seq<A...>;
template<typename R, typename... A> auto get_arg_types_aux(R(A...)) -> type_seq<A...>;
template<typename R, typename... A> auto get_arg_types_aux(R(*)(A...)) -> type_seq<A...>;
template<typename T> auto get_arg_types_aux(const T&) -> decltype(get_arg_types_aux(&T::operator()));
template<typename F> auto get_arg_types(F&& f) -> decltype(get_arg_types_aux(f)) { return decltype(get_arg_types_aux(f))(); }
}
template<typename F>
Variant invoke(F f, Variant* args)
{
return details::invoke(f, args, details::get_arg_types(f));
}
int main()
{
auto test = [](int a, double b, std::string c) -> int
{
std::cout << "a=" << a << '\n';
std::cout << "b=" << b << '\n';
std::cout << "c=" << c << '\n';
return 42;
};
Variant a[] = {Variant("20"), Variant("1.5"), Variant("x")};
std::cout << cast<int>(invoke(test, a)) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHNzdHJlYW0+CgpzdHJ1Y3QgVmFyaWFudAp7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgZXhwbGljaXQgVmFyaWFudChUIHgpIHsgc3RkOjpzdHJpbmdzdHJlYW0gc3M7IHNzIDw8IHg7IGltcGwgPSBzcy5zdHIoKTsgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBmcmllbmQgVCBjYXN0KFZhcmlhbnQgdikgeyBzdGQ6OnN0cmluZ3N0cmVhbSBzcyh2LmltcGwpOyBUIHQ7IHNzID4+IHQ7IHJldHVybiB0OyB9Cgpwcml2YXRlOgogICAgc3RkOjpzdHJpbmcgaW1wbDsKfTsKCm5hbWVzcGFjZSBkZXRhaWxzCnsKICAgIHRlbXBsYXRlPHR5cGVuYW1lLi4uIFRzPiBzdHJ1Y3QgdHlwZV9zZXEge307CgogICAgdGVtcGxhdGU8dW5zaWduZWQuLi4gTnM+IHN0cnVjdCBudW1fc2VxIHt9OwogICAgdGVtcGxhdGU8dW5zaWduZWQgSSwgdW5zaWduZWQuLi4gTnM+IHN0cnVjdCBnZW5fbnVtX3NlcSA6IGdlbl9udW1fc2VxPEkgLSAxLCBJIC0gMSwgTnMuLi4+IHt9OwogICAgdGVtcGxhdGU8dW5zaWduZWQuLi4gTnM+IHN0cnVjdCBnZW5fbnVtX3NlcTwwLCBOcy4uLj4geyB0eXBlZGVmIG51bV9zZXE8TnMuLi4+IHR5cGU7IH07CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgRiwgdW5zaWduZWQuLi4gSXMsIHR5cGVuYW1lLi4uIFRzPgogICAgVmFyaWFudCBpbnZva2UyKEYgZiwgVmFyaWFudCogYXJncywgbnVtX3NlcTxJcy4uLj4sIHR5cGVfc2VxPFRzLi4uPikKICAgIHsKICAgICAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOyAvLyB3b3JrYXJvdW5kIGZvciBhIFZDKysgYnVnICgnYmFzaWNfc3RyaW5nPC4uLj4nIDogdW5kZWNsYXJlZCBpZGVudGlmaWVyKQogICAgICAgIHJldHVybiBWYXJpYW50KGYoY2FzdDxUcz4oYXJnc1tJc10pLi4uKSk7CiAgICB9CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CiAgICBWYXJpYW50IGludm9rZShGIGYsIFZhcmlhbnQqIGFyZ3MsIHR5cGVfc2VxPFRzLi4uPiBhcmdUeXBlcykKICAgIHsKICAgICAgICByZXR1cm4gaW52b2tlMihmLCBhcmdzLCB0eXBlbmFtZSBnZW5fbnVtX3NlcTxzaXplb2YuLi4oVHMpPjo6dHlwZSgpLCBhcmdUeXBlcyk7CiAgICB9CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgQywgdHlwZW5hbWUgUiwgdHlwZW5hbWUuLi4gQT4gYXV0byBnZXRfYXJnX3R5cGVzX2F1eChSKEM6OiopKEEuLi4pKSAtPiB0eXBlX3NlcTxBLi4uPjsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEE+IGF1dG8gZ2V0X2FyZ190eXBlc19hdXgoUihDOjoqKShBLi4uKSBjb25zdCkgLT4gdHlwZV9zZXE8QS4uLj47CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZS4uLiBBPiBhdXRvIGdldF9hcmdfdHlwZXNfYXV4KFIoQS4uLikpIC0+IHR5cGVfc2VxPEEuLi4+OwogICAgdGVtcGxhdGU8dHlwZW5hbWUgUiwgdHlwZW5hbWUuLi4gQT4gYXV0byBnZXRfYXJnX3R5cGVzX2F1eChSKCopKEEuLi4pKSAtPiB0eXBlX3NlcTxBLi4uPjsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IGF1dG8gZ2V0X2FyZ190eXBlc19hdXgoY29uc3QgVCYpIC0+IGRlY2x0eXBlKGdldF9hcmdfdHlwZXNfYXV4KCZUOjpvcGVyYXRvcigpKSk7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGPiBhdXRvIGdldF9hcmdfdHlwZXMoRiYmIGYpIC0+IGRlY2x0eXBlKGdldF9hcmdfdHlwZXNfYXV4KGYpKSB7IHJldHVybiBkZWNsdHlwZShnZXRfYXJnX3R5cGVzX2F1eChmKSkoKTsgfQp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBGPgpWYXJpYW50IGludm9rZShGIGYsIFZhcmlhbnQqIGFyZ3MpCnsKICAgIHJldHVybiBkZXRhaWxzOjppbnZva2UoZiwgYXJncywgZGV0YWlsczo6Z2V0X2FyZ190eXBlcyhmKSk7Cn0KCmludCBtYWluKCkKewogICAgYXV0byB0ZXN0ID0gW10oaW50IGEsIGRvdWJsZSBiLCBzdGQ6OnN0cmluZyBjKSAtPiBpbnQKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgImE9IiA8PCBhIDw8ICdcbic7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJiPSIgPDwgYiA8PCAnXG4nOwogICAgICAgIHN0ZDo6Y291dCA8PCAiYz0iIDw8IGMgPDwgJ1xuJzsKICAgICAgICByZXR1cm4gNDI7CiAgICB9OwoKICAgIFZhcmlhbnQgYVtdID0ge1ZhcmlhbnQoIjIwIiksIFZhcmlhbnQoIjEuNSIpLCBWYXJpYW50KCJ4Iil9OwogICAgc3RkOjpjb3V0IDw8IGNhc3Q8aW50PihpbnZva2UodGVzdCwgYSkpIDw8ICdcbic7Cn0K