//	Roast+ License

//	関数オブジェクト

#ifndef __SFJP_OPENMGL_roast_function_HPP__
#define __SFJP_OPENMGL_roast_function_HPP__

#include "roast_pp.h"
//#include "roast/std/myu_class_func_ptr.h"


//#define _ROAST_FUNCTION__TEMPLATE_ARGS__CALLBACK(N)		typename T ## N

#define _ROAST_FUNCTION__TMPL_ARGS_(X)		typename _ARG ##X
#define _ROAST_FUNCTION__FUNC_ARGS_(X)		_ARG ##X  arg ##X
#define _ROAST_FUNCTION__CALL_ARGS_(X)		arg ##X

//		public functionBase<_R ()(
//			ROAST_PP_COMMA_REPEART_INC(NUM,_ROAST_FUNCTION__FUNC_ARGS_))>

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

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

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

namespace roast{
/*
	class function ## N < typename RET_T, 
		ROAST_PP_COMMA_REPEART_INC(N, _ROAST_FUNCTION__TEMPLATE_ARGS__CALLBACK) >
	{
	
	};
*/

	_ROAST_FUNCTION__0(0)
	//_ROAST_FUNCTION__X(1)

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

}


#endif//__SFJP_OPENMGL_roast_function_HPP__
