#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;
}