//	Open-MGL / MSL の myu_class_func_ptr より流用

#ifndef __agh_class_func_ptr_H__
#define __agh_class_func_ptr_H__

#define AGH_PP_LPARE		(

//////////////////////////////////////////////////////

//	Incriment - インクリメント
#define AGH_PP_INC__0	1
#define AGH_PP_INC__1	2
#define AGH_PP_INC__2	3
#define AGH_PP_INC__3	4
#define AGH_PP_INC__4	5
#define AGH_PP_INC__5	6
#define AGH_PP_INC__6	7
#define AGH_PP_INC__7	8
#define AGH_PP_INC__8	9
#define AGH_PP_INC__9	10

#define AGH_PP_INC_(x)	AGH_PP_INC__##x
#define AGH_PP_INC(x)	AGH_PP_INC_(x)

//////////////////////////////////////////////////////

//	繰り返し
#define AGH_PP_REPEART_INC__0(callback)		
#define AGH_PP_REPEART_INC__1(callback)		AGH_PP_REPEART_INC__0(callback)	callback(1)
#define AGH_PP_REPEART_INC__2(callback)		AGH_PP_REPEART_INC__1(callback)	callback(2)
#define AGH_PP_REPEART_INC__3(callback)		AGH_PP_REPEART_INC__2(callback)	callback(3)
#define AGH_PP_REPEART_INC__4(callback)		AGH_PP_REPEART_INC__3(callback)	callback(4)
#define AGH_PP_REPEART_INC__5(callback)		AGH_PP_REPEART_INC__4(callback)	callback(5)
#define AGH_PP_REPEART_INC__6(callback)		AGH_PP_REPEART_INC__5(callback)	callback(6)
#define AGH_PP_REPEART_INC__7(callback)		AGH_PP_REPEART_INC__6(callback)	callback(7)
#define AGH_PP_REPEART_INC__8(callback)		AGH_PP_REPEART_INC__7(callback)	callback(8)
#define AGH_PP_REPEART_INC__9(callback)		AGH_PP_REPEART_INC__8(callback)	callback(9)
#define AGH_PP_REPEART_INC__10(callback)		AGH_PP_REPEART_INC__9(callback)	callback(10)

#define AGH_PP_REPEART_INC_(x,callback)		AGH_PP_REPEART_INC__##x(callback)
#define AGH_PP_REPEART_INC(x,callback)		AGH_PP_REPEART_INC_(x,callback)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define AGH_PP_COMMA_REPEART_INC__0(callback)		
#define AGH_PP_COMMA_REPEART_INC__1(callback)		AGH_PP_COMMA_REPEART_INC__0(callback)	callback(1)
#define AGH_PP_COMMA_REPEART_INC__2(callback)		AGH_PP_COMMA_REPEART_INC__1(callback),	callback(2)
#define AGH_PP_COMMA_REPEART_INC__3(callback)		AGH_PP_COMMA_REPEART_INC__2(callback),	callback(3)
#define AGH_PP_COMMA_REPEART_INC__4(callback)		AGH_PP_COMMA_REPEART_INC__3(callback),	callback(4)
#define AGH_PP_COMMA_REPEART_INC__5(callback)		AGH_PP_COMMA_REPEART_INC__4(callback),	callback(5)
#define AGH_PP_COMMA_REPEART_INC__6(callback)		AGH_PP_COMMA_REPEART_INC__5(callback),	callback(6)
#define AGH_PP_COMMA_REPEART_INC__7(callback)		AGH_PP_COMMA_REPEART_INC__6(callback),	callback(7)
#define AGH_PP_COMMA_REPEART_INC__8(callback)		AGH_PP_COMMA_REPEART_INC__7(callback),	callback(8)
#define AGH_PP_COMMA_REPEART_INC__9(callback)		AGH_PP_COMMA_REPEART_INC__8(callback),	callback(9)
#define AGH_PP_COMMA_REPEART_INC__10(callback)		AGH_PP_COMMA_REPEART_INC__9(callback),	callback(10)

