// best would be a template, but this will do
class queue
{
public:
	typedef char DataElement;
	enum RetVal { Success, Underflow, Overflow };
private:
	struct Node
	{
		DataElement data;
		Node* pPrev;
	};
	Node* m_pHead;
	Node* m_pTail;

public:
	queue(){ m_pHead = m_pTail = NULL; };
	~queue(){ empty() };

	RetVal append(const DataElement &data);
	RetVal retrieve(DataElement &data);
	RetVal serve(const DataElement &data);

	RetVal empty();
	bool isempty() { return m_pHead == NULL; };
	bool isfull() { return false; }; // unlikely because on heap
}

RetVal queue::append(const DataElement &data)
{
	Node *pNew = new Node;
	if(pNew == NULL)
		return Overflow;
	pNew->data = data;
	pNew->pPrev = NULL;
	if(m_pTail != NULL)
		m_pTail->pPrev = pNew;
	m_pTail = pNew;
	if(m_pHead == NULL)		// first element?
		m_pHead = pNew;
	return Success;
}

RetVal queue::retrieve(DataElement &data)
{
	if(m_pHead == NULL)
		return Underflow;
	data = m_pHead->data;
	return Success;
}

RetVal queue::serve(DataElement &data)
{
	if(m_pHead == NULL)
		return Underflow;
	data = m_pHead->data;
	Node *pTemp = m_pHead->pPrev;
	if(m_pTail == m_pHead)	// last element?
		m_pTail = NULL;
	delete m_pHead;
	m_pHead = pTemp;
	return Success;
}

RetVal queue::empty()
{
	Node *p = m_pHead;
	while(p != NULL)
	{
		Node *p2 = p->pPrev;
		delete p;
		p = p2;
	}
	m_pHead = m_pTail = NULL;
	return Success;
}