|
activemq-cpp-3.4.0
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 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 // The real queue 00064 std::list<T> queue; 00065 00066 // Object used for sync 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 // Pop the element into a temp, since we need to remain locked. 00208 // this means getting front and then popping. 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: // Synchronizable 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: // Statics 00284 00290 T& getSafeValue() { 00291 static T safe; 00292 return safe; 00293 } 00294 00295 }; 00296 00297 }} 00298 00299 #endif /*_DECAF_UTIL_STLQUEUE_H_*/