#ifndef XPRIORITYQUEUE_H #define XPRIORITYQUEUE_H template struct XPriority { int operator()(const T& iT) const { return iT; } }; /************************************************ Name: XPriorityQueue Summary: Class representation of a priority queue. Template Parameters: T : type of object to store into the queue PF : priority function, which is use to tell the priority (an int) of a T object. Remarks: This container is used to fastly pop an object, sorted by a criterion, called here the priority of the object. Insertion and Pop are in O(log(n)) and the objects are stored flat, in an array, avoiding many small allocations. You can not store objects with ctor and dtor in it because they won't be called. See Also : XArray, XList ************************************************/ template > class XPriorityQueue { public: /************************************************ Summary: Constructors. Input Arguments: iBaseNumber: Default number of reserved elements. ************************************************/ XPriorityQueue(int iBaseNumber = 0):m_Cells(iBaseNumber) {} /************************************************ Summary: Removes all the elements from the queue. Remarks: The memory allocated is not freed by this call. ************************************************/ void Clear() { if (m_Cells.Size()) { // already allocated : sets to the beginning m_Cells.Resize(1); } } void Insert(const T& iT) { if (!m_Cells.Size()) { // first insertion : init m_Cells.Reserve(2); m_Cells.Resize(1); // the first node is the root } int i = m_Cells.Size(); m_Cells.PushBack(iT); T* cells = m_Cells.Begin(); PF prio; int insertPrio = prio(iT); while (i > 1 && prio(cells[i / 2]) < insertPrio) { cells[i] = cells[i / 2]; i /= 2; } cells[i] = iT; } /************************************************ Summary: Removes the higher priority element of the queue. Input Arguments: oT: pointer to the T object that will be filled with the higher priority element. The pointer need to be valid. Return Value: TRUE if an object is popped. ************************************************/ XBOOL Pop(T* oT) { if (m_Cells.Size() <= 1) return 0; { T* cells = m_Cells.Begin(); *oT = cells[1]; } T tmp = m_Cells.PopBack(); int size = m_Cells.Size(); if (size == 1) // was the last one return 1; int i = 1; int j; PF prio; int lastPriority = prio(tmp); T* cells = m_Cells.Begin(); while (i <= size / 2) { j = 2 * i; if (j < size && prio(cells[j]) < prio(cells[j + 1])) { j++; } if (prio(cells[j]) <= lastPriority) { break; } cells[i] = cells[j]; i = j; } cells[i] = tmp; return 1; } /************************************************ Summary: Peeks the higher priority element of the queue. Input Arguments: oT: pointer to the T object that will be filled with the higher priority element. The pointer need to be valid. Return Value: TRUE if an object is popped. ************************************************/ XBOOL Peek(T* oT) const { if (m_Cells.Size() <= 1) return 0; T* cells = m_Cells.Begin(); *oT = cells[1]; return 1; } /************************************************ Summary: Returns the occupied size in memory in bytes Parameters: addstatic: TRUE if you want to add the size occupied by the class itself. ************************************************/ int GetMemoryOccupation(XBOOL iAddStatic = FALSE) const { return m_Cells.GetMemoryOccupation(iAddStatic); } protected: // array of queue cells XArray m_Cells; }; #endif