//-----------------------------------------------------------------------------
// Coroutine trait
// Anything that implements this trait can be resumed.
// Anything that is resumed is a coroutine.
trait is_coroutine(dtype T) {
      void main(T* this);
      coroutine_handle* get_handle(T* this);
}

//-----------------------------------------------------------------------------
forall(dtype T | {coroutine_handle* T.c})
coroutine_handle* get_handle(T* this) {
	return this->c
}

//-----------------------------------------------------------------------------
struct myCoroutine {
	int bla;
	coroutine_handle c;
};

void main(myCoroutine* this) {
	sout | this->bla | endl;
}

void foo() {
	//Run the coroutine
	myCoroutine myc;
	resume(myc);
}

//-----------------------------------------------------------------------------
// Thread trait
// Alternative 1
trait is_thread(dtype T) { 
      void main(T* this);
      thread_handle* get_handle(T* this);
	thread T;
};

//-----------------------------------------------------------------------------
forall(dtype T | {thread_handle* T.t})
thread_handle* get_handle(T* this) {
	return this->t
}

//-----------------------------------------------------------------------------
thread myThread {
	int bla;
	thread_handle c;
};

void main(myThread* this) {
	sout | this->bla | endl;
}

void foo() {
	//Run the thread
	myThread myc;
}

//-----------------------------------------------------------------------------
// Thread trait
// Alternative 2
trait is_thread(dtype T) {
      void main(T* this);
      thread_handle* get_handle(T* this);
	
};

//-----------------------------------------------------------------------------
forall(dtype T | {thread_handle* T.t})
thread_handle* get_handle(T* this) {
	return this->t
}

//-----------------------------------------------------------------------------
struct myThread {
	int bla;
	thread_handle c;
};

void main(myThread* this) {
	sout | this->bla | endl;
}

void foo() {
	//Run the thread
	thread(myThread) myc;
}