2016-11-27 13:29:40 +00:00
|
|
|
#pragma once
|
2016-11-27 13:15:10 +00:00
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-11-27 15:22:43 +00:00
|
|
|
template <typename Fun>
|
2016-11-27 12:55:32 +00:00
|
|
|
class Function;
|
|
|
|
|
2016-11-27 15:22:43 +00:00
|
|
|
template <typename Ret, typename... Args>
|
2016-11-27 13:09:31 +00:00
|
|
|
class Function<Ret(Args...)>
|
2016-11-27 12:55:32 +00:00
|
|
|
{
|
2016-11-27 13:00:34 +00:00
|
|
|
private:
|
2016-11-27 15:22:43 +00:00
|
|
|
class callable_base
|
2016-11-27 13:00:34 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-11-27 13:30:42 +00:00
|
|
|
virtual Ret call(Args...) const = 0;
|
2016-11-27 15:22:43 +00:00
|
|
|
virtual ~callable_base() = default;
|
2016-11-27 13:00:34 +00:00
|
|
|
};
|
2016-11-27 13:02:28 +00:00
|
|
|
|
|
|
|
template <typename Fun>
|
|
|
|
class callable : public callable_base
|
|
|
|
{
|
|
|
|
private:
|
2016-11-27 13:06:57 +00:00
|
|
|
Fun _fun;
|
2016-11-27 13:02:28 +00:00
|
|
|
public:
|
2016-11-27 13:06:57 +00:00
|
|
|
callable(Fun fun):_fun(fun) {}
|
2016-11-27 13:12:06 +00:00
|
|
|
|
2016-11-27 13:30:42 +00:00
|
|
|
virtual Ret call(Args... args) const override
|
2016-11-27 13:06:57 +00:00
|
|
|
{ return _fun(std::forward<Args>(args)...); }
|
2016-11-27 13:12:06 +00:00
|
|
|
|
|
|
|
virtual ~callable() override {}
|
2016-11-27 13:02:28 +00:00
|
|
|
};
|
2016-11-27 13:06:57 +00:00
|
|
|
|
2016-11-27 13:20:02 +00:00
|
|
|
std::unique_ptr<callable_base> _fun;
|
2016-11-27 13:26:31 +00:00
|
|
|
bool _is_null = false;
|
2016-11-27 13:15:10 +00:00
|
|
|
|
2016-11-27 13:00:34 +00:00
|
|
|
public:
|
2016-11-27 13:06:57 +00:00
|
|
|
Function() {}
|
|
|
|
|
|
|
|
template <typename Fun>
|
|
|
|
Function& operator=(Fun fun)
|
|
|
|
{
|
2016-11-27 13:15:10 +00:00
|
|
|
_fun = std::make_unique<callable<Fun>>(fun);
|
2016-11-27 13:26:31 +00:00
|
|
|
_is_null = false;
|
2016-11-27 13:06:57 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-11-27 15:22:43 +00:00
|
|
|
Function& operator=(std::nullptr_t)
|
2016-11-27 13:50:49 +00:00
|
|
|
{ _is_null = true; return *this; }
|
2016-11-27 13:26:31 +00:00
|
|
|
|
2016-11-27 13:08:01 +00:00
|
|
|
Ret operator()(Args... args) const
|
2016-11-27 13:26:31 +00:00
|
|
|
{
|
|
|
|
if (_is_null)
|
2016-11-27 13:28:59 +00:00
|
|
|
throw std::bad_function_call();
|
2016-11-27 13:26:31 +00:00
|
|
|
return _fun->call(std::forward<Args>(args)...);
|
|
|
|
}
|
2016-11-27 13:08:01 +00:00
|
|
|
|
2016-11-27 13:12:06 +00:00
|
|
|
operator bool() const
|
|
|
|
{ return static_cast<bool>(_fun); }
|
2016-11-27 13:20:02 +00:00
|
|
|
};
|