#ifndef CO
#define CO

/*

	coroutine
	finite state machine
	actor model
	high level abstract for GOTO
	static memory allocation

*/

template <class ... DP>
class Co
{
	public:
		virtual Co<DP...>* Routine(DP ... dp)
		{
			return 0;
		}
};

/*
template <class ... DP>
class Coroutines : public Co<DP...>
{

	private:
		Co<DP...>** Routines;
	protected:
		void Run(DP ... dp)
		{
			for (int i=0; this->Routines[i]; i++)
			{
				Co<DP...> * co = this->Routines[i];
				while(co)
				{
					co = co->Routine(dp...);
				}
			}
		}
	public:
		Coroutines(Co<DP...>** routines)
		{
			this->Routines = routines;
		}

		Co<DP...>* Routine(DP ... dp)
		{
			this->Run(dp...);
			return this;
		}
};
*/

template <class ... DP>
class Cos : public Co<DP...>
{
	private:
		Co<DP...>** Ntinuations;
		int sum;
	protected:
		void Continue(DP ... dp)
		{
			for (int i=0; i<this->sum; i++)
			if (this->Ntinuations[i])
			{
				this->Ntinuations[i] = this->Ntinuations[i]->Routine(dp...);
			}

		}
	public:
		Cos(Co<DP...>** ntinuations)
		{
			this->Ntinuations = ntinuations;
			for (this->sum=0; this->Ntinuations[this->sum]; this->sum++){}
		}

		Co<DP...>* Routine(DP ... dp)
		{
			this->Continue(dp...);
			return this;
		}
};


template <typename TP>
static TP* Singleton()
{
	static TP singleton;
	return &singleton;
}

#endif
