在VC6恶劣的环境下实现神一般操作的模板

/*******************************************************************
 file name : LUA_Util.h
 author  :   Clark/陈泽丹
 created :   2013-2-2
 purpose :   在不改动原有方式的前提下, 简化Lua与C++互相调用的函数接口
*********************************************************************/

#ifndef	__LUAUTIL_H__
#define	__LUAUTIL_H__



#define TYPELIST_1(T1) \
Lua_Typelist<T1, Lua_NullType>

#define TYPELIST_2(T1, T2) \
Lua_Typelist<T1, TYPELIST_1(T2) >

#define TYPELIST_3(T1, T2, T3) \
Lua_Typelist<T1, TYPELIST_2(T2, T3) >

#define TYPELIST_4(T1, T2, T3, T4) \
Lua_Typelist<T1, TYPELIST_3(T2, T3, T4) >

#define TYPELIST_5(T1, T2, T3, T4, T5) \
Lua_Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >

#define TYPELIST_6(T1, T2, T3, T4, T5, T6) \
Lua_Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >

#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
Lua_Typelist<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >

#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
Lua_Typelist<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >



//并排参数用
#define GET_TYPELIST_PAR1( Par ) \
	Par.head

#define GET_TYPELIST_PAR2( Par ) \
	Par.head, GET_TYPELIST_PAR1( Par.tail )

#define GET_TYPELIST_PAR3( Par ) \
	Par.head, GET_TYPELIST_PAR2( Par.tail )

#define GET_TYPELIST_PAR4( Par ) \
	Par.head, GET_TYPELIST_PAR3( Par.tail )

#define GET_TYPELIST_PAR5( Par ) \
	Par.head, GET_TYPELIST_PAR4( Par.tail )

#define GET_TYPELIST_PAR6( Par ) \
	Par.head, GET_TYPELIST_PAR5( Par.tail )

#define GET_TYPELIST_PAR7( Par ) \
	Par.head, GET_TYPELIST_PAR6( Par.tail )

#define GET_TYPELIST_PAR8( Par ) \
	Par.head, GET_TYPELIST_PAR7( Par.tail )

struct Lua_RunFun
{
	template<class _Ret, int>
	struct RunFun
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			g_pTrace->TraceErrorLn("执行LUA时, 调用API找不到相应的适配函数");
		}
	};
	
	template<>
	struct RunFun<void, 1>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR1(par) );
		}
	};
	
	template<>
	struct RunFun<void, 2>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR2(par) );
		}
	};
	
	template<>
	struct RunFun<void, 3>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR3(par) );
		}
	};
	
	template<>
		struct RunFun<void, 4>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR4(par) );
		}
	};

	template<>
		struct RunFun<void, 5>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR5(par) );
		}
	};

	template<>
		struct RunFun<void, 6>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR6(par) );
		}
	};

	template<>
		struct RunFun<void, 7>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR7(par) );
		}
	};

	template<>
	struct RunFun<void, 8>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_fun( GET_TYPELIST_PAR8(par) );
		}
	};
	
	//------------------------------
	template< class _R >
	struct RunFun<_R, 1>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR1(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};
	
	template< class _R >
	struct RunFun<_R, 2>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR2(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};
	
	template< class _R >
	struct RunFun<_R, 3>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR3(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};

	template< class _R >
	struct RunFun<_R, 4>
	{
		template< class _Fun, class _TL >
		void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR4(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};

	template< class _R >
	struct RunFun<_R, 5>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR5(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};

	template< class _R >
	struct RunFun<_R, 6>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR6(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};

	template< class _R >
	struct RunFun<_R, 7>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR7(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};

	template< class _R >
	struct RunFun<_R, 8>
	{
		template< class _Fun, class _TL >
			void operator()(_Fun _fun, _TL& par, lua_State* _tolua_S)
		{
			_R _r = _fun( GET_TYPELIST_PAR8(par) );
			Lua_SetPar(_r, _tolua_S);
		}
	};
};

#endif  // __LUAUTIL_H__


 

/*******************************************************************
 file name : LUA_And_C.h
 author  :   Clark/陈泽丹
 created :   2013-2-2
 purpose :   在不改动原有方式的前提下, 简化Lua与C++互相调用的函数接口
*********************************************************************/

#ifndef	__LUA_AND_C_H__
#define	__LUA_AND_C_H__

#include "LUA_Util.h"

#ifndef __cplusplus
#include "stdlib.h"
#endif
#include "string.h"
#include "tolua++.h"





