#pragma once #include #include #include #include #ifndef __cpp_lib_move_only_function namespace std { template class move_only_function; template class move_only_function { public: move_only_function() = default; move_only_function(nullptr_t) {} move_only_function(const move_only_function&) = delete; move_only_function& operator=(const move_only_function&) = delete; move_only_function(move_only_function&&) noexcept = default; move_only_function& operator=(move_only_function&&) noexcept = default; template requires(!std::is_same_v, move_only_function> && !std::is_same_v, nullptr_t> && std::is_invocable_r_v) move_only_function(F&& f) : callable_(std::make_unique>>(std::forward(f))) {} move_only_function& operator=(nullptr_t) { callable_.reset(); return *this; } explicit operator bool() const noexcept { return callable_ != nullptr; } friend bool operator==(const move_only_function& f, nullptr_t) noexcept { return !static_cast(f); } friend bool operator==(nullptr_t, const move_only_function& f) noexcept { return !static_cast(f); } friend bool operator!=(const move_only_function& f, nullptr_t) noexcept { return static_cast(f); } friend bool operator!=(nullptr_t, const move_only_function& f) noexcept { return static_cast(f); } R operator()(Args... args) { return callable_->Call(std::forward(args)...); } private: struct CallableBase { virtual ~CallableBase() = default; virtual R Call(Args&&... args) = 0; }; template struct Callable final : CallableBase { explicit Callable(F&& f) : f_(std::move(f)) {} explicit Callable(const F& f) : f_(f) {} R Call(Args&&... args) override { return std::invoke(f_, std::forward(args)...); } F f_; }; std::unique_ptr callable_; }; } // namespace std #endif