/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#ifndef POLYGRAPH__XSTD_QUEUE_H
#define POLYGRAPH__XSTD_QUEUE_H



// general purpose queue with one big limitation:
// a given item can be in no more than one queue at a time

// implements basic queue item actions and holds pointers
class QueueItem {
	public:
		QueueItem(): thePrev(0), theNext(0) {}

		QueueItem *next() const { return theNext; }
		QueueItem *prev() const { return thePrev; }
		bool isolated() const { return !theNext && !thePrev; }

		void next(QueueItem *n) { theNext = n; if (n) n->thePrev = this; }
		void prev(QueueItem *p) { thePrev = p; if (p) p->theNext = this; }
		void isolate() { theNext = thePrev = 0; }

	protected:
		QueueItem *thePrev;
		QueueItem *theNext;
};

// a queue with default FIFO interface
template <class Item>
class Queue {
	public:
		Queue(): theCount(0) { theAncor.next(&theAncor); }

		int count() const { return theCount; }
		bool empty() const { return theCount == 0; }

		inline void enqueueAfter(QueueItem *x, Item *i);
		inline Item *dequeue(Item *i);

		Item *begin() { return firstOut(); }
		Item *end() { return 0; }
		Item *next(Item *i) { return i == lastIn() ? 0 : (Item*)i->next(); }
		
		// FIFO
		Item *firstOut() { return (Item*)theAncor.next(); }
		const Item *firstOut() const { return (const Item*)theAncor.next(); }
		Item *lastIn() { return (Item*)theAncor.prev(); }
		const Item *lastIn() const { return (const Item*)theAncor.prev(); }
		void enqueue(Item *i) { enqueueAfter(lastIn(), i); }
		Item *dequeue() { return dequeue(firstOut()); }

	protected:
		QueueItem theAncor;
		int theCount;
};

/* implementaion of in-lined methods */

template <class Item>
inline
void Queue<Item>::enqueueAfter(QueueItem *x, Item *i) {
	Assert(i->isolated());
	i->next(x->next());
	x->next(i);
	theCount++;
}

template <class Item>
inline
Item *Queue<Item>::dequeue(Item *i) {
	Assert(theCount > 0);
	i->prev()->next(i->next());
	i->isolate();
	theCount--;
	return i;
}

#endif


syntax highlighted by Code2HTML, v. 0.9.1