Files
pvData/pvDataApp/misc/queue.h
2013-05-16 09:04:42 -04:00

132 lines
2.9 KiB
C++

/* queue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <vector>
#include <cstddef>
#include <stdexcept>
#include <pv/sharedPtr.h>
#ifndef QUEUE_H
#define QUEUE_H
namespace epics { namespace pvData {
template <typename T>
class Queue
{
public:
POINTER_DEFINITIONS(Queue);
typedef std::tr1::shared_ptr<T> queueElementPtr;
typedef std::vector<queueElementPtr> queueElementPtrArray;
Queue(queueElementPtrArray &);
virtual ~Queue();
void clear();
int capacity();
int getNumberFree();
int getNumberUsed();
queueElementPtr & getFree();
void setUsed(queueElementPtr const &element);
queueElementPtr & getUsed();
void releaseUsed(queueElementPtr const &element);
private:
queueElementPtr nullElement;
queueElementPtrArray elements;
int size;
int numberFree;
int numberUsed;
int nextGetFree;
int nextSetUsed;
int nextGetUsed;
int nextReleaseUsed;
};
template <typename T>
Queue<T>::Queue(std::vector<queueElementPtr> &xxx)
: size(xxx.size()),
numberFree(size),
numberUsed(0),
nextGetFree(0),
nextSetUsed(0),
nextGetUsed(0),
nextReleaseUsed(0)
{
elements.swap(xxx);
}
template <typename T>
Queue<T>::~Queue(){}
template <typename T>
int Queue<T>::capacity(){return size;}
template <typename T>
int Queue<T>::getNumberFree(){return numberFree;}
template <typename T>
int Queue<T>::getNumberUsed(){return numberUsed;}
template <typename T>
void Queue<T>::clear()
{
numberFree = size;
numberUsed = 0;
nextGetFree = 0;
nextSetUsed = 0;
nextGetUsed = 0;
nextReleaseUsed = 0;
}
template <typename T>
std::tr1::shared_ptr<T> & Queue<T>::getFree()
{
if(numberFree==0) return nullElement;
numberFree--;
int ind = nextGetFree;
std::tr1::shared_ptr<T> queueElement = elements[nextGetFree++];
if(nextGetFree>=size) nextGetFree = 0;
return elements[ind];
}
template <typename T>
void Queue<T>::setUsed(std::tr1::shared_ptr<T> const &element)
{
if(element!=elements[nextSetUsed++]) {
throw std::logic_error("not correct queueElement");
}
numberUsed++;
if(nextSetUsed>=size) nextSetUsed = 0;
}
template <typename T>
std::tr1::shared_ptr<T> & Queue<T>::getUsed()
{
if(numberUsed==0) return nullElement;
int ind = nextGetUsed;
std::tr1::shared_ptr<T> queueElement = elements[nextGetUsed++];
if(nextGetUsed>=size) nextGetUsed = 0;
return elements[ind];
}
template <typename T>
void Queue<T>::releaseUsed(std::tr1::shared_ptr<T> const &element)
{
if(element!=elements[nextReleaseUsed++]) {
throw std::logic_error(
"not queueElement returned by last call to getUsed");
}
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
numberUsed--;
numberFree++;
}
}}
#endif /* QUEUE_H */