#define AGH_PP_COMMA_REPEART_INC_(x,callback)		AGH_PP_COMMA_REPEART_INC__##x(callback)
#define AGH_PP_COMMA_REPEART_INC(x,callback)		AGH_PP_COMMA_REPEART_INC_(x,callback)

//////////////////////////////////////////////////////

#define _CAghClassFuncPtr_TMPL_ARGS_(X)		typename _ARG ##X
#define _CAghClassFuncPtr_FUNC_ARGS_(X)		_ARG ##X  arg ##X
#define _CAghClassFuncPtr_CALL_ARGS_(X)		arg ##X

//		public CAghClassFuncPtrBase<_R ()(
//			AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_FUNC_ARGS_))>

//		void Set(void* pInstance, CLASS_FUNC_PTR pFunc){	\
//			CAghClassFuncPtrBase::Set(pInstance,(void*)pFunc);	\
//		}	\
//		\
//

#define _CAghClassFuncPtr_X(NUM)	\
	template <typename _R, \
		AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_TMPL_ARGS_)>	\
	class CAghClassFuncPtr##NUM		\
	{	\
	public:	\
		class _CDummyBase{}; /* ダミークラス（コンパイラを誤魔化すためだけに・・・ */	\
		typedef _R (_CDummyBase::*CLASS_FUNC_PTR)(	\
			AGH_PP_COMMA_REPEART_INC(NUM, _CAghClassFuncPtr_FUNC_ARGS_));	\
		\
	protected:	\
		void* m_pInstance;	\
		CLASS_FUNC_PTR m_pFunc;	\
	\
	public:	\
		CAghClassFuncPtr##NUM(){}	\
		virtual ~CAghClassFuncPtr##NUM(){}	\
		\
		void Set(void* pInstance, CLASS_FUNC_PTR pFunc){	\
			m_pInstance = pInstance;	\
			m_pFunc = pFunc;	\
		}	\
		\
		_R Call(	\
			AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_FUNC_ARGS_) )	\
		{	\
			return (((_CDummyBase*)m_pInstance)->*(m_pFunc))(	\
				AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_CALL_ARGS_) ); }	\
	};

#define _CAghClassFuncPtr_0(NUM)	\
	template <typename _R \
		AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_TMPL_ARGS_)>	\
	class CAghClassFuncPtr##NUM		\
	{	\
	public:	\
		class _CDummyBase{}; /* ダミークラス（コンパイラを誤魔化すためだけに・・・ */	\
		typedef _R (_CDummyBase::*CLASS_FUNC_PTR)(	\
			AGH_PP_COMMA_REPEART_INC(NUM, _CAghClassFuncPtr_FUNC_ARGS_));	\
		\
	protected:	\
		void* m_pInstance;	\
		CLASS_FUNC_PTR m_pFunc;	\
	\
	public:	\
		CAghClassFuncPtr##NUM(){}	\
		virtual ~CAghClassFuncPtr##NUM(){}	\
		\
		void Set(void* pInstance, CLASS_FUNC_PTR pFunc){	\
			m_pInstance = pInstance;	\
			m_pFunc = pFunc;	\
		}	\
		\
		_R Call(	\
			AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_FUNC_ARGS_) )	\
		{	\
			return (((_CDummyBase*)m_pInstance)->*(m_pFunc))(	\
				AGH_PP_COMMA_REPEART_INC(NUM,_CAghClassFuncPtr_CALL_ARGS_) ); }	\
	};
	
_CAghClassFuncPtr_0(0)
//_CAghClassFuncPtr_X(1)

AGH_PP_REPEART_INC(10,_CAghClassFuncPtr_X)
//	テンプレート引数の最大は64個までみたいです。（少なくともVC++6.0の場合では）
//	ちなみにboostは50個を最大にしているみたいだね。同じにした方がいいんだろうか？

#endif//__agh_class_func_ptr_H__
