12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- #pragma once
- #include <types/cplusplus.hpp>
- namespace std {
- namespace __inner {
- template <typename Ret, typename... Args>
- class _function_base {
- public:
- constexpr _function_base() = default;
- virtual constexpr ~_function_base() = default;
- virtual constexpr Ret operator()(Args&&... args) const = 0;
- };
- template <typename FuncLike, typename Ret, typename... Args>
- class _function : public _function_base<Ret, Args...> {
- private:
- FuncLike func;
- public:
- constexpr _function(FuncLike&& _func)
- : func(types::forward<FuncLike>(_func))
- {
- }
- constexpr ~_function() = default;
- constexpr Ret operator()(Args&&... args) const override
- {
- return func(types::forward<Args>(args)...);
- }
- };
- } // namespace __inner
- template <typename>
- class function;
- template <typename Ret, typename... Args>
- class function<Ret(Args...)> {
- private:
- char _data[sizeof(void*) * 4];
- using fb_t = __inner::_function_base<Ret, Args...>;
- constexpr fb_t* _f(void) const
- {
- return (fb_t*)_data;
- }
- public:
- template <typename FuncLike>
- constexpr function(FuncLike&& func)
- {
- using underlying_function_type = __inner::_function<FuncLike, Ret, Args...>;
- static_assert(sizeof(underlying_function_type) <= sizeof(_data), "Too large FuncLike object");
- new (_f()) underlying_function_type(types::forward<FuncLike>(func));
- }
- template <typename FuncPtr>
- constexpr function(FuncPtr* funcPtr)
- {
- new (_f()) __inner::_function<typename types::traits::decay<FuncPtr>::type, Ret, Args...>(
- types::forward<typename types::traits::decay<FuncPtr>::type>(funcPtr));
- }
- constexpr ~function()
- {
- _f()->~_function_base();
- }
- constexpr Ret operator()(Args... args) const
- {
- return (*_f())(types::forward<Args>(args)...);
- }
- };
- } // namespace std
|