/* Copyright (C) 2004 Michael Nelson Moran This file is part of OSCL. OSCL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. OSCL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OSCL; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To negotiate other licensing arrangments/agreements contact the copyright holder: Michael N. Moran 5009 Old Field Ct. mike@mnmoran.org Kennesaw, GA, USA 30144 http://mnmoran.org */ #ifndef _oscl_queue_queueh_ #define _oscl_queue_queueh_ #include "queueitem.h" /** */ namespace Oscl { /** This template class implements a singly linked list which maintains a FIFO ordering. */ template class Queue { private: /** Points to the first QueueItem in the list. */ qType* _head; /** Points to the last QueueItem in the list. */ qType* _tail; private: /** This copy constructor is intentionally NOT implemented. This would create two list heads with pointers to the same elements. In such a case, one list would be inconsistent if the content of one were changed. */ explicit Queue(const Queue&) throw(); public: /** Public constructor initializes head and tail pointers. */ Queue() throw(); /** Specialized copy constructor that moves "other" queue contents to this queue. The "other" queue is left empty. */ Queue(Queue& other) throw(); /** This assignment operator moves the contents of the other queue into this queue. The other queue is emptied after the operation. */ Queue& operator=(Queue& other) throw(); /** Remove next element from queue and return a pointer to it as a result. qType must be a subclass of QueueItem. */ qType* get(void) throw(); /** Remove last element from queue and return a pointer to it as a result. qType must be a subclass of QueueItem. */ qType* getLast(void) throw(); /** Remove next element from beginning of the queue and return a pointer to it as a result. This operation does the same thing as the get() operation, but clarifies the use of the queue as a stack in combination with the push() operation. qType must be a subclass of QueueItem. */ qType* pop(void) throw(); /** Thread into the linked list at the end of the FIFO queue. qType is a subclass of QueueItem. */ void put(qType* item) throw(); /** Thread into the linked list at the beginning of the FIFO queue. qType is a subclass of QueueItem. */ void push(qType* item) throw(); /** Remove specified qType element from the queue. qType must be a subclass of QueueItem. Returns zero if the item is not found in the queue. Otherwise it returns item. */ qType* remove(qType* item) throw(); /** Insert the "item" qType into the queue behind the "after" qType element. qType must be a subclass of QueueItem. */ void insertAfter(qType* after,qType* item) throw(); /** Insert the "item" qType into the queue ahead of the "before" qType element. qType must be a subclass of QueueItem. */ void insertBefore(qType* before,qType* item) throw(); /** Return a pointer to the first qType item in the queue. The returned item remains in the queue. qType is a subclass of QueueItem. */ qType* first(void) const throw(); /** Return a pointer to the last qType item in the queue. The returned item remains in the queue. qType is a subclass of QueueItem. */ qType* last(void) const throw(); /** Return a pointer to the qType item after the qType item "prev". Both items remain in the queue. qType is a subclass of QueueItem. */ qType* next(qType* prev) const throw(); }; template Queue::Queue(void) throw():_head(0),_tail(0){ } template Queue::Queue(Queue& other) throw(){ _head = other._head; _tail = other._tail; other._head = 0; other._tail = 0; } template Queue& Queue::operator=(Queue& other) throw(){ _head = other._head; _tail = other._tail; other._head = 0; other._tail = 0; return *this; } template inline qType* Queue::get(void) throw(){ qType* next; if((next = _head)){ _head = (qType*)next->__qitemlink; } return(next); } template inline qType* Queue::getLast(void) throw(){ qType* lastInQ; lastInQ = last(); if(!lastInQ) return 0; return remove(lastInQ); } template inline qType* Queue::pop(void) throw(){ return get(); } template inline void Queue::put(qType* item) throw(){ if(_head){ _tail->__qitemlink = item; } else{ _head = item; } _tail = item; item->__qitemlink = 0; } template inline void Queue::push(qType* item) throw(){ if(_head){ item->__qitemlink = _head; _head = item; } else{ _head = _tail = item; item->__qitemlink = 0; } } template inline qType* Queue::remove(qType* item) throw(){ qType* nxt; qType* prv; for(nxt=first(),prv=0;nxt;prv=nxt,nxt=next(nxt)){ if(nxt == item){ if(prv){ if(!(prv->__qitemlink=nxt->__qitemlink)){ _tail = prv; } } else{ if(!(_head=(qType*)nxt->__qitemlink)){ _tail = 0; } } return item; } } return 0; } template inline void Queue::insertAfter(qType* prev,qType* item) throw(){ item->__qitemlink = prev->__qitemlink; prev->__qitemlink = item; } template inline void Queue::insertBefore(qType* before,qType* item) throw(){ qType* nxt; qType* prv; for(nxt=first(),prv=0;nxt;prv=nxt,nxt=next(nxt)){ if(nxt == before){ item->__qitemlink = nxt; if(prv){ prv->__qitemlink =item; } else{ _head = item; } break; } } } template inline qType* Queue::first(void) const throw(){ return(_head); } template inline qType* Queue::last(void) const throw(){ if(_head){ return _tail; } return 0; } template inline qType* Queue::next(qType* prev) const throw(){ return((qType*)prev->__qitemlink); } }; #endif