2021-05-31 08:05:40 +00:00
|
|
|
#include <functional>
|
|
|
|
|
2021-06-03 19:20:53 +00:00
|
|
|
/** Adapt functor to static method where functor passed as context.
|
|
|
|
* Main use case to convert lambda into function that can be passed into JIT code.
|
|
|
|
*/
|
2021-05-31 08:05:40 +00:00
|
|
|
template <typename Functor>
|
|
|
|
class FunctorToStaticMethodAdaptor : public FunctorToStaticMethodAdaptor<decltype(&Functor::operator())>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename R, typename C, typename ...Args>
|
|
|
|
class FunctorToStaticMethodAdaptor<R (C::*)(Args...) const>
|
|
|
|
{
|
|
|
|
public:
|
2021-07-03 13:29:32 +00:00
|
|
|
static R call(C * ptr, Args &&... arguments)
|
2021-05-31 08:05:40 +00:00
|
|
|
{
|
2021-07-03 13:29:32 +00:00
|
|
|
return std::invoke(&C::operator(), ptr, std::forward<Args>(arguments)...);
|
2021-05-31 08:05:40 +00:00
|
|
|
}
|
|
|
|
|
2021-07-03 13:29:32 +00:00
|
|
|
static R unsafeCall(char * ptr, Args &&... arguments)
|
2021-05-31 08:05:40 +00:00
|
|
|
{
|
|
|
|
C * ptr_typed = reinterpret_cast<C*>(ptr);
|
2021-07-03 13:29:32 +00:00
|
|
|
return std::invoke(&C::operator(), ptr_typed, std::forward<Args>(arguments)...);
|
2021-05-31 08:05:40 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename R, typename C, typename ...Args>
|
|
|
|
class FunctorToStaticMethodAdaptor<R (C::*)(Args...)>
|
|
|
|
{
|
|
|
|
public:
|
2021-07-03 13:29:32 +00:00
|
|
|
static R call(C * ptr, Args &&... arguments)
|
2021-05-31 08:05:40 +00:00
|
|
|
{
|
2021-07-03 13:29:32 +00:00
|
|
|
return std::invoke(&C::operator(), ptr, std::forward<Args>(arguments)...);
|
2021-05-31 08:05:40 +00:00
|
|
|
}
|
|
|
|
|
2021-07-03 13:29:32 +00:00
|
|
|
static R unsafeCall(char * ptr, Args &&... arguments)
|
2021-05-31 08:05:40 +00:00
|
|
|
{
|
|
|
|
C * ptr_typed = static_cast<C*>(ptr);
|
2021-07-03 13:29:32 +00:00
|
|
|
return std::invoke(&C::operator(), ptr_typed, std::forward<Args>(arguments)...);
|
2021-05-31 08:05:40 +00:00
|
|
|
}
|
|
|
|
};
|