Repositories / jai.git

move_only_function.h

Clone (read-only): git clone http://git.guha-anderson.com/git/jai.git

Branch
1464 bytes · a426f058e357
// -*-C++-*- #pragma once #include <functional> #if __cpp_lib_move_only_function >= 202110L using std::move_only_function; #else // std::move_only_function unimplemented #include <memory> template<typename F> struct move_only_function; template<typename R, typename... Args, bool NE> class move_only_function<R(Args...) noexcept(NE)> { public: struct Invoker { virtual ~Invoker() = default; virtual R operator()(Args... args) noexcept(NE) = 0; }; template<typename F> struct Impl : Invoker { F f_; // Impl(F f) : f_(std::move(f)) {} template<typename RF> Impl(RF &&f) : f_(std::forward<RF>(f)) {} R operator()(Args... args) noexcept(NE) override { return std::invoke(f_, std::forward<Args>(args)...); } }; template<typename F> Impl(F &&) -> Impl<std::decay_t<F>>; std::unique_ptr<Invoker> inv_; public: move_only_function() noexcept = default; move_only_function(std::nullptr_t) noexcept {}; move_only_function(move_only_function &&) noexcept = default; template<std::invocable<Args...> F> move_only_function(F f) : inv_(new Impl{std::move(f)}) {} move_only_function &operator=(move_only_function &&) noexcept = default; R operator()(Args ...args) noexcept(NE) { return (*inv_)(std::forward<Args>(args)...); } explicit operator bool() noexcept { return inv_; } bool operator==(std::nullptr_t) noexcept { return !inv_; } }; #endif // std::move_only_function unimplemented