'Mediator for function templates
I'm trying to write a mediator that will work with functions (it is't final version).
FunctionPointer.h:
template<typename TObject, typename TRet, typename ...TParams>
class FunctionPointer
{
using TMethod = TRet(TObject::*)(TParams...);
public:
FunctionPointer(TObject* obj, TMethod meth) : m_object(obj), m_method(meth) {}
TRet operator()(TParams... params) { return (m_object->*m_method)(params...); }
private:
TObject* m_object;
TMethod m_method;
};
template<typename TObject, typename TRet, typename ...TParams>
FunctionPointer<TObject, TRet, TParams...> makeFuncPtr(TObject* obj, TRet(TObject::*meth)(TParams...))
{
return FunctionPointer<TObject, TRet, TParams...>(obj, meth);
}
BaseEvent.h:
#include <tuple>
#include "FunctionPointer.h"
class BaseEvent
{
};
template<typename ...TParams>
class AbstractEvent : public BaseEvent
{
public:
AbstractEvent(TParams... params) : m_params(std::make_tuple(params...)) {}
std::tuple<TParams...> getParams()
{
return m_params;
}
private:
std::tuple<TParams...> m_params;
};
class BaseMediator
{
public:
virtual void notify(BaseEvent* event) = 0;
};
template<typename TObject, typename ...TParams>
class AbstractMediator : public BaseMediator
{
using TFuncPtr = FunctionPointer<TObject, void, TParams...>;
public:
AbstractMediator(TObject* obj, void(TObject::*meth)(TParams...)) : m_func(makeFuncPtr(obj, meth)) {}
void notify(BaseEvent* event) override
{
AbstractEvent<TParams...>* abstractEvent = static_cast<AbstractEvent<TParams...>*>(event);
call(m_func, abstractEvent->getParams());
}
protected:
template<size_t... index>
void call(TFuncPtr function, std::tuple<TParams...> tuple, std::index_sequence<index...>)
{
return function(std::get<index>(tuple) ...);
}
void call(TFuncPtr function, std::tuple<TParams...> tuple)
{
static constexpr auto size = std::tuple_size<std::tuple<TParams...>>::value;
return call(function, tuple, std::make_index_sequence<size>{});
}
protected:
TFuncPtr m_func;
};
class BaseObject
{
public:
template<typename TObject, typename ...TParams>
void connect(TObject* sender, void(TObject::*function)(TParams...))
{
mediator = new AbstractMediator<TObject, TParams...>(sender, function);
}
template<typename ...TParams>
void call(TParams... params)
{
mediator->notify(new AbstractEvent<TParams...>(params...));
}
private:
BaseMediator* mediator = nullptr;
};
Is it possible to somehow specify that the parameters of the call(TParams...) function depend on what was previously passed to connect(TObject*, void(TObject::*function)(TParams...))?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
