#ifndef __myu_class_func_ptr_H__
#define __myu_class_func_ptr_H__

#include "msl_pp.h"

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

#define _CMyuClassFuncPtr_TMPL_ARGS_(X)		typename _ARG ##X
#define _CMyuClassFuncPtr_FUNC_ARGS_(X)		_ARG ##X  arg ##X
#define _CMyuClassFuncPtr_CALL_ARGS_(X)		arg ##X

//		public CMyuClassFuncPtrBase<_R ()(
//			MSL_PP_COMMA_REPEART_INC(NUM,_CMyuClassFuncPtr_FUNC_ARGS_))>

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

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

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

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

#endif//__myu_class_func_ptr_H__
