#include <iostream>
#include <cstdlib>
#include <list>
#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_do.h"

#define N 10

using namespace tbb;
using namespace std;

int X = 7;

struct Node {
	int data;
	bool die;	// to free node after processing to avoid memory leaks
	Node *next;

	Node()
	{
		next = NULL;
		die = false;
	}

	typedef Node *argument_type;

	void operator()( argument_type tmp_node, parallel_do_feeder<argument_type> &append_task ) const
	{
		if ( tmp_node->data == X ) {
			printf("   -> %p %5d\n", (void *) tmp_node, tmp_node->data);
		} else {
			printf("	. %p %5d\n", (void *) tmp_node, tmp_node->data);
		}

		if ( tmp_node->data % 5 == 0 ) {
			int t;
			t = tmp_node->data;

			Node *nx = new Node;
			nx->data = t + 216;
			nx->die = true;

			append_task.add( nx );

			printf("	+ %p %5d appends %d\n", (void *) tmp_node, t, t+216);
		}

		if ( tmp_node->die ) {
			printf("	x %p %5d is no more ...\n", (void *) tmp_node, tmp_node->data);
			delete tmp_node;
		}

	}
};

int main()
{
	list<Node *> l;

	for (unsigned int i=0; i<N; i++) {
		Node *node_x;

		node_x = new Node;
		node_x->data = i;

		l.push_back(node_x);

		if ( i == (unsigned) X ) {
			cout << node_x << " " << i << endl;
		}
	}
	cout << endl;

	task_scheduler_init init(4);

	X=8;
	cout << "Searching for " << X << endl;
	parallel_do(l.begin(), l.end(), Node());
	cout << endl;

	X=1;
	cout << "Searching for " << X << endl;
	parallel_do(l.begin(), l.end(), Node());

	return 0;
}

