#ifndef	__PY_TINKER_CONSTRUCT__
#define	__PY_TINKER_CONSTRUCT__

#include "__py_tinker_common.h"
#include "__py_tinker_func.h"

namespace py_tinker {

inline
void default_del_inst(void* ptr)
{delete ptr;}

template<typename CLS>
struct SDefaultConstruct0 : IFunction
{
	SDefaultConstruct0()			{}
	virtual ~SDefaultConstruct0()	{}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)new CLS, default_del_inst);)}
};

template<typename CLS, typename ARG>
struct SDefaultConstruct1 : IFunction
{
	SDefaultConstruct1()			{}
	virtual ~SDefaultConstruct1()	{}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)new CLS(arg_<ARG>(args, 0)), default_del_inst);)}
};

template<typename CLS, typename ARG, typename ARG2>
struct SDefaultConstruct2 : IFunction
{
	SDefaultConstruct2()	{}
	virtual ~SDefaultConstruct2() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)new CLS(arg_<ARG>(args, 0), arg_<ARG2>(args, 1)), default_del_inst);)}
};

template<typename CLS, typename ARG, typename ARG2, typename ARG3>
struct SDefaultConstruct3 : IFunction
{
	SDefaultConstruct3()			{}
	virtual ~SDefaultConstruct3()	{}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)new CLS(arg_<ARG>(args, 0), arg_<ARG2>(args, 1), arg_<ARG3>(args, 2)), default_del_inst);)}
};

template<typename CLS, typename ARG, typename ARG2, typename ARG3, typename ARG4>
struct SDefaultConstruct4 : IFunction
{
	SDefaultConstruct4()	{}
	virtual ~SDefaultConstruct4()								{}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)new CLS(arg_<ARG>(args, 0), arg_<ARG2>(args, 1), arg_<ARG3>(args, 2), arg_<ARG4>(args, 3)), default_del_inst);)}
}; 

template<typename CLS>
struct SCustomConstruct0 : IFunction
{
	typedef CLS* (*NEW_INST)();
	typedef void (*DEL_INST)(void*);

	SCustomConstruct0(NEW_INST new_inst, DEL_INST del_inst) : m_new_inst(new_inst), m_del_inst(del_inst)	{}
	virtual ~SCustomConstruct0() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)m_new_inst(), m_del_inst);)}

	NEW_INST m_new_inst;
	DEL_INST m_del_inst;
};

template<typename CLS, typename ARG>
struct SCustomConstruct1 : IFunction
{
	typedef CLS* (*NEW_INST)(ARG arg);
	typedef void (*DEL_INST)(void*);

	SCustomConstruct1(NEW_INST new_inst, DEL_INST del_inst) : m_new_inst(new_inst), m_del_inst(del_inst) {}
	virtual ~SCustomConstruct1() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)m_new_inst(arg_<ARG>(args, 0)), m_del_inst);)}

	NEW_INST m_new_inst;
	DEL_INST m_del_inst;
};

template<typename CLS, typename ARG, typename ARG2>
struct SCustomConstruct2 : IFunction
{
	typedef CLS* (*NEW_INST)(ARG arg, ARG2 arg2);
	typedef void (*DEL_INST)(void*);

	SCustomConstruct2(NEW_INST new_inst, DEL_INST del_inst) : m_new_inst(new_inst), m_del_inst(del_inst) {}
	virtual ~SCustomConstruct2() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)m_new_inst(arg_<ARG>(args, 0), arg_<ARG2>(args, 1)), m_del_inst);)}

	NEW_INST m_new_inst;
	DEL_INST m_del_inst;

};

template<typename CLS, typename ARG, typename ARG2, typename ARG3>
struct SCustomConstruct3 : IFunction
{
	typedef CLS* (*NEW_INST)(ARG arg, ARG2 arg2, ARG3 arg3);
	typedef void (*DEL_INST)(void*);

	SCustomConstruct3(NEW_INST new_inst, DEL_INST del_inst) : m_new_inst(new_inst), m_del_inst(del_inst) {}
	virtual ~SCustomConstruct3() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)m_new_inst(arg_<ARG>(args, 0), arg_<ARG2>(args, 1), arg_<ARG3>(args, 2)), m_del_inst);)}

	NEW_INST m_new_inst;
	DEL_INST m_del_inst;

};

template<typename CLS, typename ARG, typename ARG2, typename ARG3, typename ARG4>
struct SCustomConstruct4 : IFunction
{
	typedef CLS* (*NEW_INST)(ARG arg, ARG2 arg2, ARG3 arg3, ARG4 arg4);
	typedef void (*DEL_INST)(void*);

	SCustomConstruct4(NEW_INST new_inst, DEL_INST del_inst) : m_new_inst(new_inst), m_del_inst(del_inst) {}
	virtual ~SCustomConstruct4() {}

	PyObject* operator()(PyObject* self, PyObject* args)
	{PYTINKER_CALL(return PyCObject_FromVoidPtr((void*)m_new_inst(arg_<ARG>(args, 0), arg_<ARG2>(args, 1), arg_<ARG3>(args, 2), arg_<ARG4>(args, 3)), m_del_inst);)}

	NEW_INST m_new_inst;
	DEL_INST m_del_inst;

}; 

} // py_tinker
#endif
