#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Queue/FixedQueue.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVLFIXQUEUE_HEADER #define RAVLFIXQUEUE_HEADER 1 ////////////////////////////////////////////////////////////// //! file="Ravl/Core/Container/Queue/FixedQueue.hh" //! lib=RavlCore //! userlevel=Normal //! author="Charles Galambos" //! date="6/6/97" //! docentry="Ravl.Core.Queues" //! rcsid="$Id: FixedQueue.hh,v 1.3 2001/10/15 14:47:41 craftit Exp $" #include "Ravl/SArray1d.hh" #include "Ravl/Assert.hh" namespace RavlN { //! userlevel=Normal //: Fixed size circular queue. // A SMALL object. // This is sometimes known as a ring buffer. // FIXME :- Make FixedQueueC big.

// FIXME :- Speed up, use ptr's!.

// Note, this does not destroy items removed from // the queue until the element is overwritten by another. template class FixedQueueC : public SArray1dC { public: inline FixedQueueC(SizeT Size); //: Constructor. inline bool IsSpace(); //: Is space to data into ring ? inline void InsLast(const T &Obj); //: Insert data at end of queue. // returns the place its index in the array. inline void ForceInsLast(const T &Obj); //: Insert data at end of queue, if no space discard oldest element. // returns the place its index in the array. inline bool IsEmpty() const { return head == tail; } //: Is ring empty ? inline T GetFirst(); //: Get first item from queue. inline const T &First() const { RavlAssert(!IsEmpty()); return *tail; } //: Access first the first element in the queue. inline T &First() { RavlAssert(!IsEmpty()); return *tail; } //: Access first the first element in the queue. inline T &Last() { RavlAssert(!IsEmpty()); return *head; } //: Look at the item most recently placed in the queue. inline const T &Last() const { RavlAssert(!IsEmpty()); return *head; } //: Look at the item most recently placed in the queue. inline void DelFirst(); //: Delete thing in buffer inline SizeT Size() const; //: No of items in the ring. inline SizeT MaxSize() const { return SArray1dC::Size(); } //: Get maximum size of queue. inline bool IsInRing(UIntT P) const; //: Is P an index in the ring. inline void Empty(); //: Empty the queue of all contents. // Reset to head=0, tail=0 protected: T *head; // Next free location. T *tail; // Last used location. T *eoa; // Ptr to end of array. }; //! userlevel=Normal //: Iterate through contents of the queue. template class FixedQueueIterC : public SArray1dC { public: FixedQueueIterC() : at(0), end(0) {} //: Default constructor. FixedQueueIterC(FixedQueueC &queue) : SArray1dC(queue) { First(queue); } //: Constructor from a queue. // Note: Chaning the queue after the iterator is contructed // will not affect the indexs iterated, though the data will // change. void First(FixedQueueC &queue) { SArray1dC::operator=(queue); at = &queue.First(); end = &queue.Last(); eoa = (&(*this)[queue.MaxSize()-1])+1; } //: Goto first element in queue. const FixedQueueIterC &operator=(FixedQueueC &queue) { First(queue); return *this; } //: Assign to a queue. bool IsElm() const { return at != end; } //: At valid element ? operator bool() const { return at != end; } //: At a valid element ? void Next() { at++; if(at == eoa) at = &(*this)[0]; } //: Goto next element. void operator++(int) { Next(); } //: Goto next element. void operator++() { Next(); } //: Goto next element. T &Data() { return *at; } //: Access data. const T &Data() const { return *at; } //: Access data. T &operator*() { return *at; } //: Access data. const T &operator*() const { return *at; } //: Access data. T *operator->() { return at; } //: Access data. const T *operator->() const { return at; } //: Access data. protected: T *at; T *end; T *eoa; }; //----------------------------------------------------- template inline FixedQueueC::FixedQueueC(SizeT Size) : SArray1dC(Size+1) // Cause we always need space for 1 more item. { head = &((*this)[0]); tail = head; eoa = &(head[MaxSize()]); } template inline bool FixedQueueC::IsSpace() { T *nhead = head + 1; if(nhead >= eoa) nhead = &(*this)[0]; return (nhead != tail); } template inline void FixedQueueC::InsLast(const T &Obj) { RavlAssert(IsSpace()); *(head++) = Obj; if(head >= eoa) head = &(*this)[0]; } template inline void FixedQueueC::ForceInsLast(const T &Obj) { *(head++) = Obj; if(head >= eoa) head = &((*this)[0]); if(head == tail) { // Need to push tail ? if(++tail >= eoa) tail = &((*this)[0]); } } template inline T FixedQueueC::GetFirst() { RavlAssert(!IsEmpty()); T Ret = *(tail++); if(tail >= eoa) tail = &((*this)[0]); return Ret; } template inline void FixedQueueC::DelFirst() { RavlAssert(!IsEmpty()); if(++tail >= eoa) tail = &((*this)[0]); } template inline SizeT FixedQueueC::Size() const { if(head >= tail) return (SizeT) (head - tail); return (SizeT) ((eoa - tail) + (head - &((*this)[0]))); } template inline bool FixedQueueC::IsInRing(UIntT at) const { if(IsEmpty()) return false; const T *p = &((*this)[at]); if(head > tail) return (p >= tail && p < head); return (p >= tail || p < head); } template inline void FixedQueueC::Empty() { tail = &((*this)[0]); head = tail; } } #endif