//-----------------------------------------------------------
template< class _Type >
struct Lua_IsType	
{
	// 获得Lua传出来的参数
	bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err){ return false; }
};
template<>
struct Lua_IsType<char*>
{
	// 获得Lua传出来的参数
	bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err)
	{
		return tolua_isstring(_tolua_S, _lo, 0, &_tolua_err);
	}
};
template<>
struct Lua_IsType<long>
{
	// 获得Lua传出来的参数
	bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err)
	{
		return tolua_isnumber(_tolua_S, _lo, 0, &_tolua_err);
	}
};
template<>
struct Lua_IsType<bool>
{
	// 获得Lua传出来的参数
	bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err)
	{
		return tolua_isboolean(_tolua_S, _lo, 0, &_tolua_err);
	}
};


//-------------------------------
// 获得Lua传出来的参数
template< class _Type >
bool Lua_GetPar(_Type*& _val, lua_State* _tolua_S, int _lo)
{
	return false;
}
// 获得Lua传出来的参数
bool Lua_GetPar(char*& _val, lua_State* _tolua_S, int _lo)
{
	_val =  ((char*) tolua_tostring(_tolua_S,_lo,0));
	return true;
}
// 获得Lua传出来的参数
bool Lua_GetPar(long& _val, lua_State* _tolua_S, int _lo)
{
	_val =  ((long) tolua_tonumber(_tolua_S,_lo,0));
	return true;
}
// 获得Lua传出来的参数
bool Lua_GetPar(bool& _val, lua_State* _tolua_S, int _lo)
{
	_val =  ((bool) tolua_toboolean(_tolua_S, _lo, 0));
	return true;
}

//-------------------------------
// 传进Lua的参数
template< class _Type >
bool Lua_SetPar(_Type*& _val, lua_State* _tolua_S)
{
	return false;
}
// 获得Lua传出来的参数
bool Lua_SetPar(char*& _val, lua_State* _tolua_S)
{
	tolua_pushstring(_tolua_S, _val);
	return true;
}
// 获得Lua传出来的参数
bool Lua_SetPar(long& _val, lua_State* _tolua_S)
{
	tolua_pushnumber(_tolua_S, _val);
	return true;
}
// 获得Lua传出来的参数
bool Lua_SetPar(bool& _val, lua_State* _tolua_S)
{
	tolua_pushboolean(_tolua_S, _val);
	return true;
}


//--------------------------------------------------
struct Lua_NullType{};

template <class T, class U>
struct Lua_Typelist
{
	typedef T Head;
	typedef U Tail;
	Head head;
	Tail tail;
};

//获得相关参数
template< class TList >
struct Lua_GetLength
{
	enum { Ret = 1 + Lua_GetLength< TList::Tail >::Ret };
};
template<>
struct Lua_GetLength<Lua_NullType>
{
	enum { Ret = 0 };
};


//-------------------------------
template< class Ret, class _TypeList >
class API_Fun
{
public:
	template< class _Fun >
		int operator()(lua_State* _tolua_S, _Fun _fun, const char* _error_txt)
	{
#ifndef TOLUA_RELEASE
		tolua_Error tolua_err;
		if( !checkPar<_TypeList>()(_tolua_S, 1, tolua_err) )
			goto tolua_lerror;
#endif
		try   
		{
			getPar<_TypeList>()(_m_data, _tolua_S, 1);
			Lua_RunFun::RunFun< Ret, Lua_GetLength<_TypeList>::Ret > runfun;
			runfun(_fun, _m_data, _tolua_S);
		}
		catch (...)
		{
			g_pTrace->TraceErrorLn(_error_txt);
			throw;
			return 1;
		}
		return 0;
tolua_lerror:
#ifndef TOLUA_RELEASE
		tolua_error(_tolua_S, _error_txt, &tolua_err);
		return 0;
#endif
	}
	
private:
	//检查类型是否正确
	template< class _TL >
		struct checkPar
	{
		bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err)
		{
			if( Lua_IsType<_TL::Head>()(_tolua_S, _lo, _tolua_err) )
				return checkPar<_TL::Tail>()(_tolua_S, _lo+1, _tolua_err);
			return false;
		}
	};
	template<>
		struct checkPar<Lua_NullType>
	{
		bool operator()(lua_State* _tolua_S, int _lo, tolua_Error& _tolua_err)
		{
			return tolua_isnoobj(_tolua_S, _lo, &_tolua_err);
		}
	};
	
	//获得相关参数
	template< class _TL >
		struct getPar
	{
		bool operator()(_TL& par, lua_State* _tolua_S, int _lo)
		{
			if( Lua_GetPar(par.head, _tolua_S, _lo) )
				return getPar<_TL::Tail>()(par.tail, _tolua_S, _lo+1);
			return false;
		}
	};
	template<>
		struct getPar<Lua_NullType>
	{
		bool operator()(Lua_NullType& par, lua_State* _tolua_S, int _lo)
		{
			return true;
		}
	};
	
private:
	_TypeList _m_data;
};





#endif  // __LUA_AND_C_H__


 

你可能感兴趣的:(在VC6恶劣的环境下实现神一般操作的模板)