#include <vector>
#include <map>
#include <functional>
#include <iostream>
#include <stdexcept>
enum class test_type {t0, t1, t2, t3, t4, tn};
class tester
{
public:
void run(test_type type, const std::vector<int> &args)
{
func_map[type](args);
};
private:
void function_0() { std::cout << "f0\n"; };
void function_1(int p1, int p2) { std::cout << "f1\n"; };
void function_2(int p1, int p2, int p3) { std::cout << "f2\n"; };
void function_3(int p1, int p2) { std::cout << "f3\n"; };
void function_4(int p1) { std::cout << "f4\n"; };
void function_n(int p1) { std::cout << "fn\n"; };
static void validate(const std::vector<int> &args, size_t needed) {
if (args.size() != needed)
throw std::invalid_argument("wrong number of arguments");
}
using func_type = std::function<void(const std::vector<int> &)>;
std::map<test_type, func_type> func_map {
{test_type::t0,
[this](const std::vector<int> &args){
validate(args, 0);
function_0();
}
},
{test_type::t1,
[this](const std::vector<int> &args){
validate(args, 2);
function_1(args[0], args[1]);
}
},
{test_type::t2,
[this](const std::vector<int> &args){
validate(args, 3);
function_2(args[0], args[1], args[2]);
}
},
{test_type::t3,
[this](const std::vector<int> &args){
validate(args, 2);
function_3(args[0], args[1]);
}
},
{test_type::t4,
[this](const std::vector<int> &args){
validate(args, 1);
function_4(args[0]);
}
},
{test_type::tn,
[this](const std::vector<int> &args){
validate(args, 1);
function_n(args[0]);
}
},
};
};
int main() {
tester test;
test.run(test_type::t0, {});
test.run(test_type::t1, {1, 2});
test.run(test_type::t2, {1, 2, 3});
test.run(test_type::t3, {1, 2});
test.run(test_type::t4, {1});
test.run(test_type::tn, {1});
return 0;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KCmVudW0gY2xhc3MgdGVzdF90eXBlIHt0MCwgdDEsIHQyLCB0MywgdDQsIHRufTsKCmNsYXNzIHRlc3Rlcgp7CnB1YmxpYzoKICAgIHZvaWQgcnVuKHRlc3RfdHlwZSB0eXBlLCBjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+ICZhcmdzKQogICAgewogICAgICAgIGZ1bmNfbWFwW3R5cGVdKGFyZ3MpOwogICAgfTsKCnByaXZhdGU6ICAgIAogICAgdm9pZCBmdW5jdGlvbl8wKCkgICAgICAgICAgICAgICAgICAgICAgIHsgc3RkOjpjb3V0IDw8ICJmMFxuIjsgfTsKICAgIHZvaWQgZnVuY3Rpb25fMShpbnQgcDEsIGludCBwMikgICAgICAgICB7IHN0ZDo6Y291dCA8PCAiZjFcbiI7IH07CiAgICB2b2lkIGZ1bmN0aW9uXzIoaW50IHAxLCBpbnQgcDIsIGludCBwMykgeyBzdGQ6OmNvdXQgPDwgImYyXG4iOyB9OwogICAgdm9pZCBmdW5jdGlvbl8zKGludCBwMSwgaW50IHAyKSAgICAgICAgIHsgc3RkOjpjb3V0IDw8ICJmM1xuIjsgfTsKICAgIHZvaWQgZnVuY3Rpb25fNChpbnQgcDEpICAgICAgICAgICAgICAgICB7IHN0ZDo6Y291dCA8PCAiZjRcbiI7IH07CiAgICB2b2lkIGZ1bmN0aW9uX24oaW50IHAxKSAgICAgICAgICAgICAgICAgeyBzdGQ6OmNvdXQgPDwgImZuXG4iOyB9OwoKICAgIHN0YXRpYyB2b2lkIHZhbGlkYXRlKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MsIHNpemVfdCBuZWVkZWQpIHsKICAgICAgICBpZiAoYXJncy5zaXplKCkgIT0gbmVlZGVkKQogICAgICAgICAgICB0aHJvdyBzdGQ6OmludmFsaWRfYXJndW1lbnQoIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMiKTsKICAgIH0KCiAgICB1c2luZyBmdW5jX3R5cGUgPSBzdGQ6OmZ1bmN0aW9uPHZvaWQoY29uc3Qgc3RkOjp2ZWN0b3I8aW50PiAmKT47CgogICAgc3RkOjptYXA8dGVzdF90eXBlLCBmdW5jX3R5cGU+IGZ1bmNfbWFwIHsKICAgICAgICB7dGVzdF90eXBlOjp0MCwKICAgICAgICAgIFt0aGlzXShjb25zdCBzdGQ6OnZlY3RvcjxpbnQ+ICZhcmdzKXsKICAgICAgICAgICAgdmFsaWRhdGUoYXJncywgMCk7CiAgICAgICAgICAgIGZ1bmN0aW9uXzAoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHt0ZXN0X3R5cGU6OnQxLAogICAgICAgICAgW3RoaXNdKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MpewogICAgICAgICAgICB2YWxpZGF0ZShhcmdzLCAyKTsKICAgICAgICAgICAgZnVuY3Rpb25fMShhcmdzWzBdLCBhcmdzWzFdKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHt0ZXN0X3R5cGU6OnQyLAogICAgICAgICAgW3RoaXNdKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MpewogICAgICAgICAgICB2YWxpZGF0ZShhcmdzLCAzKTsKICAgICAgICAgICAgZnVuY3Rpb25fMihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHt0ZXN0X3R5cGU6OnQzLAogICAgICAgICAgW3RoaXNdKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MpewogICAgICAgICAgICB2YWxpZGF0ZShhcmdzLCAyKTsKICAgICAgICAgICAgZnVuY3Rpb25fMyhhcmdzWzBdLCBhcmdzWzFdKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHt0ZXN0X3R5cGU6OnQ0LAogICAgICAgICAgW3RoaXNdKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MpewogICAgICAgICAgICB2YWxpZGF0ZShhcmdzLCAxKTsKICAgICAgICAgICAgZnVuY3Rpb25fNChhcmdzWzBdKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHt0ZXN0X3R5cGU6OnRuLAogICAgICAgICAgW3RoaXNdKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4gJmFyZ3MpewogICAgICAgICAgICB2YWxpZGF0ZShhcmdzLCAxKTsKICAgICAgICAgICAgZnVuY3Rpb25fbihhcmdzWzBdKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgfTsKfTsKCmludCBtYWluKCkgewoKICAgIHRlc3RlciB0ZXN0OwogICAgdGVzdC5ydW4odGVzdF90eXBlOjp0MCwge30pOwogICAgdGVzdC5ydW4odGVzdF90eXBlOjp0MSwgezEsIDJ9KTsKICAgIHRlc3QucnVuKHRlc3RfdHlwZTo6dDIsIHsxLCAyLCAzfSk7CiAgICB0ZXN0LnJ1bih0ZXN0X3R5cGU6OnQzLCB7MSwgMn0pOwogICAgdGVzdC5ydW4odGVzdF90eXBlOjp0NCwgezF9KTsKICAgIHRlc3QucnVuKHRlc3RfdHlwZTo6dG4sIHsxfSk7CgogICAgcmV0dXJuIDA7Cn0=