BAN: Add basic Function for function pointers and member functions
This commit is contained in:
parent
d5e162b1ea
commit
3561257286
|
@ -0,0 +1,110 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/Errors.h>
|
||||
|
||||
namespace BAN
|
||||
{
|
||||
|
||||
template<typename>
|
||||
class Function;
|
||||
template<typename Ret, typename... Args>
|
||||
class Function<Ret(Args...)>
|
||||
{
|
||||
public:
|
||||
Function() {}
|
||||
Function(Ret(*function)(Args...))
|
||||
{
|
||||
static_assert(sizeof(CallablePointer) <= m_size);
|
||||
new (m_storage) CallablePointer(function);
|
||||
}
|
||||
template<typename Own>
|
||||
Function(Ret(Own::*function)(Args...), Own* owner)
|
||||
{
|
||||
static_assert(sizeof(CallableMember<Own>) <= m_size);
|
||||
new (m_storage) CallableMember<Own>(function, owner);
|
||||
}
|
||||
template<typename Own>
|
||||
Function(Ret(Own::*function)(Args...) const, const Own* owner)
|
||||
{
|
||||
static_assert(sizeof(CallableMemberConst<Own>) <= m_size);
|
||||
new (m_storage) CallableMemberConst<Own>(function, owner);
|
||||
}
|
||||
|
||||
Ret operator()(const Args&... args)
|
||||
{
|
||||
ASSERT(HasFunction());
|
||||
return ((CallableBase*)m_storage)->call(args...);
|
||||
}
|
||||
|
||||
bool HasFunction() const
|
||||
{
|
||||
for (size_t i = 0; i < m_size; i++)
|
||||
if (m_storage[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
struct CallableBase
|
||||
{
|
||||
virtual ~CallableBase() {}
|
||||
virtual Ret call(const Args&...) = 0;
|
||||
};
|
||||
|
||||
struct CallablePointer : public CallableBase
|
||||
{
|
||||
CallablePointer(Ret(*function)(Args...))
|
||||
: m_function(function)
|
||||
{ }
|
||||
|
||||
virtual Ret call(const Args&... args) override
|
||||
{
|
||||
return m_function(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
Ret(*m_function)(Args...) = nullptr;
|
||||
};
|
||||
|
||||
template<typename Own>
|
||||
struct CallableMember : public CallableBase
|
||||
{
|
||||
CallableMember(Ret(Own::*function)(Args...), Own* owner)
|
||||
: m_owner(owner)
|
||||
, m_function(function)
|
||||
{ }
|
||||
|
||||
virtual Ret call(const Args&... args) override
|
||||
{
|
||||
return (m_owner->*m_function)(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
Own* m_owner = nullptr;
|
||||
Ret(Own::*m_function)(Args...) = nullptr;
|
||||
};
|
||||
|
||||
template<typename Own>
|
||||
struct CallableMemberConst : public CallableBase
|
||||
{
|
||||
CallableMemberConst(Ret(Own::*function)(Args...) const, const Own* owner)
|
||||
: m_owner(owner)
|
||||
, m_function(function)
|
||||
{ }
|
||||
|
||||
virtual Ret call(const Args&... args) override
|
||||
{
|
||||
return (m_owner->*m_function)(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
const Own* m_owner = nullptr;
|
||||
Ret(Own::*m_function)(Args...) const = nullptr;
|
||||
};
|
||||
|
||||
private:
|
||||
static constexpr size_t m_size = sizeof(void*) * 4;
|
||||
alignas(max_align_t) uint8_t m_storage[m_size] { 0 };
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue