(svn r9406) [NoAI] -Fix: made the detection of 'void' against 'non-void' functions for the class->SQ convertor via templates (as MSVC failed to understand the other method) (KUDr) noai
authortruelight
Thu, 22 Mar 2007 09:10:00 +0000
branchnoai
changeset 9510 261d33fbabb8
parent 9509 86ff6927e68a
child 9511 f767ad06e86b
(svn r9406) [NoAI] -Fix: made the detection of 'void' against 'non-void' functions for the class->SQ convertor via templates (as MSVC failed to understand the other method) (KUDr)
-Fix: merged squirrel_helper.cpp to squirrel_helper.hpp, as that was a silly attempt of TrueLight (KUDr)
-Fix: put all Squirrel conversion code in a namespace instead of a class (to avoid G++ bitching) (KUDr)
projects/openttd.vcproj
projects/openttd_vs80.vcproj
source.list
src/ai/api/ai_order.hpp
src/ai/api/ai_transactionmode.hpp
src/squirrel_helper.cpp
src/squirrel_helper.hpp
--- a/projects/openttd.vcproj	Thu Mar 22 08:58:17 2007 +0000
+++ b/projects/openttd.vcproj	Thu Mar 22 09:10:00 2007 +0000
@@ -347,9 +347,6 @@
 				RelativePath=".\..\src\squirrel.cpp">
 			</File>
 			<File
-				RelativePath=".\..\src\squirrel_helper.cpp">
-			</File>
-			<File
 				RelativePath=".\..\src\squirrel_std.cpp">
 			</File>
 			<File
--- a/projects/openttd_vs80.vcproj	Thu Mar 22 08:58:17 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Thu Mar 22 09:10:00 2007 +0000
@@ -692,10 +692,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\squirrel_helper.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\squirrel_std.cpp"
 				>
 			</File>
--- a/source.list	Thu Mar 22 08:58:17 2007 +0000
+++ b/source.list	Thu Mar 22 09:10:00 2007 +0000
@@ -68,7 +68,6 @@
 string.cpp
 strings.cpp
 squirrel.cpp
-squirrel_helper.cpp
 squirrel_std.cpp
 texteff.cpp
 tgp.cpp
--- a/src/ai/api/ai_order.hpp	Thu Mar 22 08:58:17 2007 +0000
+++ b/src/ai/api/ai_order.hpp	Thu Mar 22 09:10:00 2007 +0000
@@ -156,9 +156,12 @@
 DECLARE_ENUM_AS_BIT_SET(AIOrder::AIOrderFlags);
 
 #ifdef DEFINE_SQUIRREL_CLASS
+
 /* Custom template to allow AIOrderFlags as param */
-template <> AIOrder::AIOrderFlags SQConvert::GetParam(ForceType<AIOrder::AIOrderFlags>, HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIOrder::AIOrderFlags)tmp; }
-template <> int SQConvert::Return<AIOrder::AIOrderFlags>(HSQUIRRELVM vm, AIOrder::AIOrderFlags res) { sq_pushinteger(vm, (int32)res); return 1; }
+namespace SQConvert {
+	template <> AIOrder::AIOrderFlags GetParam(ForceType<AIOrder::AIOrderFlags>, HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIOrder::AIOrderFlags)tmp; }
+	template <> int Return<AIOrder::AIOrderFlags>(HSQUIRRELVM vm, AIOrder::AIOrderFlags res) { sq_pushinteger(vm, (int32)res); return 1; }
+}; // namespace SQConvert
 
 void SQAIOrderRegister(Squirrel *engine) {
 	DefSQClass <AIOrder> SQAIOrder("AIOrder");
--- a/src/ai/api/ai_transactionmode.hpp	Thu Mar 22 08:58:17 2007 +0000
+++ b/src/ai/api/ai_transactionmode.hpp	Thu Mar 22 09:10:00 2007 +0000
@@ -103,7 +103,9 @@
 
 #ifdef DEFINE_SQUIRREL_CLASS
 /* Custom template to allow AITransactionMode-instance as param */
-template <> AITransactionMode *SQConvert::GetParam(ForceType<AITransactionMode *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AITransactionMode *)instance; }
+namespace SQConvert {
+	template <> AITransactionMode *GetParam(ForceType<AITransactionMode *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AITransactionMode *)instance; }
+}; // namespace SQConvert
 
 void SQAITransactionModeRegister(Squirrel *engine) {
 	DefSQClass <AITransactionMode> SQAITransactionMode("AITransactionMode");
--- a/src/squirrel_helper.cpp	Thu Mar 22 08:58:17 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/* $Id$ */
-
-/** @file squirrel_helper.cpp parts of the implementation of the class for convert code */
-
-#include "stdafx.h"
-#include "squirrel_helper.hpp"
-
-template <> int SQConvert::Return<uint8> (HSQUIRRELVM vm, uint8 res)  { sq_pushinteger(vm, (int32)res); return 1; }
-template <> int SQConvert::Return<uint16>(HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
-template <> int SQConvert::Return<uint32>(HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
-template <> int SQConvert::Return<int8>  (HSQUIRRELVM vm, int8 res)   { sq_pushinteger(vm, res); return 1; }
-template <> int SQConvert::Return<int16> (HSQUIRRELVM vm, int16 res)  { sq_pushinteger(vm, res); return 1; }
-template <> int SQConvert::Return<int32> (HSQUIRRELVM vm, int32 res)  { sq_pushinteger(vm, res); return 1; }
-template <> int SQConvert::Return<bool>  (HSQUIRRELVM vm, bool res)   { sq_pushbool   (vm, res); return 1; }
-template <> int SQConvert::Return<char *>(HSQUIRRELVM vm, char *res)  { if (res == NULL) sq_pushnull(vm); else sq_pushstring (vm, OTTD2FS(res), strlen(res)); free(res); return 1; }
-
-template <> uint8       SQConvert::GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> uint16      SQConvert::GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> uint32      SQConvert::GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> int8        SQConvert::GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> int16       SQConvert::GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> int32       SQConvert::GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
-template <> bool        SQConvert::GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index) { SQBool        tmp; sq_getbool   (vm, index, &tmp); return tmp != 0; }
-template <> const char *SQConvert::GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index) { const SQChar *tmp; sq_getstring (vm, index, &tmp); return FS2OTTD(tmp); }
--- a/src/squirrel_helper.hpp	Thu Mar 22 08:58:17 2007 +0000
+++ b/src/squirrel_helper.hpp	Thu Mar 22 09:10:00 2007 +0000
@@ -8,10 +8,39 @@
 #include <squirrel.h>
 
 /**
- * The Squirrel convert class. It doesn't have an instance, the methods only are used.
+ * The Squirrel convert routines
  */
-class SQConvert {
-public:
+namespace SQConvert {
+
+	template <bool Y> struct YesT {
+		static const bool Yes = Y;
+		static const bool No = !Y;
+	};
+
+	/**
+	 * Helper class to recognize if the given type is void. Usage: 'IsVoidT<T>::Yes'
+	 */
+	template <typename T> struct IsVoidT : YesT<false> {};
+	template <> struct IsVoidT<void> : YesT<true> {};
+
+	/**
+	 * Helper class to recognize if the function/method return type is void.
+	 */
+	template <typename Tfunc> struct HasVoidReturnT;
+	/* functions */
+	template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
+	template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
+	template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
+	/* methods */
+	template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
+	template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
+
+
 	/**
 	 * Special class to make it possible for the compiler to pick the correct GetParam().
 	 */
@@ -22,264 +51,330 @@
 	 */
 	template <typename T> static int Return(HSQUIRRELVM vm, T t);
 
+	template <> inline int Return<uint8> (HSQUIRRELVM vm, uint8 res)  { sq_pushinteger(vm, (int32)res); return 1; }
+	template <> inline int Return<uint16>(HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
+	template <> inline int Return<uint32>(HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
+	template <> inline int Return<int8>  (HSQUIRRELVM vm, int8 res)   { sq_pushinteger(vm, res); return 1; }
+	template <> inline int Return<int16> (HSQUIRRELVM vm, int16 res)  { sq_pushinteger(vm, res); return 1; }
+	template <> inline int Return<int32> (HSQUIRRELVM vm, int32 res)  { sq_pushinteger(vm, res); return 1; }
+	template <> inline int Return<bool>  (HSQUIRRELVM vm, bool res)   { sq_pushbool   (vm, res); return 1; }
+	template <> inline int Return<char *>(HSQUIRRELVM vm, char *res)  { if (res == NULL) sq_pushnull(vm); else sq_pushstring (vm, OTTD2FS(res), strlen(res)); free(res); return 1; }
+
 	/**
 	 * To get a param from squirrel, we call this function. It converts to the right format.
 	 */
 	template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index);
 
-	/**
-	 * The real C++ caller for method with a return value and 0 params.
-	 */
-	template <typename CL, typename RT>
-	static int SQCall(CL *instance, RT (CL::*func)(), HSQUIRRELVM vm)
-	{
-		return Return(vm, (instance->*func)());
-	}
+	template <> inline uint8       GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline uint16      GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline uint32      GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline int8        GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline int16       GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline int32       GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index) { SQInteger     tmp; sq_getinteger(vm, index, &tmp); return tmp; }
+	template <> inline bool        GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index) { SQBool        tmp; sq_getbool   (vm, index, &tmp); return tmp != 0; }
+	template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index) { const SQChar *tmp; sq_getstring (vm, index, &tmp); return FS2OTTD(tmp); }
 
 	/**
-	 * The real C++ caller for function with a return value and 0 params.
-	 */
-	template <typename CL, typename RT>
-	static int SQCall(CL *instance, RT (*func)(), HSQUIRRELVM vm)
-	{
-		return Return(vm, (*func)());
-	}
+	* Helper class to recognize the function type (retval type, args) and use the proper specialization
+	* for SQ callback. The partial specializations for the second arg (Tis_void_retval) are not possible
+	* on the function. Therefore the class is used instead.
+	*/
+	template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
 
 	/**
-	 * The real C++ caller for method with no return value and 0 params.
+	 * The real C++ caller for function with return value and 0 params.
 	 */
-	template <typename CL>
-	static int SQCall(CL *instance, void (CL::*func)(), HSQUIRRELVM vm)
-	{
-		(instance->*func)();
-		return 0;
-	}
+	template <typename Tretval>
+	struct HelperT<Tretval (*)(), false> {
+		static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
+		{
+			return Return(vm, (*func)());
+		}
+	};
 
 	/**
 	 * The real C++ caller for function with no return value and 0 params.
 	 */
-	template <typename CL>
-	static int SQCall(CL *instance, void (*func)(), HSQUIRRELVM vm)
-	{
-		(*func)();
-		return 0;
-	}
+	template <typename Tretval>
+	struct HelperT<Tretval (*)(), true> {
+		static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
+		{
+			(*func)();
+			return 0;
+		}
+	};
 
 	/**
-	 * The real C++ caller for method with a return value and 1 param.
+	 * The real C++ caller for method with return value and 0 params.
 	 */
-	template <typename CL, typename RT, typename P1>
-	static int SQCall(CL *instance, RT (CL::*func)(P1), HSQUIRRELVM vm)
-	{
-		return Return(vm, (instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2)
-					));
-	}
+	template <class Tcls, typename Tretval>
+	struct HelperT<Tretval (Tcls::*)(), false> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
+		{
+			return Return(vm, (instance->*func)());
+		}
+	};
 
 	/**
-	 * The real C++ caller for function with a return value and 1 param.
+	 * The real C++ caller for method with no return value and 0 params.
 	 */
-	template <typename CL, typename RT, typename P1>
-	static int SQCall(CL *instance, RT (*func)(P1), HSQUIRRELVM vm)
-	{
-		return Return(vm, (*func)(
-						GetParam(ForceType<P1>(), vm, 2)
-					));
-	}
+	template <class Tcls, typename Tretval>
+	struct HelperT<Tretval (Tcls::*)(), true> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
+		{
+			(instance->*func)();
+			return 0;
+		}
+	};
+
+	/**
+	 * The real C++ caller for function with return value and 1 param.
+	 */
+	template <typename Tretval, typename Targ1>
+	struct HelperT<Tretval (*)(Targ1), false> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
+		{
+			return Return(vm, (*func)(
+				GetParam(ForceType<Targ1>(), vm, 2)
+			));
+		}
+	};
+
+	/**
+	 * The real C++ caller for function with no return value and 1 param.
+	 */
+	template <typename Tretval, typename Targ1>
+	struct HelperT<Tretval (*)(Targ1), true> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
+		{
+			(*func)(
+				GetParam(ForceType<Targ1>(), vm, 2)
+			);
+			return 0;
+		}
+	};
+
+	/**
+	 * The real C++ caller for method with return value and 1 param.
+	 */
+	template <class Tcls, typename Tretval, typename Targ1>
+	struct HelperT<Tretval (Tcls::*)(Targ1), false> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
+		{
+			return Return(vm, (instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2)
+			));
+		}
+	};
 
 	/**
 	 * The real C++ caller for method with no return value and 1 param.
 	 */
-	template <typename CL, typename P1>
-	static int SQCall(CL *instance, void (CL::*func)(P1), HSQUIRRELVM vm)
-	{
-		(instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2)
-					);
-		return 0;
-	}
-
-	/**
-	 * The real C++ caller for function with no return value and 1 param.
-	 */
-	template <typename CL, typename P1>
-	static int SQCall(CL *instance, void (*func)(P1), HSQUIRRELVM vm)
-	{
-		(*func)(
-						GetParam(ForceType<P1>(), vm, 2)
-					);
-		return 0;
-	}
+	template <class Tcls, typename Tretval, typename Targ1>
+	struct HelperT<Tretval (Tcls::*)(Targ1), true> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
+		{
+			(instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2)
+			);
+			return 0;
+		}
+	};
 
 	/**
-	 * The real C++ caller for method with a return value and 2 params.
+	 * The real C++ caller for function with return value and 2 params.
 	 */
-	template <typename CL, typename RT, typename P1, typename P2>
-	static int SQCall(CL *instance, RT (CL::*func)(P1, P2), HSQUIRRELVM vm)
-	{
-		return Return(vm, (instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3)
-					));
-	}
+	template <typename Tretval, typename Targ1, typename Targ2>
+	struct HelperT<Tretval (*)(Targ1, Targ2), false> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
+		{
+			return Return(vm, (*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3)
+			));
+		}
+	};
 
 	/**
-	 * The real C++ caller for function with a return value and 2 params.
+	 * The real C++ caller for function with no return value and 2 params.
 	 */
-	template <typename CL, typename RT, typename P1, typename P2>
-	static int SQCall(CL *instance, RT (*func)(P1, P2), HSQUIRRELVM vm)
-	{
-		return Return(vm, (*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3)
-					));
-	}
+	template <typename Tretval, typename Targ1, typename Targ2>
+	struct HelperT<Tretval (*)(Targ1, Targ2), true> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
+		{
+			(*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3)
+			);
+			return 0;
+		}
+	};
+
+	/**
+	 * The real C++ caller for method with return value and 2 params.
+	 */
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
+		{
+			return Return(vm, (instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3)
+			));
+		}
+	};
 
 	/**
 	 * The real C++ caller for method with no return value and 2 params.
 	 */
-	template <typename CL, typename P1, typename P2>
-	static int SQCall(CL *instance, void (CL::*func)(P1, P2), HSQUIRRELVM vm)
-	{
-		(instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3)
-					);
-		return 0;
-	}
-
-	/**
-	 * The real C++ caller for function with no return value and 2 params.
-	 */
-	template <typename CL, typename P1, typename P2>
-	static int SQCall(CL *instance, void (*func)(P1, P2), HSQUIRRELVM vm)
-	{
-		(*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3)
-					);
-		return 0;
-	}
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
+		{
+			(instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3)
+			);
+			return 0;
+		}
+	};
 
 	/**
-	 * The real C++ caller for method with a return value and 3 params.
-	 */
-	template <typename CL, typename RT, typename P1, typename P2, typename P3>
-	static int SQCall(CL *instance, RT (CL::*func)(P1, P2, P3), HSQUIRRELVM vm)
-	{
-		return Return(vm, (instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4)
-					));
-	}
-
-	/**
-	 * The real C++ caller for function with a return value and 3 params.
+	 * The real C++ caller for function with return value and 3 params.
 	 */
-	template <typename CL, typename RT, typename P1, typename P2, typename P3>
-	static int SQCall(CL *instance, RT (*func)(P1, P2, P3), HSQUIRRELVM vm)
-	{
-		return Return(vm, (*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4)
-					));
-	}
-
-	/**
-	 * The real C++ caller for method with no return value and 3 params.
-	 */
-	template <typename CL, typename P1, typename P2, typename P3>
-	static int SQCall(CL *instance, void (CL::*func)(P1, P2, P3), HSQUIRRELVM vm)
-	{
-		(instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4)
-					);
-		return 0;
-	}
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
+	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
+		{
+			return Return(vm, (*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4)
+			));
+		}
+	};
 
 	/**
 	 * The real C++ caller for function with no return value and 3 params.
 	 */
-	template <typename CL, typename P1, typename P2, typename P3>
-	static int SQCall(CL *instance, void (*func)(P1, P2, P3), HSQUIRRELVM vm)
-	{
-		(*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4)
-					);
-		return 0;
-	}
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
+	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
+		{
+			(*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4)
+			);
+			return 0;
+		}
+	};
 
 	/**
-	 * The real C++ caller for method with a return value and 4 params.
+	 * The real C++ caller for method with return value and 3 params.
 	 */
-	template <typename CL, typename RT, typename P1, typename P2, typename P3, typename P4>
-	static int SQCall(CL *instance, RT (CL::*func)(P1, P2, P3, P4), HSQUIRRELVM vm)
-	{
-		return Return(vm, (instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4),
-						GetParam(ForceType<P4>(), vm, 5)
-					));
-	}
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
+		{
+			return Return(vm, (instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4)
+			));
+		}
+	};
 
 	/**
-	 * The real C++ caller for function with a return value and 4 params.
+	 * The real C++ caller for method with no return value and 3 params.
 	 */
-	template <typename CL, typename RT, typename P1, typename P2, typename P3, typename P4>
-	static int SQCall(CL *instance, RT (*func)(P1, P2, P3, P4), HSQUIRRELVM vm)
-	{
-		return Return(vm, (*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4),
-						GetParam(ForceType<P4>(), vm, 5)
-					));
-	}
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
+		{
+			(instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4)
+			);
+			return 0;
+		}
+	};
+
+	/**
+	 * The real C++ caller for function with return value and 4 params.
+	 */
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
+	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
+		{
+			return Return(vm, (*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4),
+				GetParam(ForceType<Targ4>(), vm, 5)
+			));
+		}
+	};
+
+	/**
+	 * The real C++ caller for function with no return value and 4 params.
+	 */
+	template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
+	struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
+		static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
+		{
+			(*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4),
+				GetParam(ForceType<Targ4>(), vm, 5)
+			);
+			return 0;
+		}
+	};
+
+	/**
+	 * The real C++ caller for method with return value and 4 params.
+	 */
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
+		{
+			return Return(vm, (instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4),
+				GetParam(ForceType<Targ4>(), vm, 5)
+			));
+		}
+	};
 
 	/**
 	 * The real C++ caller for method with no return value and 4 params.
 	 */
-	template <typename CL, typename P1, typename P2, typename P3, typename P4>
-	static int SQCall(CL *instance, void (CL::*func)(P1, P2, P3, P4), HSQUIRRELVM vm)
-	{
-		(instance->*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4),
-						GetParam(ForceType<P4>(), vm, 5)
-					);
-		return 0;
-	}
+	template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
+	struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
+		static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
+		{
+			(instance->*func)(
+				GetParam(ForceType<Targ1>(), vm, 2),
+				GetParam(ForceType<Targ2>(), vm, 3),
+				GetParam(ForceType<Targ3>(), vm, 4),
+				GetParam(ForceType<Targ4>(), vm, 5)
+			);
+			return 0;
+		}
+	};
 
-	/**
-	 * The real C++ caller for function with no return value and 4 params.
-	 */
-	template <typename CL, typename P1, typename P2, typename P3, typename P4>
-	static int SQCall(CL *instance, void (*func)(P1, P2, P3, P4), HSQUIRRELVM vm)
-	{
-		(*func)(
-						GetParam(ForceType<P1>(), vm, 2),
-						GetParam(ForceType<P2>(), vm, 3),
-						GetParam(ForceType<P3>(), vm, 4),
-						GetParam(ForceType<P4>(), vm, 5)
-					);
-		return 0;
-	}
 
 	/**
 	 * A general template for all callback functions from Squirrel.
 	 *  In here the function_proc is recovered, and the SQCall is called that
 	 *  can handle this exact amount of params.
 	 */
-	template <typename CL, typename Func>
-	static SQInteger DefSQCallback(HSQUIRRELVM vm)
+	template <typename Tcls, typename Tmethod>
+	inline SQInteger DefSQCallback(HSQUIRRELVM vm)
 	{
 		/* Find the amount of params we got */
 		int nparam = sq_gettop(vm);
@@ -290,9 +385,10 @@
 		sq_getinstanceup(vm, 1, &instance, 0);
 		/* Get the real function pointer */
 		sq_getuserdata(vm, nparam, &ptr, 0);
-		/* Deligate it to a template that can handle this specific function */
-		return SQCall((CL *)instance, *(Func *)ptr, vm);
+		/* Delegate it to a template that can handle this specific function */
+		return HelperT<Tmethod>::SQCall((Tcls *)instance, *(Tmethod *)ptr, vm);
 	}
-};
+
+}; // namespace SQConvert
 
 #endif /* SQUIRREL_HELPER_HPP */