/*
|
* 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_ */
|