#ifndef tqueue_h
#define tqueue_h
#undef check

#include <nrnmutdec.h>
#include <pool.h>

class TQItem;
declarePool(TQItemPool, TQItem)

// 0 use bbtqueue, 1 use rbtqueue, 2 use sptqueue, 3 use sptfifoq
#define BBTQ 5

#define FAST_LEAST 1

#if BBTQ == 0
#include <bbtqueue.h>
#endif

#if BBTQ == 1
#define RBTQueue TQueue
#define RBTQItem TQItem
#include <rbtqueue.h>
#endif

#if BBTQ == 2
#define SplayTQueue TQueue
#define SplayTQItem TQItem
#include <sptqueue.h>
#endif

#if BBTQ == 3
// note: cannot use the fifo queue for parallel simulations since
// the received MPI_Allgather buffer is not properly time sorted.
#undef FAST_LEAST
// required
#define FAST_LEAST 1
#define SplayTFifoQueue TQueue
#define SplayTFifoQItem TQItem
#include <sptfifoq.h>
#endif

#if BBTQ == 4
#undef FAST_LEAST
// required
#define FAST_LEAST 1
#define Splay2TQueue TQueue
#define Splay2TQItem TQItem
#include <spt2queue.h>
#endif

#if BBTQ == 5
#undef FAST_LEAST
// required
#define FAST_LEAST 1
#define SplayTBinQueue TQueue
#define SplayTBinQItem TQItem
#include <sptbinq.h>
#endif

class SelfQueue { // not really a queue but a doubly linked list for fast
public:		  // insertion, deletion, iteration
	SelfQueue(TQItemPool*, int mkmut = 0);
	virtual ~SelfQueue();
	TQItem* insert(void*);
	void* remove(TQItem*);
	void remove_all();
	TQItem* first() { return head_; }
	TQItem* next(TQItem* q) { return q->right_; }
private:
	TQItem* head_;
	TQItemPool* tpool_;
	MUTDEC
};

#endif
