activemq-cpp-3.3.0

src/main/decaf/util/StlQueue.h

Go to the documentation of this file.
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_*/