#pragma once #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(types::forward(_func)) { } constexpr ~_function() = default; constexpr Ret operator()(Args&&... args) const override { return func(types::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(types::forward(func)); } template constexpr function(FuncPtr* funcPtr) { new (_f()) __inner::_function::type, Ret, Args...>( types::forward::type>(funcPtr)); } constexpr ~function() { _f()->~_function_base(); } constexpr Ret operator()(Args... args) const { return (*_f())(types::forward(args)...); } }; } // namespace std