skullc-peripherals/Utility/Inc/utility_function.hpp

105 lines
1.8 KiB
C++

/*
* utility_function.hpp
*
* Created on: Jun 20, 2021
* Author: erki
*/
#ifndef SKULLC_UTILITY_FUNCTION_HPP_
#define SKULLC_UTILITY_FUNCTION_HPP_
#include <utility_assert.hpp>
namespace Utility
{
template<class>
class IFunction;
template<typename R, typename... Args>
class IFunction<R(Args...)>
{
public:
using result_type = R;
using static_signature = R (*)(Args...);
virtual ~IFunction()
{}
virtual result_type operator()(Args... args) = 0;
template<typename Tag>
static_signature toStaticFunction()
{
static decltype(this) h = this;
return +[](Args... args) { (*h)(args...); };
}
};
template<class>
class Function;
template<typename R, typename... Args>
class Function<R(Args...)> : public IFunction<R(Args...)>
{
public:
using result_type = R;
using signature = R (*)(Args...);
Function() = delete;
explicit Function(signature callable)
: callable_(callable)
{
SKULLC_ASSERT_DEBUG(callable_);
}
~Function() override
{
}
result_type operator()(Args... args) override
{
return (*callable_)(args...);
}
private:
signature callable_ = nullptr;
};
template<class, class>
class FunctionOwned;
template<typename H, typename R, typename... Args>
class FunctionOwned<H, R(Args...)> : public IFunction<R(Args...)>
{
public:
using source = H;
using result_type = R;
using signature = R (source::*)(Args...);
FunctionOwned() = delete;
explicit FunctionOwned(source& src, signature callable)
: src_(&src), callable_(callable)
{
SKULLC_ASSERT_DEBUG(callable_);
}
~FunctionOwned() override
{}
result_type operator()(Args... args) override
{
return (src_->*callable_)(args...);
}
private:
source* src_ = nullptr;
signature callable_ = nullptr;
};
}// namespace Utility
#endif /* SKULLC_UTILITY_FUNCTION_HPP_ */