00001 #ifndef CIRCULARQUEUE_H_
00002 #define CIRCULARQUEUE_H_
00003
00004 #include <iostream>
00005
00006 using std::cerr;
00007 using std::endl;
00008
00009 #include <cstdlib>
00010
00011 #include <algorithm>
00012
00013 using std::fill;
00014
00016
00022 template <class T>
00023 class CircularQueue
00024 {
00025
00026 public:
00028
00031 CircularQueue(size_t size, T v);
00032
00033 virtual ~CircularQueue();
00034
00036
00039 T &get(int position = 0) const;
00040
00041
00043
00049 void put(const T &elem);
00050
00051
00053 void moveMark(int steps);
00054
00056
00059 T &getFromMark(int position) const;
00060
00061 void reset(T v);
00062
00063 void putArray(double *arr, int len);
00064
00065
00066 protected:
00067 size_t _size;
00068 unsigned current;
00069 unsigned currentMark;
00070 T *entry;
00071 };
00072
00073
00074 template <class T>
00075 CircularQueue<T>::CircularQueue(size_t size, T v)
00076 : _size(size)
00077 {
00078 entry = new T[_size];
00079 reset(v);
00080 }
00081
00082
00083 template <class T>
00084 CircularQueue<T>::~CircularQueue()
00085 {
00086 delete [] entry;
00087 }
00088
00089
00090 template <class T>
00091 inline void CircularQueue<T>::reset(T v)
00092 {
00093 fill(entry, entry + _size, v);
00094 current = 0;
00095 currentMark = 0;
00096 }
00097
00098
00099 template <class T>
00100 inline T & CircularQueue<T>::get(int position) const
00101 {
00102 int myIndex = current - position;
00103 if ( myIndex < 0 ) myIndex += _size;
00104 return entry[myIndex] ;
00105 }
00106
00107 template <class T>
00108 inline void CircularQueue<T>::putArray(double *arr, int len)
00109 {
00110 if (current + len >= _size) {
00111 int first_slice = _size - current - 1;
00112 memcpy((char *)(entry + current + 1), (char *)arr, sizeof(double)*(first_slice));
00113 memcpy((char *)(entry), (char *)(arr + first_slice), sizeof(double)*(len - first_slice));
00114 }
00115 else {
00116 memcpy((char *)(entry + current + 1), (char *)arr, sizeof(double)*len);
00117 }
00118 current = (current + len) % _size;
00119 }
00120
00121
00122 template <class T>
00123 inline T & CircularQueue<T>::getFromMark(int position) const
00124 {
00125 int myIndex = currentMark - position;
00126 if (myIndex < 0 ) myIndex += _size;
00127 return entry [myIndex];
00128 }
00129
00130
00131 template <class T>
00132 inline void CircularQueue<T>::moveMark(int steps)
00133 {
00134 currentMark += steps;
00135 if (currentMark > _size-1)
00136 currentMark -= _size;
00137 }
00138
00139
00140
00141 template <class T>
00142 inline void CircularQueue<T>::put(const T &elem)
00143 {
00144 if (current < _size-1)
00145 current++;
00146 else
00147 current=0;
00148
00149 entry[current] = elem;
00150 }
00151
00152
00153 #endif