#pragma once #include #include namespace std { namespace __inner { template class _function_base { public: constexpr _function_base() = default; virtual constexpr ~_function_base() = default; virtual constexpr Ret operator()(Args&&... args) const = 0; }; template class _function : public _function_base { private: FuncLike func; public: constexpr _function(FuncLike&& _func) : func(std::forward(_func)) { } constexpr ~_function() = default; constexpr Ret operator()(Args&&... args) const override { return func(std::forward(args)...); } }; } // namespace __inner template class function; template class function { private: char _data[sizeof(void*) * 2]; using fb_t = __inner::_function_base; constexpr fb_t* _f(void) const { return (fb_t*)_data; } public: template constexpr function(FuncLike&& func) { static_assert(sizeof(FuncLike) <= sizeof(_data)); new (_f()) __inner::_function(std::forward(func)); } template constexpr function(FuncPtr* funcPtr) { new (_f()) __inner::_function, Ret, Args...>( std::forward>(funcPtr)); } constexpr ~function() { _f()->~_function_base(); } constexpr Ret operator()(Args... args) const { return (*_f())(std::forward(args)...); } }; } // namespace std