Skip to content

Instantly share code, notes, and snippets.

@Cleroth
Last active July 19, 2018 20:22
Show Gist options
  • Save Cleroth/3a5091e33f9125a276894416c13a185a to your computer and use it in GitHub Desktop.
Save Cleroth/3a5091e33f9125a276894416c13a185a to your computer and use it in GitHub Desktop.
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;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment