/* * queue.h * * Created on: 2021Äê11ÔÂ2ÈÕ * Author: graydon */ #ifndef QUEUE_H_ #define QUEUE_H_ #include <string.h> #include <iostream> #include "typedefs.h" template <typename type> class Queue { private: u32 size; type* dataPtr; u32 wpos; u32 rpos; u32 count; public: Queue(u32 elemNum); Queue(const Queue<type>&); ~Queue(); u32 Pop(type& data); u32 Pop(type* data,type** dataptr, u32 size); u32 Push(type& data); u32 Push(type* data, u32 size); inline u32 Count() { return count; } inline u32 Space() { return size - count; } uvoid Clear(); void Destroy(); Queue<type>& operator=(const Queue<type>&); }; template<typename type> inline Queue<type>::Queue(u32 elemNum) { dataPtr = new type[elemNum]; size = elemNum; rpos = wpos = 0; count = 0; } template<typename type> inline Queue<type>::Queue(const Queue<type>&q) { dataPtr = new type[q.size]; memcpy(dataPtr, q.dataPtr, q.size * sizeof(type)); rpos = q.rpos; wpos = q.wpos; count = q.count; size = q.size; } template<typename type> inline Queue<type>::~Queue() { Destroy(); } template<typename type> inline uvoid Queue<type>::Clear() { rpos = wpos = 0; count = 0; } template<typename type> inline u32 Queue<type>::Pop(type& data) { if (count < 1) { return 0; } data = dataPtr[rpos++]; if (rpos >= size) { rpos = 0; } count -= 1; return 1; } template<typename type> inline u32 Queue<type>::Pop(type * data, type ** dataptr, u32 num) { if (count < num) { return 0; } if (rpos + num > size) { //swap u32 diff = size - rpos; memcpy(data, dataPtr + rpos, diff * sizeof(type)); memcpy(data + diff, dataPtr, (num - diff) * sizeof(type)); rpos = num - diff; if (dataptr) *dataptr = data; } else { if (dataptr) *dataptr = dataPtr + rpos; else memcpy(data, dataPtr+rpos, num*sizeof(type)); rpos += num; } count -= num; return num; } template<typename type> inline u32 Queue<type>::Push(type * data, u32 num) { if (size - count < num) { return 0; } if (wpos + num > size) { int diff = size - wpos; memcpy(dataPtr + wpos, data, diff * sizeof(type)); memcpy(dataPtr, data + diff, (num - diff) * sizeof(type)); wpos = num - diff; } else { memcpy(dataPtr + wpos, data, num * sizeof(type)); wpos += num; if (wpos >= size) { wpos = 0; } } count += num; return num; } template<typename type> inline u32 Queue<type>::Push(type& data) { if (size - count < 1) { return 0; } dataPtr[wpos++] = data; if (wpos >= size) { wpos = 0; } count += 1; return 1; } template<typename type> inline void Queue<type>::Destroy() { if (dataPtr) { delete[] dataPtr; dataPtr = 0; } } template<typename type> inline Queue<type>& Queue<type>::operator=(const Queue<type> &q) { if (&q != this) { dataPtr = new type[q.size]; memcpy(dataPtr, q.dataPtr, q.size*sizeof(type)); rpos = q.rpos; wpos = q.wpos; count = q.count; size = q.size; } return *this; } #endif /* QUEUE_H_ */