#ifndef __CPP_QUEUE_H
#define __CPP_QUEUE_H
#ifdef __cplusplus
#include <ubixos/types.h>
#include <lib/Pair.h>
#include <lib/Alloc.h>
template <class T> class Queue
{
public:
class Pair<int, T>;
Queue();
~Queue();
void insert(const int, const T &);
void insert(Pair<int,T> & a) { insert(a.first(), a.second()); };
const Pair<int,T> find(const int) const;
const T remove(const int);
const T remove();
const T top();
const Pair<int,T> pop();
void empty();
int size();
private:
class Node
{
public:
Node() : index(-1), prev(NULL), next(NULL), data() {};
int index;
Node * prev;
Node * next;
T data;
};
Node * first;
Node * last;
int sz;
Alloc allocator;
};
template <class T> Queue<T>::Queue() : first(NULL), last(NULL), sz(0)
{ allocator.setSize(sizeof(Node)); };
template <class T> Queue<T>::~Queue() { while(first != NULL) this->pop(); };
template <class T>
void Queue<T>::insert(const int a, const T & b)
{
Node * temp = (Node *) allocator.allocate();
temp->index = a;
temp->data = b;
temp->next = first;
if (NULL == last)
this->last = temp;
else
this->first->prev = temp;
this->first = temp;
sz++;
}
template <class T>
const Pair<int,T> Queue<T>::find(const int a) const {
T item = T();
bool found = false;
Node * temp = first;
while ((NULL != temp) && !found)
{
if (a == temp->index)
{
item = temp->data;
found = true;
}
temp = temp->next;
}
if (found)
return Pair<int,T>(a,item);
else
return Pair<int,T>(-1,item);
}
template <class T>
const T Queue<T>::remove(const int a) {
T item = T();
bool found = false;
Node * temp = first;
while ((NULL != temp) && !found)
{
if (a == temp->index)
{
item = temp->data;
found = true;
if (NULL != temp->prev)
temp->prev->next = temp->next;
if (NULL != temp->next)
temp->next->prev = temp->prev;
if (temp == first)
first = temp->next;
if (temp == last)
last = temp->prev;
allocator.deallocate(temp);
temp = NULL;
sz--;
}
temp = temp->next;
}
return item;
}
template <class T>
const T Queue<T>::remove()
{
T item = T();
Node * temp;
if (NULL != last)
{
item = last->data;
if (NULL != last->prev)
{
last->prev->next = NULL;
temp = last;
last = last->prev;
delete temp;
}
else
{
temp = last;
first = last = NULL;
delete temp;
}
sz--;
}
return item;
}
template <class T>
const T Queue<T>::top()
{
T item = T();
if (NULL != last)
{
item = last->data;
}
return item;
}
template <class T>
const Pair<int,T> Queue<T>::pop()
{
T item = T();
int index;
bool found = false;
Node * temp;
if (NULL != first)
{
item = first->data;
index = first->index;
found = true;
if (NULL != first->next)
{
temp = first;
first = first->next;
first->prev = NULL;
delete temp;
}
else
{
temp = last;
first = last = NULL;
delete temp;
}
sz--;
}
if (found)
return Pair<int, T>(index, item);
else
return Pair<int, T>(-1, item);
}
template <class T>
void Queue<T>::empty() { while (last != NULL) pop(); }
template <class T>
int Queue<T>::size() { return sz; }
#endif
#endif // __QUEUE_H