27 template<
typename TReturn = void,
typename... TArgs>
using AnyPtrFuncT = TReturn(AnyClass::*)(TArgs...);
28 template<
typename TReturn = void,
typename... TArgs>
using AnyPtrStaticFuncT = TReturn(*)(TArgs...);
33 template<
class TOut,
class TIn>
inline TOut
horrible_cast(TIn mIn) noexcept {
HorribleUnion<TOut, TIn> u; static_assert(
sizeof(TIn) ==
sizeof(u) &&
sizeof(TIn) ==
sizeof(TOut),
"Cannot use horrible_cast<>"); u.
in = mIn;
return u.
out; }
40 static_assert(TN - 100,
"Unsupported member function pointer on this compiler");
48 mFuncOut =
reinterpret_cast<AnyPtrFunc>(mFunc);
49 return reinterpret_cast<AnyPtrThis>(
const_cast<TThis*
>(mThis));
53 template<
typename TReturn,
typename... TArgs>
struct Closure
63 template<
class TThis,
class TInvoker>
inline void bind(TThis* mThis, TInvoker mInvoker, PtrStaticFuncT mFunc) noexcept
65 if(mFunc ==
nullptr) ptrFunction =
nullptr;
else bind(mThis, mInvoker);
69 inline bool operator==(std::nullptr_t) const noexcept {
return ptrThis ==
nullptr && ptrFunction ==
nullptr; }
70 inline bool operator==(
const Closure& mRhs)
const noexcept {
return ptrThis == mRhs.ptrThis && ptrFunction == mRhs.ptrFunction; }
71 inline bool operator==(PtrStaticFuncT mPtr)
const noexcept {
return mPtr ==
nullptr ? *
this ==
nullptr : mPtr ==
reinterpret_cast<PtrStaticFuncT
>(
getStaticFunc()); }
75 inline bool operator<(
const Closure& mRhs)
const {
return ptrThis != mRhs.ptrThis ? ptrThis < mRhs.ptrThis : std::memcmp(&ptrFunction, &mRhs.ptrFunction,
sizeof(ptrFunction)) < 0; }
78 inline std::size_t
getHash() const noexcept {
return reinterpret_cast<std::size_t
>(ptrThis) ^ Internal::unsafe_horrible_cast<std::size_t>(ptrFunction); }
80 inline PtrFuncT
getPtrFunction() const noexcept {
return reinterpret_cast<PtrFuncT
>(ptrFunction); }
88 Closure<TReturn, TArgs...> closure;
89 inline TReturn invokeStaticFunc(TArgs... mArgs)
const {
return (*(closure.
getStaticFunc()))(std::forward<TArgs>(mArgs)...); }
92 template<
class TThis,
class TFunc>
inline void bind(TThis* mThis, TFunc mFunc) noexcept { closure.
bind(mThis, mFunc); }
93 template<
class TFunc>
inline void bind(TFunc mFunc) noexcept { closure.
bind(
this, &FastFuncImpl::invokeStaticFunc, mFunc); }
99 template<
typename X,
typename Y>
inline FastFuncImpl(X* mThis, Y mFunc) noexcept {
bind(mThis, mFunc); }
105 inline bool operator==(std::nullptr_t) const noexcept {
return closure ==
nullptr; }
107 inline bool operator==(PtrStaticFuncT mFuncPtr)
const noexcept {
return closure == mFuncPtr; }
117 template<
typename TReturn,
typename TThis,
typename... TArgs>
struct MemFuncToFunc<TReturn(TThis::*)(TArgs...) const> {
using Type = TReturn(*)(TArgs...); };
119 #define ENABLE_IF_CONV_TO_FUN_PTR(x) typename std::enable_if<std::is_constructible<typename MemFuncToFunc<decltype(&std::decay<x>::type::operator())>::Type, x>::value>::type* = nullptr
120 #define ENABLE_IF_NOT_CONV_TO_FUN_PTR(x) typename std::enable_if<!std::is_constructible<typename MemFuncToFunc<decltype(&std::decay<x>::type::operator())>::Type, x>::value>::type* = nullptr
121 #define ENABLE_IF_SAME_TYPE(x, y) typename = typename std::enable_if<!std::is_same<x, typename std::decay<y>::type>{}>::type
128 std::shared_ptr<void> storage;
129 template<
typename T>
inline static void funcDeleter(
void* mPtr) {
static_cast<T*
>(mPtr)->~T();
operator delete(mPtr); }
132 using BaseType::BaseType;
134 inline FastFunc() noexcept =
default;
138 using FuncType =
typename std::decay<TFunc>::type;
139 this->bind(&mFunc, &FuncType::operator());
142 : storage(operator new(sizeof(TFunc)), funcDeleter<typename std::decay<TFunc>::type>)
144 using FuncType =
typename std::decay<TFunc>::type;
145 new (storage.get()) FuncType(std::forward<TFunc>(mFunc));
146 this->bind(storage.get(), &FuncType::operator());
150 #undef ENABLE_IF_CONV_TO_FUN_PTR
151 #undef ENABLE_IF_NOT_CONV_TO_FUN_PTR
152 #undef ENABLE_IF_SAME_TYPE
FastFuncImpl & operator=(PtrStaticFuncT mFunc) noexcept
TReturn(*)(TArgs...) Type
bool operator!=(std::nullptr_t) const noexcept
TOut horrible_cast(TIn mIn) noexcept
bool operator!=(PtrStaticFuncT mFuncPtr) const noexcept
bool operator!=(const Closure &mRhs) const noexcept
bool operator==(PtrStaticFuncT mPtr) const noexcept
bool operator!=(const FastFuncImpl &mImpl) const noexcept
static AnyPtrThis convert(const TThis *mThis, TFunc mFunc, AnyPtrFunc &mFuncOut) noexcept
bool operator>(const FastFuncImpl &mImpl) const
static AnyPtrThis convert(const TThis *, TFunc, AnyPtrFunc &) noexcept
AnyPtrThis getPtrThis() const noexcept
bool operator==(std::nullptr_t) const noexcept
TReturn(*)(TArgs...) AnyPtrStaticFuncT
PtrStaticFuncT getStaticFunc() const noexcept
bool operator==(const FastFuncImpl &mImpl) const noexcept
PtrFuncT getPtrFunction() const noexcept
bool operator==(const Closure &mRhs) const noexcept
bool operator<(const Closure &mRhs) const
void bind(TThis *mThis, TInvoker mInvoker, PtrStaticFuncT mFunc) noexcept
void(AnyClass::*)( AnyPtrFunc)
std::size_t getHash() const noexcept
bool operator<(const FastFuncImpl &mImpl) const
bool operator!=(PtrStaticFuncT mPtr) const noexcept
void bind(TThis *mThis, TFunc mFunc) noexcept
#define ENABLE_IF_CONV_TO_FUN_PTR(x)
TReturn operator()(TArgs...mArgs) const
FastFuncImpl() noexcept=default
FastFuncImpl(X *mThis, Y mFunc) noexcept
void bind(TThis *mThis, TFunc mFunc) noexcept
TReturn(AnyClass::*)(TArgs...) AnyPtrFuncT
bool operator!=(std::nullptr_t) const noexcept
FastFuncImpl(PtrStaticFuncT mFunc) noexcept
bool operator==(std::nullptr_t) const noexcept
void bind(TFunc mFunc) noexcept
TOut unsafe_horrible_cast(TIn mIn) noexcept
#define ENABLE_IF_NOT_CONV_TO_FUN_PTR(x)
FastFunc(TFunc &&mFunc, ENABLE_IF_NOT_CONV_TO_FUN_PTR(TFunc))
constexpr std::size_t SingleMemFuncPtrSize
FastFunc(TFunc &&mFunc, ENABLE_IF_CONV_TO_FUN_PTR(TFunc))
bool operator==(PtrStaticFuncT mFuncPtr) const noexcept
bool operator>(const Closure &mRhs) const