function/Function.hpp

61 lines
1.2 KiB
C++
Raw Permalink Normal View History

2016-11-27 13:29:40 +00:00
#pragma once
#include <memory>
template <typename Fun>
class Function;
template <typename Ret, typename... Args>
class Function<Ret(Args...)>
{
private:
class callable_base
{
public:
2016-11-27 13:30:42 +00:00
virtual Ret call(Args...) const = 0;
virtual ~callable_base() = default;
};
template <typename Fun>
class callable : public callable_base
{
private:
2016-11-27 13:06:57 +00:00
Fun _fun;
public:
2016-11-27 13:06:57 +00:00
callable(Fun fun):_fun(fun) {}
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)...); }
virtual ~callable() override {}
};
2016-11-27 13:06:57 +00:00
std::unique_ptr<callable_base> _fun;
bool _is_null = false;
public:
2016-11-27 13:06:57 +00:00
Function() {}
template <typename Fun>
Function& operator=(Fun fun)
{
_fun = std::make_unique<callable<Fun>>(fun);
_is_null = false;
2016-11-27 13:06:57 +00:00
return *this;
}
Function& operator=(std::nullptr_t)
2016-11-27 13:50:49 +00:00
{ _is_null = true; return *this; }
2016-11-27 13:08:01 +00:00
Ret operator()(Args... args) const
{
if (_is_null)
throw std::bad_function_call();
return _fun->call(std::forward<Args>(args)...);
}
2016-11-27 13:08:01 +00:00
operator bool() const
{ return static_cast<bool>(_fun); }
};