BAN: Add basic Function for function pointers and member functions

This commit is contained in:
Bananymous 2023-01-16 14:59:33 +02:00
parent d5e162b1ea
commit 3561257286
1 changed files with 110 additions and 0 deletions

110
BAN/include/BAN/Function.h Normal file
View File

@ -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 };
};
}