mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-08 02:48:30 +00:00
SourceHook tests pass again! Added test for list (and a small bit of tinyhash). Woot.
--HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40112
This commit is contained in:
parent
5ed98f9a46
commit
46e9986a0e
2901
sourcehook/generate/FastDelegate.h
Normal file
2901
sourcehook/generate/FastDelegate.h
Normal file
File diff suppressed because it is too large
Load Diff
779
sourcehook/generate/sh_memfuncinfo.h
Normal file
779
sourcehook/generate/sh_memfuncinfo.h
Normal file
@ -0,0 +1,779 @@
|
||||
/* ======== SourceHook ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): Pavol "PM OnoTo" Marko
|
||||
* ============================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This file provides a way for getting information about a member function.
|
||||
* @file sh_memfuncinfo.h
|
||||
*/
|
||||
|
||||
#ifndef __SHINT_MEMFUNC_INFO_H__
|
||||
#define __SHINT_MEMFUNC_INFO_H__
|
||||
|
||||
namespace SourceHook
|
||||
{
|
||||
|
||||
// Don Clugston:
|
||||
// implicit_cast< >
|
||||
// I believe this was originally going to be in the C++ standard but
|
||||
// was left out by accident. It's even milder than static_cast.
|
||||
// I use it instead of static_cast<> to emphasize that I'm not doing
|
||||
// anything nasty.
|
||||
// Usage is identical to static_cast<>
|
||||
template <class OutputClass, class InputClass>
|
||||
inline OutputClass implicit_cast(InputClass input){
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
struct MemFuncInfo
|
||||
{
|
||||
bool isVirtual; // Is the function virtual?
|
||||
int thisptroffs; // The this pointer the function expects to be called with
|
||||
// If -1, you need to call the GetFuncInfo_GetThisPtr function
|
||||
int vtblindex; // The function's index in the vtable (0-based, 1=second entry, 2=third entry, ...)
|
||||
int vtbloffs; // The vtable pointer
|
||||
};
|
||||
|
||||
// Ideas by Don Clugston.
|
||||
// Check out his excellent paper: http://www.codeproject.com/cpp/FastDelegate.asp
|
||||
|
||||
template<int N> struct MFI_Impl
|
||||
{
|
||||
template<class MFP> static inline void GetFuncInfo(MFP *mfp, MemFuncInfo &out)
|
||||
{
|
||||
static char weird_memfunc_pointer_exclamation_mark_arrow_error[N-1000];
|
||||
}
|
||||
};
|
||||
|
||||
# if SH_COMP == SH_COMP_GCC
|
||||
|
||||
template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16
|
||||
{
|
||||
struct GCC_MemFunPtr
|
||||
{
|
||||
union
|
||||
{
|
||||
void *funcadr; // always even
|
||||
intptr_t vtable_index_plus1; // = vindex+1, always odd
|
||||
};
|
||||
intptr_t delta;
|
||||
};
|
||||
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
|
||||
{
|
||||
GCC_MemFunPtr *mfp_detail = (GCC_MemFunPtr*)&mfp;
|
||||
out.thisptroffs = mfp_detail->delta;
|
||||
if (mfp_detail->vtable_index_plus1 & 1)
|
||||
{
|
||||
out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE;
|
||||
out.vtbloffs = 0;
|
||||
out.isVirtual = true;
|
||||
}
|
||||
else
|
||||
out.isVirtual = false;
|
||||
}
|
||||
};
|
||||
|
||||
# elif SH_COMP == SH_COMP_MSVC
|
||||
|
||||
namespace
|
||||
{
|
||||
int MFI_GetVtblOffset(void *mfp)
|
||||
{
|
||||
unsigned char *addr = (unsigned char*)mfp;
|
||||
if (*addr == 0xE9) // Jmp
|
||||
{
|
||||
// May or may not be!
|
||||
// Check where it'd jump
|
||||
addr += 5 /*size of the instruction*/ + *(unsigned long*)(addr + 1);
|
||||
}
|
||||
|
||||
// Check whether it's a virtual function call
|
||||
// They look like this:
|
||||
// 004125A0 8B 01 mov eax,dword ptr [ecx]
|
||||
// 004125A2 FF 60 04 jmp dword ptr [eax+4]
|
||||
// ==OR==
|
||||
// 00411B80 8B 01 mov eax,dword ptr [ecx]
|
||||
// 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h]
|
||||
|
||||
// However, for vararg functions, they look like this:
|
||||
// 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4]
|
||||
// 0048F0B4 8B 00 mov eax,dword ptr [eax]
|
||||
// 0048F0B6 FF 60 08 jmp dword ptr [eax+8]
|
||||
// ==OR==
|
||||
// 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4]
|
||||
// 0048F0B4 8B 00 mov eax,dword ptr [eax]
|
||||
// 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h]
|
||||
|
||||
// With varargs, the this pointer is passed as if it was the first argument
|
||||
|
||||
bool ok = false;
|
||||
if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 &&
|
||||
addr[4] == 0x8B && addr[5] == 0x00)
|
||||
{
|
||||
addr += 6;
|
||||
ok = true;
|
||||
}
|
||||
else if (addr[0] == 0x8B && addr[1] == 0x01)
|
||||
{
|
||||
addr += 2;
|
||||
ok = true;
|
||||
}
|
||||
if (!ok)
|
||||
return -1;
|
||||
|
||||
if (*addr++ == 0xFF)
|
||||
{
|
||||
if (*addr == 0x60)
|
||||
{
|
||||
return *++addr / 4;
|
||||
}
|
||||
else if (*addr == 0xA0)
|
||||
{
|
||||
return *((unsigned int*)++addr) / 4;
|
||||
}
|
||||
else if (*addr == 0x20)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones
|
||||
{
|
||||
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
|
||||
{
|
||||
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
|
||||
out.isVirtual = out.vtblindex >= 0 ? true : false;
|
||||
out.thisptroffs = 0;
|
||||
out.vtbloffs = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones!
|
||||
{
|
||||
struct MSVC_MemFunPtr2
|
||||
{
|
||||
void *funcadr;
|
||||
int delta;
|
||||
};
|
||||
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
|
||||
{
|
||||
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
|
||||
out.isVirtual = out.vtblindex >= 0 ? true : false;
|
||||
out.thisptroffs = reinterpret_cast<MSVC_MemFunPtr2*>(&mfp)->delta;
|
||||
out.vtbloffs = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// By Don Clugston, adapted
|
||||
template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG
|
||||
{
|
||||
class __single_inheritance GenericClass;
|
||||
class GenericClass {};
|
||||
|
||||
struct MicrosoftVirtualMFP {
|
||||
void (GenericClass::*codeptr)(); // points to the actual member function
|
||||
int delta; // #bytes to be added to the 'this' pointer
|
||||
int vtable_index; // or 0 if no virtual inheritance
|
||||
};
|
||||
|
||||
struct GenericVirtualClass : virtual public GenericClass
|
||||
{
|
||||
typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)();
|
||||
GenericVirtualClass * GetThis() { return this; }
|
||||
};
|
||||
|
||||
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
|
||||
{
|
||||
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
|
||||
out.isVirtual = out.vtblindex >= 0 ? true : false;
|
||||
// This pointer
|
||||
/*
|
||||
union {
|
||||
MFP func;
|
||||
GenericClass* (T::*ProbeFunc)();
|
||||
MicrosoftVirtualMFP s;
|
||||
} u;
|
||||
u.func = mfp;
|
||||
union {
|
||||
GenericVirtualClass::ProbePtrType virtfunc;
|
||||
MicrosoftVirtualMFP s;
|
||||
} u2;
|
||||
|
||||
// Check that the horrible_cast<>s will work
|
||||
typedef int ERROR_CantUsehorrible_cast[sizeof(mfp)==sizeof(u.s)
|
||||
&& sizeof(mfp)==sizeof(u.ProbeFunc)
|
||||
&& sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];
|
||||
// Unfortunately, taking the address of a MF prevents it from being inlined, so
|
||||
// this next line can't be completely optimised away by the compiler.
|
||||
u2.virtfunc = &GenericVirtualClass::GetThis;
|
||||
u.s.codeptr = u2.s.codeptr;
|
||||
out.thisptroffs = (reinterpret_cast<T*>(NULL)->*u.ProbeFunc)();
|
||||
*/
|
||||
out.thisptroffs = -1;
|
||||
out.vtbloffs = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Don: Nasty hack for Microsoft and Intel (IA32 and Itanium)
|
||||
// unknown_inheritance classes go here
|
||||
// This is probably the ugliest bit of code I've ever written. Look at the casts!
|
||||
// There is a compiler bug in MSVC6 which prevents it from using this code.
|
||||
template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN
|
||||
{
|
||||
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
|
||||
{
|
||||
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
|
||||
out.isVirtual = out.vtblindex >= 0 ? true : false;
|
||||
|
||||
// The member function pointer is 16 bytes long. We can't use a normal cast, but
|
||||
// we can use a union to do the conversion.
|
||||
union {
|
||||
MFP func;
|
||||
// In VC++ and ICL, an unknown_inheritance member pointer
|
||||
// is internally defined as:
|
||||
struct {
|
||||
void *m_funcaddress; // points to the actual member function
|
||||
int delta; // #bytes to be added to the 'this' pointer
|
||||
int vtordisp; // #bytes to add to 'this' to find the vtable
|
||||
int vtable_index; // or 0 if no virtual inheritance
|
||||
} s;
|
||||
} u;
|
||||
// Check that the horrible_cast will work
|
||||
typedef int ERROR_CantUsehorrible_cast[sizeof(u.func)==sizeof(u.s)? 1 : -1];
|
||||
u.func = mfp;
|
||||
int virtual_delta = 0;
|
||||
if (u.s.vtable_index) { // Virtual inheritance is used
|
||||
/*
|
||||
// First, get to the vtable.
|
||||
// It is 'vtordisp' bytes from the start of the class.
|
||||
int * vtable = *reinterpret_cast<int **>(
|
||||
reinterpret_cast<char *>(thisptr) + u.s.vtordisp );
|
||||
|
||||
// 'vtable_index' tells us where in the table we should be looking.
|
||||
virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>(
|
||||
reinterpret_cast<const char *>(vtable) + u.s.vtable_index);
|
||||
// The int at 'virtual_delta' gives us the amount to add to 'this'.
|
||||
// Finally we can add the three components together. Phew!
|
||||
out.thisptr = reinterpret_cast<void *>(
|
||||
reinterpret_cast<char *>(thisptr) + u.s.delta + virtual_delta);
|
||||
*/
|
||||
out.vtbloffs = u.s.vtordisp;
|
||||
out.thisptroffs = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.vtbloffs = out.vtblindex < 0 ? 0 : u.s.delta;
|
||||
out.thisptroffs = u.s.delta;
|
||||
}
|
||||
};
|
||||
};
|
||||
# else
|
||||
# error Unsupported compiler
|
||||
# endif
|
||||
|
||||
// This version does not take a this pointer
|
||||
// Useful for hookdecls, as they ensure that mfp is correct through a static_cast
|
||||
template<class X> inline void GetFuncInfo(X mfp, MemFuncInfo &out)
|
||||
{
|
||||
MFI_Impl<sizeof(mfp)>::GetFuncInfo(mfp, out);
|
||||
}
|
||||
|
||||
// Versions which do take a this
|
||||
template<class X, class Y, class RetType>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)() = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)() const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)() const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
|
||||
// GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it
|
||||
#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300
|
||||
|
||||
template<class X, class Y, class RetType>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
|
||||
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const, MemFuncInfo &out)
|
||||
{
|
||||
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const = mfp;
|
||||
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
2159
sourcehook/generate/sourcehook.h
Normal file
2159
sourcehook/generate/sourcehook.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,10 @@
|
||||
#define SH_GLOB_PLUGPTR g_PLID
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SH_DEBUG
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# define SH_ASSERT__(x, info, file, line, func) \
|
||||
((printf("SOURCEHOOK DEBUG ASSERTION FAILED:\n %s:%u(%s): %s\n", file, line, func, info), true) ? (abort(), 0) : 0)
|
||||
# define SH_ASSERT(x, info) if (!(x)) SH_ASSERT__(x, info, __FILE__, __LINE__, __FUNCTION__)
|
||||
@ -68,10 +71,9 @@
|
||||
#include "FastDelegate.h"
|
||||
#include "sh_memfuncinfo.h"
|
||||
#include "sh_memory.h"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include "sh_list.h"
|
||||
#include "sh_vector.h"
|
||||
#include "sh_tinyhash.h"
|
||||
|
||||
// Good old metamod!
|
||||
|
||||
@ -185,8 +187,8 @@ namespace SourceHook
|
||||
int thisptr_offs; //!< This pointer offset
|
||||
};
|
||||
void *ptr; //!< Pointer to the interface instance
|
||||
SourceHook::List<Hook> hooks_pre; //!< A list of pre-hooks
|
||||
SourceHook::List<Hook> hooks_post; //!< A list of post-hooks
|
||||
List<Hook> hooks_pre; //!< A list of pre-hooks
|
||||
List<Hook> hooks_post; //!< A list of post-hooks
|
||||
bool operator ==(void *other) const
|
||||
{
|
||||
return ptr == other;
|
||||
@ -196,7 +198,7 @@ namespace SourceHook
|
||||
void *vfnptr; //!< Pointer to the function
|
||||
void *orig_entry; //!< The original vtable entry
|
||||
|
||||
typedef SourceHook::List<Iface> IfaceList;
|
||||
typedef List<Iface> IfaceList;
|
||||
typedef IfaceList::iterator IfaceListIter;
|
||||
IfaceList ifaces; //!< List of interface pointers
|
||||
|
||||
@ -214,7 +216,7 @@ namespace SourceHook
|
||||
|
||||
void *hookfunc_vfnptr; //!< Pointer to the hookfunc impl
|
||||
|
||||
typedef SourceHook::List<VfnPtr> VfnPtrList;
|
||||
typedef List<VfnPtr> VfnPtrList;
|
||||
typedef VfnPtrList::iterator VfnPtrListIter;
|
||||
VfnPtrList vfnptrs; //!< List of hooked interfaces
|
||||
};
|
||||
@ -237,6 +239,8 @@ namespace SourceHook
|
||||
class ISourceHook
|
||||
{
|
||||
public:
|
||||
virtual ~ISourceHook()
|
||||
{ }
|
||||
/**
|
||||
* @brief Return interface version
|
||||
*/
|
||||
@ -467,8 +471,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
void *ourvfnptr = reinterpret_cast<void*>( \
|
||||
*reinterpret_cast<void***>(reinterpret_cast<char*>(this) + ms_HI->vtbl_offs) + ms_HI->vtbl_idx); \
|
||||
\
|
||||
HookManagerInfo::VfnPtrListIter vfptriter = ms_HI->find(ms_HI->vfnptrs.begin(), \
|
||||
ms_HI->vfnptrs.end(), ourvfnptr); \
|
||||
HookManagerInfo::VfnPtrListIter vfptriter = ms_HI->vfnptrs.find(ourvfnptr); \
|
||||
if (vfptriter == ms_HI->vfnptrs.end()) \
|
||||
{ \
|
||||
/* Bleh? Should be impossible! */ \
|
||||
@ -476,7 +479,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
} \
|
||||
HookManagerInfo::VfnPtr &vfnptr = *vfptriter; \
|
||||
/* 2) Find the iface */ \
|
||||
HookManagerInfo::VfnPtr::IfaceListIter ifiter = ms_HI->find(vfnptr.ifaces.begin(), vfnptr.ifaces.end(), this); \
|
||||
HookManagerInfo::VfnPtr::IfaceListIter ifiter = vfnptr.ifaces.find(this); \
|
||||
if (ifiter == vfnptr.ifaces.end()) \
|
||||
{ \
|
||||
/* The iface info was not found. Redirect the call to the original function. */ \
|
||||
@ -486,8 +489,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
} \
|
||||
HookManagerInfo::VfnPtr::Iface &ci = *ifiter; \
|
||||
/* 2) Declare some vars and set it up */ \
|
||||
SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook> &prelist = ci.hooks_pre; \
|
||||
SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook> &postlist = ci.hooks_post; \
|
||||
List<HookManagerInfo::VfnPtr::Iface::Hook> &prelist = ci.hooks_pre; \
|
||||
List<HookManagerInfo::VfnPtr::Iface::Hook> &postlist = ci.hooks_post; \
|
||||
rettype orig_ret; \
|
||||
rettype override_ret; \
|
||||
rettype plugin_ret; \
|
||||
@ -501,7 +504,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
|
||||
#define SH_CALL_HOOKS(post, params) \
|
||||
prev_res = MRES_IGNORED; \
|
||||
for (SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
|
||||
for (List<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
|
||||
{ \
|
||||
if (hiter->paused) continue; \
|
||||
cur_res = MRES_IGNORED; \
|
||||
@ -544,8 +547,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
void *ourvfnptr = reinterpret_cast<void*>( \
|
||||
*reinterpret_cast<void***>(reinterpret_cast<char*>(this) + ms_HI->vtbl_offs) + ms_HI->vtbl_idx); \
|
||||
\
|
||||
HookManagerInfo::VfnPtrListIter vfptriter = ms_HI->find(ms_HI->vfnptrs.begin(), \
|
||||
ms_HI->vfnptrs.end(), ourvfnptr); \
|
||||
HookManagerInfo::VfnPtrListIter vfptriter = ms_HI->vfnptrs.find(ourvfnptr); \
|
||||
if (vfptriter == ms_HI->vfnptrs.end()) \
|
||||
{ \
|
||||
/* Bleh? Should be impossible! */ \
|
||||
@ -553,7 +555,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
} \
|
||||
HookManagerInfo::VfnPtr &vfnptr = *vfptriter; \
|
||||
/* 2) Find the iface */ \
|
||||
HookManagerInfo::VfnPtr::IfaceListIter ifiter = ms_HI->find(vfnptr.ifaces.begin(), vfnptr.ifaces.end(), this); \
|
||||
HookManagerInfo::VfnPtr::IfaceListIter ifiter = vfnptr.ifaces.find(this); \
|
||||
if (ifiter == vfnptr.ifaces.end()) \
|
||||
{ \
|
||||
/* The iface info was not found. Redirect the call to the original function. */ \
|
||||
@ -564,8 +566,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
} \
|
||||
HookManagerInfo::VfnPtr::Iface &ci = *ifiter; \
|
||||
/* 2) Declare some vars and set it up */ \
|
||||
SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook> &prelist = ci.hooks_pre; \
|
||||
SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook> &postlist = ci.hooks_post; \
|
||||
List<HookManagerInfo::VfnPtr::Iface::Hook> &prelist = ci.hooks_pre; \
|
||||
List<HookManagerInfo::VfnPtr::Iface::Hook> &postlist = ci.hooks_post; \
|
||||
META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \
|
||||
META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \
|
||||
META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \
|
||||
@ -575,7 +577,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
|
||||
|
||||
#define SH_CALL_HOOKS_void(post, params) \
|
||||
prev_res = MRES_IGNORED; \
|
||||
for (SourceHook::List<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
|
||||
for (List<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \
|
||||
{ \
|
||||
if (hiter->paused) continue; \
|
||||
cur_res = MRES_IGNORED; \
|
||||
|
||||
@ -126,12 +126,22 @@ public:
|
||||
{
|
||||
m_This = where.m_This;
|
||||
}
|
||||
//pre decrement
|
||||
iterator & operator--()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return *this;
|
||||
}
|
||||
//post decrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
@ -147,7 +157,8 @@ public:
|
||||
m_This = m_This->next;
|
||||
return old;
|
||||
}
|
||||
T & operator * () const
|
||||
|
||||
const T & operator * () const
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
@ -155,10 +166,16 @@ public:
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T * operator -> () const
|
||||
|
||||
T * operator -> ()
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
const T * operator -> () const
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
|
||||
bool operator != (const iterator &where) const
|
||||
{
|
||||
return (m_This != where.m_This);
|
||||
@ -238,6 +255,7 @@ public:
|
||||
}
|
||||
List & operator =(List &src)
|
||||
{
|
||||
clear();
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
|
||||
@ -42,10 +42,40 @@ namespace SourceHook
|
||||
};
|
||||
typedef List<THashNode *> * NodePtr;
|
||||
public:
|
||||
THash() : m_numBuckets(0), m_Buckets(NULL)
|
||||
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f)
|
||||
{
|
||||
_Refactor();
|
||||
}
|
||||
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
|
||||
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed)
|
||||
{
|
||||
for (size_t i=0; i<m_numBuckets; i++)
|
||||
m_Buckets[i] = NULL;
|
||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||
_FindOrInsert(iter->key)->val = iter->val;
|
||||
}
|
||||
void operator=(const THash &other)
|
||||
{
|
||||
clear();
|
||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||
_FindOrInsert(iter->key)->val = iter->val;
|
||||
}
|
||||
|
||||
~THash()
|
||||
{
|
||||
if (m_Buckets)
|
||||
delete [] m_Buckets;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
if (m_Buckets)
|
||||
delete [] m_Buckets;
|
||||
m_Buckets = NULL;
|
||||
m_numBuckets = 0;
|
||||
m_percentUsed = 0.0f;
|
||||
|
||||
_Refactor();
|
||||
}
|
||||
size_t GetBuckets()
|
||||
{
|
||||
return m_numBuckets;
|
||||
@ -135,14 +165,15 @@ namespace SourceHook
|
||||
}
|
||||
public:
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
class iterator
|
||||
{
|
||||
friend class THash;
|
||||
public:
|
||||
iterator() : hash(NULL), end(true)
|
||||
iterator() : curbucket(-1), hash(NULL), end(true)
|
||||
{
|
||||
};
|
||||
iterator(THash *h) : hash(h), end(false)
|
||||
iterator(THash *h) : curbucket(-1), hash(h), end(false)
|
||||
{
|
||||
if (!h->m_Buckets)
|
||||
end = true;
|
||||
@ -162,7 +193,7 @@ namespace SourceHook
|
||||
_Inc();
|
||||
return old;
|
||||
}
|
||||
THashNode & operator * () const
|
||||
const THashNode & operator * () const
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
@ -170,7 +201,7 @@ namespace SourceHook
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
THashNode * operator ->() const
|
||||
const THashNode * operator ->() const
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
@ -197,7 +228,7 @@ namespace SourceHook
|
||||
private:
|
||||
void _Inc()
|
||||
{
|
||||
if (end || !hash || curbucket >= hash->m_numBuckets)
|
||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||
return;
|
||||
if (curbucket < 0)
|
||||
{
|
||||
@ -242,6 +273,105 @@ namespace SourceHook
|
||||
THash *hash;
|
||||
bool end;
|
||||
};
|
||||
class const_iterator
|
||||
{
|
||||
friend class THash;
|
||||
public:
|
||||
const_iterator() : curbucket(-1), hash(NULL), end(true)
|
||||
{
|
||||
};
|
||||
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
|
||||
{
|
||||
if (!h->m_Buckets)
|
||||
end = true;
|
||||
else
|
||||
_Inc();
|
||||
};
|
||||
//pre increment
|
||||
const_iterator & operator++()
|
||||
{
|
||||
_Inc();
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
_Inc();
|
||||
return old;
|
||||
}
|
||||
const THashNode & operator * () const
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
const THashNode * operator ->() const
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
bool operator ==(const const_iterator &where) const
|
||||
{
|
||||
if (where.hash == this->hash
|
||||
&& where.end == this->end
|
||||
&&
|
||||
(this->end ||
|
||||
((where.curbucket == this->curbucket)
|
||||
&& (where.iter == iter))
|
||||
))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool operator !=(const const_iterator &where) const
|
||||
{
|
||||
return !( (*this) == where );
|
||||
}
|
||||
private:
|
||||
void _Inc()
|
||||
{
|
||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||
return;
|
||||
if (curbucket < 0)
|
||||
{
|
||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket < 0)
|
||||
end = true;
|
||||
} else {
|
||||
if (iter != hash->m_Buckets[curbucket]->end())
|
||||
iter++;
|
||||
if (iter == hash->m_Buckets[curbucket]->end())
|
||||
{
|
||||
int oldbucket = curbucket;
|
||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket == oldbucket)
|
||||
end = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
int curbucket;
|
||||
typename SourceHook::List<THashNode *>::iterator iter;
|
||||
const THash *hash;
|
||||
bool end;
|
||||
};
|
||||
public:
|
||||
iterator begin()
|
||||
{
|
||||
@ -253,6 +383,18 @@ namespace SourceHook
|
||||
iter.hash = this;
|
||||
return iter;
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(this);
|
||||
}
|
||||
const_iterator end() const
|
||||
{
|
||||
const_iterator iter;
|
||||
iter.hash = this;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
iterator find(const U & u) const
|
||||
{
|
||||
|
||||
@ -27,7 +27,10 @@
|
||||
#define SH_GLOB_PLUGPTR g_PLID
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SH_DEBUG
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# define SH_ASSERT__(x, info, file, line, func) \
|
||||
((printf("SOURCEHOOK DEBUG ASSERTION FAILED:\n %s:%u(%s): %s\n", file, line, func, info), true) ? (abort(), 0) : 0)
|
||||
# define SH_ASSERT(x, info) if (!(x)) SH_ASSERT__(x, info, __FILE__, __LINE__, __FUNCTION__)
|
||||
@ -236,6 +239,8 @@ namespace SourceHook
|
||||
class ISourceHook
|
||||
{
|
||||
public:
|
||||
virtual ~ISourceHook()
|
||||
{ }
|
||||
/**
|
||||
* @brief Return interface version
|
||||
*/
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
// Hello BAIL!
|
||||
// hello pm how are you
|
||||
// I'm fine, what about you?
|
||||
// This is a test file
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "sh_tinyhash.h"
|
||||
#include "sh_list.h"
|
||||
#include "sourcehook_impl.h"
|
||||
|
||||
using namespace std;
|
||||
@ -21,7 +22,7 @@ class Test
|
||||
TestProto m_Func;
|
||||
std::string m_Name;
|
||||
|
||||
static std::list<Test *> ms_Tests;
|
||||
static SourceHook::List<Test *> ms_Tests;
|
||||
public:
|
||||
Test(TestProto func, const char *name) : m_Func(func), m_Name(name)
|
||||
{
|
||||
@ -46,7 +47,7 @@ public:
|
||||
static void DoTests()
|
||||
{
|
||||
int passed=0, failed=0;
|
||||
for (std::list<Test*>::iterator iter = ms_Tests.begin(); iter != ms_Tests.end(); ++iter)
|
||||
for (SourceHook::List<Test*>::iterator iter = ms_Tests.begin(); iter != ms_Tests.end(); ++iter)
|
||||
{
|
||||
if ((**iter)())
|
||||
++passed;
|
||||
@ -58,40 +59,22 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::list<Test *> Test::ms_Tests;
|
||||
SourceHook::List<Test *> Test::ms_Tests;
|
||||
|
||||
#define DO_TEST(x) \
|
||||
bool Test##x(std::string &error); \
|
||||
Test g_Test##x(Test##x, #x);
|
||||
|
||||
DO_TEST(List);
|
||||
DO_TEST(Basic);
|
||||
DO_TEST(VafmtAndOverload);
|
||||
DO_TEST(ThisPtrOffs);
|
||||
DO_TEST(PlugSys);
|
||||
DO_TEST(Bail);
|
||||
|
||||
template <>
|
||||
int SourceHook::HashFunction<int>(const int & k)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
|
||||
template <>
|
||||
int SourceHook::Compare<int>(const int & v1, const int & v2)
|
||||
{
|
||||
if (v1 == v2)
|
||||
return 0;
|
||||
if (v1 < v2)
|
||||
return -1;
|
||||
if (v1 > v2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::string error;
|
||||
int passed=0, failed=0;
|
||||
|
||||
g_Verbose = argc > 1 && strcmp(argv[1], "-v") == 0;
|
||||
|
||||
|
||||
165
sourcehook/test/testlist.cpp
Normal file
165
sourcehook/test/testlist.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include <string>
|
||||
#include "sh_list.h"
|
||||
#include "sh_tinyhash.h"
|
||||
|
||||
// TEST LIST
|
||||
// Tests sh_list, sh_tinyhash, sh_vector
|
||||
|
||||
// :TODO: vector test
|
||||
|
||||
#define CHECK_COND(c, err) if (!(c)) { error = err; return false; }
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Hmm
|
||||
{
|
||||
Hmm *m_This;
|
||||
int m_Int;
|
||||
Hmm(const Hmm &other) : m_This(this), m_Int(other.m_Int)
|
||||
{
|
||||
}
|
||||
Hmm(int i) : m_This(this), m_Int(i)
|
||||
{
|
||||
}
|
||||
Hmm() : m_This(this), m_Int(0)
|
||||
{
|
||||
}
|
||||
void operator = (const Hmm &other)
|
||||
{
|
||||
m_Int = other.m_Int;
|
||||
}
|
||||
operator int () const
|
||||
{
|
||||
return m_Int;
|
||||
}
|
||||
};
|
||||
|
||||
#define LIST_THIS_CHECK(lst, err) \
|
||||
for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter) \
|
||||
CHECK_COND(&(*iter) == iter->m_This, err);
|
||||
|
||||
bool DoTestList(std::string &error)
|
||||
{
|
||||
typedef SourceHook::List<Hmm> ListType;
|
||||
ListType lst;
|
||||
|
||||
CHECK_COND(lst.empty(), "Part1");
|
||||
|
||||
for (int i = 1; i <= 100; ++i)
|
||||
lst.push_back(i);
|
||||
|
||||
LIST_THIS_CHECK(lst, "PartA1");
|
||||
|
||||
CHECK_COND(!lst.empty(), "Part2");
|
||||
|
||||
lst.clear();
|
||||
|
||||
CHECK_COND(lst.empty(), "Part3");
|
||||
|
||||
for (int i = 1; i <= 100; ++i)
|
||||
lst.push_back(i);
|
||||
|
||||
CHECK_COND(lst.back() == 100, "Part4");
|
||||
LIST_THIS_CHECK(lst, "PartA2");
|
||||
|
||||
int ver = 1;
|
||||
for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter)
|
||||
CHECK_COND(*iter == ver++, "Part5");
|
||||
|
||||
CHECK_COND(ver == 101, "Part 6");
|
||||
|
||||
ListType::iterator iter50 = lst.find(50);
|
||||
CHECK_COND(*iter50 == 50, "Part7");
|
||||
|
||||
iter50 = lst.erase(iter50);
|
||||
CHECK_COND(*iter50 == 51, "Part8");
|
||||
CHECK_COND(*--iter50 == 49, "Part8.2");
|
||||
|
||||
lst.remove(80);
|
||||
|
||||
ver = 1;
|
||||
for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter)
|
||||
{
|
||||
CHECK_COND(*iter == ver++, "Part9");
|
||||
if (ver == 50 || ver == 80)
|
||||
++ver;
|
||||
}
|
||||
CHECK_COND(ver == 101, "Part10");
|
||||
LIST_THIS_CHECK(lst, "PartA3");
|
||||
|
||||
ListType lst2;
|
||||
lst = lst2;
|
||||
CHECK_COND(lst.empty(), "Part11");
|
||||
|
||||
for (int i = 1; i <= 100; ++i)
|
||||
lst.push_back(i);
|
||||
lst2 = lst;
|
||||
CHECK_COND(lst2.size() == 100, "Part11.2");
|
||||
|
||||
LIST_THIS_CHECK(lst, "PartA4");
|
||||
LIST_THIS_CHECK(lst2, "PartA5");
|
||||
|
||||
ver = 1;
|
||||
for (ListType::iterator iter = lst2.begin(); iter != lst2.end(); ++iter)
|
||||
CHECK_COND(*iter == ver++, "Part12");
|
||||
|
||||
lst.clear();
|
||||
for (int i = 401; i <= 500; ++i)
|
||||
lst.push_back(i);
|
||||
lst = lst2;
|
||||
CHECK_COND(lst2.size() == 100, "Part13");
|
||||
|
||||
ver = 1;
|
||||
for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter)
|
||||
CHECK_COND(*iter == ver++, "Part14");
|
||||
|
||||
LIST_THIS_CHECK(lst, "PartA6");
|
||||
LIST_THIS_CHECK(lst2, "PartA7");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DoTestTinyHash(std::string &error)
|
||||
{
|
||||
const int mymax = 5000;
|
||||
|
||||
typedef SourceHook::THash<int, int> HashType;
|
||||
HashType hash;
|
||||
|
||||
for (int i = 1; i <= mymax; ++i)
|
||||
hash[i] = i + 5000;
|
||||
|
||||
for (int i = 1; i <= mymax; ++i)
|
||||
CHECK_COND(hash[i] == i + 5000, "Part1");
|
||||
|
||||
// Find
|
||||
int ver = 1;
|
||||
for (HashType::iterator iter = hash.begin(); iter != hash.end(); ++iter)
|
||||
CHECK_COND(iter->key == ver && iter->val == (ver++) + 5000, "Part2");
|
||||
|
||||
CHECK_COND(ver == mymax+1, "Part2.1");
|
||||
|
||||
HashType::iterator iter = hash.find(300);
|
||||
CHECK_COND(iter != hash.end() && iter->val == 300+5000, "Part3.1");
|
||||
iter = hash.find(mymax+200);
|
||||
CHECK_COND(iter == hash.end(), "Part3.2");
|
||||
|
||||
HashType hash2;
|
||||
for (int i = 1; i <= mymax; ++i)
|
||||
hash2[i] = i + 5000;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TestList(std::string &error)
|
||||
{
|
||||
if (!DoTestList(error))
|
||||
return false;
|
||||
|
||||
if (!DoTestTinyHash(error))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user