00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef RAUL_SRSW_QUEUE_HPP
00019 #define RAUL_SRSW_QUEUE_HPP
00020
00021 #include <cassert>
00022
00023 #include <boost/utility.hpp>
00024
00025 #include "raul/AtomicInt.hpp"
00026
00027 namespace Raul {
00028
00029
00042 template <typename T>
00043 class SRSWQueue : boost::noncopyable
00044 {
00045 public:
00047 explicit SRSWQueue(size_t size);
00048 ~SRSWQueue();
00049
00050
00051
00052 inline size_t capacity() const { return _size-1; }
00053
00054
00055
00056
00057 inline bool full() const;
00058 inline bool push(const T& obj);
00059
00060
00061
00062
00063 inline bool empty() const;
00064 inline T& front() const;
00065 inline void pop();
00066
00067 private:
00068 AtomicInt _front;
00069 AtomicInt _back;
00070 const size_t _size;
00071 T* const _objects;
00072 };
00073
00074
00075 template<typename T>
00076 SRSWQueue<T>::SRSWQueue(size_t size)
00077 : _front(0)
00078 , _back(0)
00079 , _size(size + 1)
00080 , _objects(new T[_size])
00081 {
00082 assert(size > 1);
00083 }
00084
00085
00086 template <typename T>
00087 SRSWQueue<T>::~SRSWQueue()
00088 {
00089 delete[] _objects;
00090 }
00091
00092
00095 template <typename T>
00096 inline bool
00097 SRSWQueue<T>::empty() const
00098 {
00099 return (_back.get() == _front.get());
00100 }
00101
00102
00105 template <typename T>
00106 inline bool
00107 SRSWQueue<T>::full() const
00108 {
00109 return (((_front.get() - _back.get() + _size) % _size) == 1);
00110 }
00111
00112
00115 template <typename T>
00116 inline T&
00117 SRSWQueue<T>::front() const
00118 {
00119 return _objects[_front.get()];
00120 }
00121
00122
00128 template <typename T>
00129 inline bool
00130 SRSWQueue<T>::push(const T& elem)
00131 {
00132 if (full()) {
00133 return false;
00134 } else {
00135 unsigned back = _back.get();
00136 _objects[back] = elem;
00137 _back = (back + 1) % _size;
00138 return true;
00139 }
00140 }
00141
00142
00149 template <typename T>
00150 inline void
00151 SRSWQueue<T>::pop()
00152 {
00153 assert(!empty());
00154 assert(_size > 0);
00155
00156 _front = (_front.get() + 1) % (_size);
00157 }
00158
00159
00160 }
00161
00162 #endif // RAUL_SRSW_QUEUE_HPP