/**********************************************************************
 
	Copyright (C) 2003-2004
	Hirohisa MORI <joshua@nichibun.ac.jp>
	Tomohito Nakajima <nakajima@zeta.co.jp>
	Tomoki SEKIYAMA <sekiyama@yahoo.co.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/


#ifndef ___SERIALIZED_EXEC_H____
#define ___SERIALIZED_EXEC_H____


#include "machine/v_m.h"


// arg 0

template<typename RET, typename FUNC>
class v_serialized_exec_func_s0{
	RET &ret;
	FUNC func;
public:
	v_serialized_exec_func_s0(RET &ret, FUNC func) : 
	  ret(ret), func(func){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s0 *s){
		s->ret = s->func();
	}
	void dummy() {}
};


template<typename FUNC>
class v_serialized_exec_sub_s0{
	FUNC func;
public:
	v_serialized_exec_sub_s0(FUNC func) : 
	  func(func){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s0 *s){
		s->func();
	}
	void dummy() {}
};


template<typename FUNC>
void v_serialized_exec_sub(FUNC func){
	v_serialized_exec_sub_s0<FUNC> s(func);
	s.dummy();
}

template<typename RET>
RET v_serialized_exec_func(RET(*func)()){
	RET ret;
	v_serialized_exec_func_s0<RET,RET(*)()> s(ret, func);
	s.dummy();
	return ret;
}


// arg 1

template<typename RET, typename FUNC, typename A1>
class v_serialized_exec_func_s1{
	RET &ret;
	FUNC func;
	A1 a1;
public:
	v_serialized_exec_func_s1(RET &ret, FUNC func, A1 a1) : 
	  ret(ret), func(func), a1(a1){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s1 *s){
		s->ret = s->func(s->a1);
	}
	void dummy() {}
};


template<typename FUNC, typename A1>
class v_serialized_exec_sub_s1{
	FUNC func;
	A1 a1;
public:
	v_serialized_exec_sub_s1(FUNC func, A1 a1) : 
	  func(func), a1(a1){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s1 *s){
		s->func(s->a1);
	}
	void dummy() {}
};


template<typename FUNC, typename A1>
void v_serialized_exec_sub(FUNC func, A1 a1){
	v_serialized_exec_sub_s1<FUNC,A1> s(func,a1);
	s.dummy();
}

template<typename RET, typename A1, typename B1>
RET v_serialized_exec_func(RET(*func)(B1), A1 a1){
	RET ret;
	v_serialized_exec_func_s1<RET,RET(*)(B1),A1> s(ret, func,a1);
	s.dummy();
	return ret;
}


// arg 2

template<typename RET, typename FUNC, typename A1, typename A2>
class v_serialized_exec_func_s2{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
public:
	v_serialized_exec_func_s2(RET &ret, FUNC func, A1 a1, A2 a2) : 
	  ret(ret), func(func), a1(a1),a2(a2){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s2 *s){
		s->ret = s->func(s->a1, s->a2);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2>
class v_serialized_exec_sub_s2{
	FUNC func;
	A1 a1;
	A2 a2;
public:
	v_serialized_exec_sub_s2(FUNC func, A1 a1, A2 a2) : 
	  func(func), a1(a1),a2(a2){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s2 *s){
		s->func(s->a1, s->a2);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2){
	v_serialized_exec_sub_s2<FUNC,A1,A2> s(func,a1,a2);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename B1, typename B2>
RET v_serialized_exec_func(RET(*func)(B1,B2), A1 a1, A2 a2){
	RET ret;
	v_serialized_exec_func_s2<RET,RET(*)(B1,B2),A1,A2> s(ret, func,a1,a2);
	s.dummy();
	return ret;
}


// arg 3

template<typename RET, typename FUNC, typename A1, typename A2, typename A3>
class v_serialized_exec_func_s3{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
public:
	v_serialized_exec_func_s3(RET &ret, FUNC func, A1 a1, A2 a2, A3 a3) : 
	  ret(ret), func(func), a1(a1),a2(a2),a3(a3){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s3 *s){
		s->ret = s->func(s->a1, s->a2, s->a3);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3>
class v_serialized_exec_sub_s3{
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
public:
	v_serialized_exec_sub_s3(FUNC func, A1 a1, A2 a2, A3 a3) : 
	  func(func), a1(a1),a2(a2),a3(a3){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s3 *s){
		s->func(s->a1, s->a2, s->a3);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2, A3 a3){
	v_serialized_exec_sub_s3<FUNC,A1,A2,A3> s(func,a1,a2,a3);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename A3, typename B1, typename B2, typename B3>
RET v_serialized_exec_func(RET(*func)(B1,B2,B3), A1 a1, A2 a2, A3 a3){
	RET ret;
	v_serialized_exec_func_s3<RET,RET(*)(B1,B2,B3),A1,A2,A3> s(ret, func,a1,a2,a3);
	s.dummy();
	return ret;
}



// arg 4

template<typename RET, typename FUNC, typename A1, typename A2, typename A3, typename A4>
class v_serialized_exec_func_s4{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
public:
	v_serialized_exec_func_s4(RET &ret, FUNC func, A1 a1, A2 a2, A3 a3, A4 a4) : 
	  ret(ret), func(func), a1(a1),a2(a2),a3(a3),a4(a4){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s4 *s){
		s->ret = s->func(s->a1, s->a2, s->a3, s->a4);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4>
class v_serialized_exec_sub_s4{
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
public:
	v_serialized_exec_sub_s4(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4) : 
	  func(func), a1(a1),a2(a2),a3(a3),a4(a4){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s4 *s){
		s->func(s->a1, s->a2, s->a3, s->a4);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4){
	v_serialized_exec_sub_s4<FUNC,A1,A2,A3,A4> s(func,a1,a2,a3,a4);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename A3, typename A4, typename B1, typename B2, typename B3, typename B4>
RET v_serialized_exec_func(RET(*func)(B1,B2,B3,B4), A1 a1, A2 a2, A3 a3, A4 a4){
	RET ret;
	v_serialized_exec_func_s4<RET,RET(*)(B1,B2,B3,B4),A1,A2,A3,A4> s(ret, func,a1,a2,a3,a4);	
	s.dummy();
	return ret;
}


// arg 5

template<typename RET, typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5>
class v_serialized_exec_func_s5{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
public:
	v_serialized_exec_func_s5(RET &ret, FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : 
	  ret(ret), func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s5 *s){
		s->ret = s->func(s->a1, s->a2, s->a3, s->a4, s->a5);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5>
class v_serialized_exec_sub_s5{
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
public:
	v_serialized_exec_sub_s5(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : 
	  func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s5 *s){
		s->func(s->a1, s->a2, s->a3, s->a4, s->a5);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5){
	v_serialized_exec_sub_s5<FUNC,A1,A2,A3,A4,A5> s(func,a1,a2,a3,a4,a5);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename A3, typename A4, typename A5, typename B1, typename B2, typename B3, typename B4, typename B5>
RET v_serialized_exec_func(RET(*func)(B1,B2,B3,B4,B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5){
	RET ret;
	v_serialized_exec_func_s5<RET,RET(*)(B1,B2,B3,B4,B5),A1,A2,A3,A4,A5> s(ret, func,a1,a2,a3,a4,a5);	
	s.dummy();
	return ret;
}


// arg 6

template<typename RET, typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
class v_serialized_exec_func_s6{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
	A6 a6;
public:
	v_serialized_exec_func_s6(RET &ret, FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : 
	  ret(ret), func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5), a6(a6){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s6 *s){
		s->ret = s->func(s->a1, s->a2, s->a3, s->a4, s->a5, s->a6);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
class v_serialized_exec_sub_s6{
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
	A6 a6;
public:
	v_serialized_exec_sub_s6(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : 
	  func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5),a6(a6){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s6 *s){
		s->func(s->a1, s->a2, s->a3, s->a4, s->a5, s->a6);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6){
	v_serialized_exec_sub_s6<FUNC,A1,A2,A3,A4,A5,A6> s(func,a1,a2,a3,a4,a5,a6);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6>
RET v_serialized_exec_func(RET(*func)(B1,B2,B3,B4,B5,B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6){
	RET ret;
	v_serialized_exec_func_s6<RET,RET(*)(B1,B2,B3,B4,B5,B6),A1,A2,A3,A4,A5,A6> s(ret, func,a1,a2,a3,a4,a5,a6);
	s.dummy();
	return ret;
}




// arg 7

template<typename RET, typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
class v_serialized_exec_func_s7{
	RET &ret;
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
	A6 a6;
	A7 a7;
public:
	v_serialized_exec_func_s7(RET &ret, FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : 
	  ret(ret), func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5),a6(a6),a7(a7){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_func_s7 *s){
		s->ret = s->func(s->a1, s->a2, s->a3, s->a4, s->a5, s->a6, s->a7);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
class v_serialized_exec_sub_s7{
	FUNC func;
	A1 a1;
	A2 a2;
	A3 a3;
	A4 a4;
	A5 a5;
	A6 a6;
	A7 a7;
public:
	v_serialized_exec_sub_s7(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : 
	  func(func), a1(a1),a2(a2),a3(a3),a4(a4),a5(a5),a6(a6),a7(a7){
		V_SERIALIZED_EXEC(exec, this);
	}
	static void exec(v_serialized_exec_sub_s7 *s){
		s->func(s->a1, s->a2, s->a3, s->a4, s->a5, s->a6, s->a7);
	}
	void dummy() {}
};


template<typename FUNC, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
void v_serialized_exec_sub(FUNC func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7){
	v_serialized_exec_sub_s7<FUNC,A1,A2,A3,A4,A5,A6,A7> s(func,a1,a2,a3,a4,a5,a6,a7);
	s.dummy();
}

template<typename RET, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7>
RET v_serialized_exec_func(RET(*func)(B1,B2,B3,B4,B5,B6,B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7){
	RET ret;
	v_serialized_exec_func_s7<RET,RET(*)(B1,B2,B3,B4,B5,B6,B7),A1,A2,A3,A4,A5,A6,A7> s(ret, func,a1,a2,a3,a4,a5,a6,a7);
	s.dummy();
	return ret;
}

#endif
