#include <iostream>
#include <string>
#include <utility>
#include <tuple>
#include <functional>
#include <vector>
using namespace std;
class Test {
public:
Test() { cout << "Test()" << endl; }
Test(const Test&) { cout << "Test(const Test&)" << endl; }
Test(Test&&) { cout << "Test(Test&&)" << endl; }
~Test() {}
Test& operator = (const Test&) { cout << "copy operator" << endl; }
Test& operator = (Test&&) { cout << "move operator" << endl; }
};
void OrigFunc(int a, string b, Test t) {
cout << "OrigFunc(" << a << ", " << b << ")" << endl;
}
template<typename... Args>
void ForwardFunc(Args&&... args) {
OrigFunc(std::forward<Args>(args)...);
//OrigFunc(args...);
}
template<typename... FuncParams, typename... ArgTypes>
tuple<ArgTypes...> ArgsChecker(function<FuncParams...> func, ArgTypes&&... args) {
tuple<ArgTypes...> arguments(args...);
func(std::forward<ArgTypes>(args)...);
return arguments;
}
template<int IDX, int NUM_ELEMS>
struct TuplePrinter {
template<typename... TupleArgs>
static void Print(const tuple<TupleArgs...>& hisTuple) {
cout << "tuple[" << IDX << "] : " << get<IDX>(hisTuple) << endl;
TuplePrinter<IDX + 1, NUM_ELEMS>::Print(hisTuple);
}
};
template<int NUM_ELEMS>
struct TuplePrinter<NUM_ELEMS, NUM_ELEMS> {
template<typename... TupleArgs>
static void Print(const tuple<TupleArgs...>& hisTuple) {
}
};
int main() {
auto args = ArgsChecker(function<void(int, string, Test)>(OrigFunc), 1234, string("Hello World"), Test());
TuplePrinter<0, tuple_size<decltype(args)>::value - 1>::Print(args);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCiNpbmNsdWRlIDx2ZWN0b3I+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCmNsYXNzIFRlc3QgewpwdWJsaWM6CiAgICBUZXN0KCkgeyBjb3V0IDw8ICJUZXN0KCkiIDw8IGVuZGw7IH0KCVRlc3QoY29uc3QgVGVzdCYpIHsgY291dCA8PCAiVGVzdChjb25zdCBUZXN0JikiIDw8IGVuZGw7IH0KCVRlc3QoVGVzdCYmKSB7IGNvdXQgPDwgIlRlc3QoVGVzdCYmKSIgPDwgZW5kbDsgfQoJflRlc3QoKSB7fQoKCVRlc3QmIG9wZXJhdG9yID0gKGNvbnN0IFRlc3QmKSB7IGNvdXQgPDwgImNvcHkgb3BlcmF0b3IiIDw8IGVuZGw7IH0KCVRlc3QmIG9wZXJhdG9yID0gKFRlc3QmJikgeyBjb3V0IDw8ICJtb3ZlIG9wZXJhdG9yIiA8PCBlbmRsOyB9Cn07CgoKdm9pZCBPcmlnRnVuYyhpbnQgYSwgc3RyaW5nIGIsIFRlc3QgdCkgewoJY291dCA8PCAiT3JpZ0Z1bmMoIiA8PCBhIDw8ICIsICIgPDwgYiA8PCAiKSIgPDwgZW5kbDsKfQoKCnRlbXBsYXRlPHR5cGVuYW1lLi4uIEFyZ3M+CnZvaWQgRm9yd2FyZEZ1bmMoQXJncyYmLi4uIGFyZ3MpIHsKCU9yaWdGdW5jKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7CgkvL09yaWdGdW5jKGFyZ3MuLi4pOwp9CgoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gRnVuY1BhcmFtcywgdHlwZW5hbWUuLi4gQXJnVHlwZXM+CnR1cGxlPEFyZ1R5cGVzLi4uPiBBcmdzQ2hlY2tlcihmdW5jdGlvbjxGdW5jUGFyYW1zLi4uPiBmdW5jLCBBcmdUeXBlcyYmLi4uIGFyZ3MpIHsKCXR1cGxlPEFyZ1R5cGVzLi4uPiBhcmd1bWVudHMoYXJncy4uLik7CglmdW5jKHN0ZDo6Zm9yd2FyZDxBcmdUeXBlcz4oYXJncykuLi4pOwoJcmV0dXJuIGFyZ3VtZW50czsKfQoKCnRlbXBsYXRlPGludCBJRFgsIGludCBOVU1fRUxFTVM+CnN0cnVjdCBUdXBsZVByaW50ZXIgewoJdGVtcGxhdGU8dHlwZW5hbWUuLi4gVHVwbGVBcmdzPgoJc3RhdGljIHZvaWQgUHJpbnQoY29uc3QgdHVwbGU8VHVwbGVBcmdzLi4uPiYgaGlzVHVwbGUpIHsKCQljb3V0IDw8ICJ0dXBsZVsiIDw8IElEWCA8PCAiXSA6ICIgPDwgZ2V0PElEWD4oaGlzVHVwbGUpIDw8IGVuZGw7CgkJVHVwbGVQcmludGVyPElEWCArIDEsIE5VTV9FTEVNUz46OlByaW50KGhpc1R1cGxlKTsKCX0KfTsKCgp0ZW1wbGF0ZTxpbnQgTlVNX0VMRU1TPgpzdHJ1Y3QgVHVwbGVQcmludGVyPE5VTV9FTEVNUywgTlVNX0VMRU1TPiB7Cgl0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUdXBsZUFyZ3M+CglzdGF0aWMgdm9pZCBQcmludChjb25zdCB0dXBsZTxUdXBsZUFyZ3MuLi4+JiBoaXNUdXBsZSkgewoJfQp9OwoKCmludCBtYWluKCkgewoJYXV0byBhcmdzID0gQXJnc0NoZWNrZXIoZnVuY3Rpb248dm9pZChpbnQsIHN0cmluZywgVGVzdCk+KE9yaWdGdW5jKSwgMTIzNCwgc3RyaW5nKCJIZWxsbyBXb3JsZCIpLCBUZXN0KCkpOwoJVHVwbGVQcmludGVyPDAsIHR1cGxlX3NpemU8ZGVjbHR5cGUoYXJncyk+Ojp2YWx1ZSAtIDE+OjpQcmludChhcmdzKTsKfQo=