#include <memory>
#include <utility>
template <typename T>
struct function;
template <typename R, typename... A>
struct function<R(A...)> {
struct inner_fun_base {
virtual R call(A...) = 0;
};
template <typename F>
struct inner_fun : inner_fun_base {
inner_fun(F f) : f(f) {}
F f;
virtual R call(A... a) {
return f(std::forward<A>(a)...);
}
};
std::unique_ptr<inner_fun_base> ptr;
template <typename F>
function(F f) // I'm going by value here for simplicity
:ptr(new inner_fun<F>(f)) {}
R operator()(A... a) {
return ptr->call(std::forward<A>(a)...);
}
};
#include <iostream>
int main() {
function<bool(int)> f([](int n) { return n > 3; });
std::cout << f(2) << f(4);
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IGZ1bmN0aW9uOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEE+CnN0cnVjdCBmdW5jdGlvbjxSKEEuLi4pPiB7CiAgICBzdHJ1Y3QgaW5uZXJfZnVuX2Jhc2UgewogICAgICAgIHZpcnR1YWwgUiBjYWxsKEEuLi4pID0gMDsKICAgIH07CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEY+CiAgICBzdHJ1Y3QgaW5uZXJfZnVuIDogaW5uZXJfZnVuX2Jhc2UgewogICAgICAgIGlubmVyX2Z1bihGIGYpIDogZihmKSB7fQogICAgICAgIEYgZjsKICAgICAgICB2aXJ0dWFsIFIgY2FsbChBLi4uIGEpIHsKICAgICAgICAgICAgcmV0dXJuIGYoc3RkOjpmb3J3YXJkPEE+KGEpLi4uKTsKICAgICAgICB9CiAgICB9OwoKICAgIHN0ZDo6dW5pcXVlX3B0cjxpbm5lcl9mdW5fYmFzZT4gcHRyOwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBGPgogICAgZnVuY3Rpb24oRiBmKSAvLyBJJ20gZ29pbmcgYnkgdmFsdWUgaGVyZSBmb3Igc2ltcGxpY2l0eQogICAgOnB0cihuZXcgaW5uZXJfZnVuPEY+KGYpKSB7fQoKICAgIFIgb3BlcmF0b3IoKShBLi4uIGEpIHsKICAgICAgICByZXR1cm4gcHRyLT5jYWxsKHN0ZDo6Zm9yd2FyZDxBPihhKS4uLik7CiAgICB9Cn07CgojaW5jbHVkZSA8aW9zdHJlYW0+CgppbnQgbWFpbigpIHsKICAgIGZ1bmN0aW9uPGJvb2woaW50KT4gZihbXShpbnQgbikgeyByZXR1cm4gbiA+IDM7IH0pOwogICAgc3RkOjpjb3V0IDw8IGYoMikgPDwgZig0KTsKfQo=