Skip to content

Instantly share code, notes, and snippets.

@Cleroth
Last active July 19, 2018 20:22

Revisions

  1. Cleroth revised this gist Jul 19, 2018. No changes.
  2. Cleroth renamed this gist Jul 19, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. Cleroth created this gist Jul 19, 2018.
    69 changes: 69 additions & 0 deletions CallbackFunctor
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    namespace detail
    {
    template <typename Res = void, typename ... Args>
    class Lambda {
    public:
    virtual Res operator()(Args ... args) = 0;
    virtual ~Lambda() noexcept = default;
    };

    template <typename T, typename Res, typename ... Args>
    class LambdaImpl : public Lambda<Res, Args...> {
    public:
    LambdaImpl(T t) : _t(t) {}
    Res operator()(Args ... args) override
    {
    return _t(std::forward<Args>(args)...);
    }

    private:
    T _t;
    };
    };

    template <typename Res, typename ... Args, typename T>
    std::unique_ptr<detail::Lambda<Res, Args...>> MakeLambda(T t)
    {
    return std::make_unique<detail::LambdaImpl<T, Res, Args...>>(t);
    }


    template <typename Res = void, typename ... Args>
    class CallbackFunctor {
    public:
    CallbackFunctor() {}

    template <typename T>
    CallbackFunctor(T t)
    {
    _lambda = MakeLambda<Res, Args...>(t);
    }

    template <typename T>
    void operator=(T t)
    {
    _lambda = MakeLambda<Res, Args...>(t);
    }

    void operator=(std::nullptr_t)
    {
    _lambda = nullptr;
    }
    template<typename ...Args>
    auto operator()(Args &&... args) const
    {
    if(!_lambda)
    return Res(0);
    else
    return (*_lambda)(std::forward<Args>(args)...);
    }

    operator bool() const
    {
    return (bool)_lambda;
    }

    private:
    using LambdaType = detail::Lambda<Res, Args...>;
    std::unique_ptr<LambdaType> _lambda;
    };