#pragma once
+#include "debug.h"
+#include "mathw.h"
+
// HACK
#ifndef NULL
#define NULL 0
Queue();
~Queue() {}
- void init(int iStartSize = 2, int iSizeMultiplier = 2);
+ void init(unsigned int uiStartSize = 2, unsigned int uiSizeMultiplier = 2);
void fini();
- void alloc(int iSize);
+ void alloc(unsigned int uiSize);
void trim();
bool isEmpty() const;
- Item& getFront();
- Item& getBack();
+ const Item& getFront() const;
+ const Item& getBack() const;
void pushFront(const Item& i);
- void popBack(const Item& i);
+ void pushBack(const Item& i);
private:
- int m_iStartSize;
- int m_iSizeMultiplier;
+ unsigned int getLength() const;
+ unsigned int getSpaceNeeded(unsigned int uiSize) const;
+
+ unsigned int m_uiStartSize;
+ unsigned int m_uiSizeMultiplier;
- int m_iAllocated;
- Item* m_pArrayItems;
+ unsigned int m_uiAllocated;
+ Item* m_pArrayItems;
+ bool m_fIsEmpty;
- int m_iHead;
- int m_iTail;
+ unsigned int m_uiHead;
+ unsigned int m_uiTail;
};
} // namespace bear
template < class Item >
bear::Queue<Item>::Queue()
- : m_iStartSize(0),
- m_iSizeMultiplier(0),
- m_iAllocated(0),
+ : m_uiStartSize(0),
+ m_uiSizeMultiplier(0),
+ m_uiAllocated(0),
m_pArrayItems(NULL),
- m_iHead(0),
- m_iTail(0)
+ m_fIsEmpty(0),
+ m_uiHead(0),
+ m_uiTail(0)
{
}
template < class Item >
void bear::Queue<Item>::init
(
- int iStartSize,
- int iSizeMultiplier
+ unsigned int uiStartSize,
+ unsigned int uiSizeMultiplier
)
{
- m_iStartSize = iStartSize;
- m_iSizeMultiplier = iSizeMultiplier;
+ m_uiStartSize = uiStartSize;
+ m_uiSizeMultiplier = uiSizeMultiplier;
+
+ m_uiAllocated = 0;
+
+ bear::DASSERT(NULL == m_pArrayItems); // this better be the case
+ m_pArrayItems = NULL;
+
+ m_fIsEmpty = true;
+
+ m_uiHead = 0;
+ m_uiTail = 0;
}
template < class Item >
void bear::Queue<Item>::fini()
{
+ m_uiStartSize = 0;
+ m_uiSizeMultiplier = 0;
+ m_uiAllocated = 0;
+
+ delete m_pArrayItems;
+ m_pArrayItems = NULL;
+
+ m_fIsEmpty = true;
+
+ m_uiHead = 0;
+ m_uiTail = 0;
}
template < class Item >
-void bear::Queue<Item>::alloc(int iSize)
+void bear::Queue<Item>::alloc(unsigned int uiSize)
{
+ if(m_uiAllocated < uiSize)
+ {
+ unsigned int uiOldLength = getLength();
+
+ unsigned int uiOldAllocated = m_uiAllocated;
+ Item* pOldArrayItems = m_pArrayItems;
+ unsigned int uiOldHead = m_uiHead;
+ unsigned int uiOldTail = m_uiTail;
+
+ m_uiAllocated = 0;
+ m_pArrayItems = NULL;
+ m_uiHead = -1;
+ m_uiTail = -1;
+
+ unsigned int uiNewAllocated = uiSize;
+ Item* pNewArrayItems = new Item[uiNewAllocated];
+ unsigned int uiNewHead = 0;
+ unsigned int uiNewTail = uiOldLength - 1;
+
+ for(unsigned int uiNewIndex = uiNewHead; uiNewIndex <= uiNewTail; uiNewIndex++)
+ {
+ unsigned int iOldIndex = mod(uiNewIndex + uiOldHead, uiOldAllocated);
+ bear::DASSERT(iOldIndex <= uiOldTail);
+
+ pNewArrayItems[uiNewIndex] = pOldArrayItems[iOldIndex];
+ }
+
+ m_uiAllocated = uiNewAllocated;
+ m_pArrayItems = pNewArrayItems;
+ m_uiHead = uiNewHead;
+ m_uiTail = uiNewTail;
+ }
+ // TODO: return error code
}
template < class Item >
void bear::Queue<Item>::trim()
template < class Item >
bool bear::Queue<Item>::isEmpty() const
{
- return false;
+ return m_fIsEmpty;
}
template < class Item >
-Item& bear::Queue<Item>::getFront()
+const Item& bear::Queue<Item>::getFront() const
{
+ // This is very bad. Fix your code
+ DASSERT(!isEmpty());
+ return m_pArrayItems[m_uiHead];
}
template < class Item >
-Item& bear::Queue<Item>::getBack()
+const Item& bear::Queue<Item>::getBack() const
{
+ // This is very bad. Fix your code
+ DASSERT(!isEmpty());
+ return m_pArrayItems[m_uiTail];
}
template < class Item >
void bear::Queue<Item>::pushFront(const Item& i)
{
+ // Make sure we have the space to add an item
+ alloc( getSpaceNeeded( getLength() + 1 ) );
+ m_uiHead = mod( m_uiHead + 1, m_uiAllocated );
+
+ m_pArrayItems[m_uiHead] = i;
}
template < class Item >
-void bear::Queue<Item>::popBack(const Item& i)
+void bear::Queue<Item>::pushBack(const Item& i)
{
+ // Make sure we have the space to add an item
+ alloc( getSpaceNeeded( getLength() + 1 ) );
+
+ m_uiTail = mod( m_uiTail + 1, m_uiAllocated );
+
+ m_pArrayItems[m_uiTail] = i;
+}
+
+template < class Item >
+unsigned int bear::Queue<Item>::getLength() const
+{
+ if ( isEmpty() )
+ {
+ return 0;
+ }
+ else
+ {
+ return mod( m_uiTail - m_uiHead, m_uiAllocated ) + 1;
+ }
}
+template < class Item >
+unsigned int bear::Queue<Item>::getSpaceNeeded(unsigned int uiSize) const
+{
+ unsigned int uiNewSize = m_uiAllocated;
+
+ while ( uiNewSize < uiSize )
+ {
+ uiNewSize *= m_uiSizeMultiplier;
+ }
+
+ return uiNewSize;
+}