#include <cstddef>
#include <iostream>
#include <memory>
#include <type_traits>
template <typename, size_t> class FastFunc;
template <typename R, typename... Args, size_t Size>
class FastFunc<R(Args...), Size> {
public:
template <typename F>
FastFunc(F f): handler(&Get<F>()) {
new (&storage) F(std::move(f));
}
~FastFunc() {
handler->destroy(&storage);
}
R operator()(Args&&... args) {
return handler->apply(&storage, std::forward<Args>(args)...);
}
private:
using Storage = typename std::aligned_storage<Size, alignof(max_align_t)>::type;
struct Handler {
R (*apply)(void*, Args&&...);
void (*destroy)(void*);
}; // struct Handler
template <typename F>
static R Apply(void* f, Args&&... args) {
(*reinterpret_cast<F*>(f))(std::forward<Args>(args)...);
}
template <typename F>
static void Destroy(void* f) {
reinterpret_cast<F*>(f)->~F();
}
template <typename F>
Handler const& Get() {
static Handler const H = { &Apply<F>, &Destroy<F> };
return H;
} // Get
Handler const* handler;
Storage storage;
}; // class FastFunc
int main() {
FastFunc<void(), 32> stateless = []() { std::cout << "stateless\n"; };
stateless();
bool b = true;
FastFunc<void(), 32> stateful = [&b]() { std::cout << "stateful: " << b << "\n"; };
stateful();
b = false;
stateful();
return 0;
}
I2luY2x1ZGUgPGNzdGRkZWY+CgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnRlbXBsYXRlIDx0eXBlbmFtZSwgc2l6ZV90PiBjbGFzcyBGYXN0RnVuYzsKCnRlbXBsYXRlIDx0eXBlbmFtZSBSLCB0eXBlbmFtZS4uLiBBcmdzLCBzaXplX3QgU2l6ZT4KY2xhc3MgRmFzdEZ1bmM8UihBcmdzLi4uKSwgU2l6ZT4gewpwdWJsaWM6CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRj4KICAgIEZhc3RGdW5jKEYgZik6IGhhbmRsZXIoJkdldDxGPigpKSB7CiAgICAgICAgbmV3ICgmc3RvcmFnZSkgRihzdGQ6Om1vdmUoZikpOwogICAgfQogICAgCiAgICB+RmFzdEZ1bmMoKSB7CiAgICAgICAgaGFuZGxlci0+ZGVzdHJveSgmc3RvcmFnZSk7CiAgICB9CiAgICAKICAgIFIgb3BlcmF0b3IoKShBcmdzJiYuLi4gYXJncykgewogICAgICByZXR1cm4gaGFuZGxlci0+YXBwbHkoJnN0b3JhZ2UsIHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7CiAgICB9CiAgICAKcHJpdmF0ZToKICAgIHVzaW5nIFN0b3JhZ2UgPSB0eXBlbmFtZSBzdGQ6OmFsaWduZWRfc3RvcmFnZTxTaXplLCBhbGlnbm9mKG1heF9hbGlnbl90KT46OnR5cGU7CiAgICAKICAgIHN0cnVjdCBIYW5kbGVyIHsKICAgICAgICBSICgqYXBwbHkpKHZvaWQqLCBBcmdzJiYuLi4pOwogICAgICAgIHZvaWQgKCpkZXN0cm95KSh2b2lkKik7CiAgICB9OyAvLyBzdHJ1Y3QgSGFuZGxlcgogICAgCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRj4KICAgIHN0YXRpYyBSIEFwcGx5KHZvaWQqIGYsIEFyZ3MmJi4uLiBhcmdzKSB7CiAgICAgICAgKCpyZWludGVycHJldF9jYXN0PEYqPihmKSkoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgIH0KICAKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBGPgogICAgc3RhdGljIHZvaWQgRGVzdHJveSh2b2lkKiBmKSB7CiAgICAJcmVpbnRlcnByZXRfY2FzdDxGKj4oZiktPn5GKCk7CiAgICB9CiAgICAKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBGPgogICAgSGFuZGxlciBjb25zdCYgR2V0KCkgewogICAgICAgIHN0YXRpYyBIYW5kbGVyIGNvbnN0IEggPSB7ICZBcHBseTxGPiwgJkRlc3Ryb3k8Rj4gfTsKICAgICAgICByZXR1cm4gSDsKICAgIH0gLy8gR2V0CiAgICAKICAgIEhhbmRsZXIgY29uc3QqIGhhbmRsZXI7CiAgICBTdG9yYWdlIHN0b3JhZ2U7Cn07IC8vIGNsYXNzIEZhc3RGdW5jCgppbnQgbWFpbigpIHsKCUZhc3RGdW5jPHZvaWQoKSwgMzI+IHN0YXRlbGVzcyA9IFtdKCkgeyBzdGQ6OmNvdXQgPDwgInN0YXRlbGVzc1xuIjsgfTsKCXN0YXRlbGVzcygpOwoJCglib29sIGIgPSB0cnVlOwoJRmFzdEZ1bmM8dm9pZCgpLCAzMj4gc3RhdGVmdWwgPSBbJmJdKCkgeyBzdGQ6OmNvdXQgPDwgInN0YXRlZnVsOiAiIDw8IGIgPDwgIlxuIjsgfTsKCXN0YXRlZnVsKCk7CgkKCWIgPSBmYWxzZTsKCXN0YXRlZnVsKCk7CgkKCXJldHVybiAwOwp9