00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _DECAF_UTIL_STLQUEUE_H_
00018 #define _DECAF_UTIL_STLQUEUE_H_
00019
00020 #include <list>
00021 #include <vector>
00022 #include <decaf/util/Iterator.h>
00023 #include <decaf/util/concurrent/Mutex.h>
00024 #include <decaf/lang/Exception.h>
00025
00026 namespace decaf{
00027 namespace util{
00028
00059 template <typename T>
00060 class StlQueue : public concurrent::Synchronizable {
00061 private:
00062
00063
00064 std::list<T> queue;
00065
00066
00067 mutable util::concurrent::Mutex mutex;
00068
00069 private:
00070
00071 class QueueIterator : public Iterator<T> {
00072 private:
00073
00074 typename std::list<T>::iterator current;
00075 typename std::list<T>::iterator previous;
00076 typename std::list<T>* queue;
00077
00078 public:
00079
00080 QueueIterator( typename std::list<T>* queue ) :
00081 current( queue->begin() ), previous( queue->end() ), queue( queue ) {
00082 }
00083
00084 virtual ~QueueIterator() {}
00085
00086 virtual T next() {
00087 if( this->current == queue->end() ) {
00088 throw NoSuchElementException(
00089 __FILE__, __LINE__,
00090 "Queue::Iterator::next - No more elements to return" );
00091 }
00092
00093 this->previous = this->current;
00094 return *( this->current++ );
00095 }
00096
00097 virtual bool hasNext() const {
00098 return ( this->current != queue->end() );
00099 }
00100
00101 virtual void remove() {
00102 if( this->previous == queue->end() ) {
00103 throw lang::exceptions::IllegalStateException(
00104 __FILE__, __LINE__,
00105 "Queue::Iterator::remove - Invalid State to call remove" );
00106 }
00107
00108 this->queue->erase( this->previous );
00109 this->previous = this->queue->end();
00110 }
00111 };
00112
00113 public:
00114
00115 StlQueue() : queue(), mutex() {}
00116
00117 virtual ~StlQueue() {}
00118
00123 Iterator<T>* iterator() {
00124 return new QueueIterator( &queue );
00125 }
00126
00130 void clear() {
00131 queue.clear();
00132 }
00133
00138 T& front() {
00139 if( queue.empty() ) {
00140 return getSafeValue();
00141 }
00142
00143 return queue.front();
00144 }
00145
00150 const T& front() const {
00151 if( queue.empty() ) {
00152 return getSafeValue();
00153 }
00154
00155 return queue.front();
00156 }
00157
00162 T& back() {
00163 if( queue.empty() ) {
00164 return getSafeValue();
00165 }
00166
00167 return queue.back();
00168 }
00169
00174 const T& back() const {
00175 if( queue.empty() ) {
00176 return getSafeValue();
00177 }
00178
00179 return queue.back();
00180 }
00181
00186 void push( const T &t ) {
00187 queue.push_back( t );
00188 }
00189
00194 void enqueueFront( const T &t ) {
00195 queue.push_front( t );
00196 }
00197
00202 T pop() {
00203 if( queue.empty() ) {
00204 return getSafeValue();
00205 }
00206
00207
00208
00209 T temp = queue.front();
00210 queue.pop_front();
00211
00212 return temp;
00213 }
00214
00219 size_t size() const{
00220 return queue.size();
00221 }
00222
00227 bool empty() const {
00228 return queue.empty();
00229 }
00230
00234 virtual std::vector<T> toArray() const {
00235 std::vector<T> valueArray( queue.begin(), queue.end() );
00236 return valueArray;
00237 }
00238
00245 void reverse( StlQueue<T>& target ) const {
00246 target.queue.insert( target.queue.end(), queue.rbegin(), queue.rend() );
00247 }
00248
00249 public:
00250
00251 virtual void lock() {
00252 mutex.lock();
00253 }
00254
00255 virtual bool tryLock() {
00256 return mutex.tryLock();
00257 }
00258
00259 virtual void unlock() {
00260 mutex.unlock();
00261 }
00262
00263 virtual void wait() {
00264 mutex.wait();
00265 }
00266
00267 virtual void wait( long long millisecs ) {
00268 mutex.wait( millisecs );
00269 }
00270
00271 virtual void wait( long long millisecs, int nanos ) {
00272 mutex.wait( millisecs, nanos );
00273 }
00274
00275 virtual void notify() {
00276 mutex.notify();
00277 }
00278
00279 virtual void notifyAll() {
00280 mutex.notifyAll();
00281 }
00282
00283 public:
00284
00290 T& getSafeValue() {
00291 static T safe;
00292 return safe;
00293 }
00294
00295 };
00296
00297 }}
00298
00299 #endif