|
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 00018 #ifndef _DECAF_UTIL_ABSTRACTLIST_H_ 00019 #define _DECAF_UTIL_ABSTRACTLIST_H_ 00020 00021 #include <decaf/util/Config.h> 00022 #include <decaf/util/NoSuchElementException.h> 00023 #include <decaf/lang/exceptions/UnsupportedOperationException.h> 00024 #include <decaf/lang/exceptions/NullPointerException.h> 00025 #include <decaf/lang/exceptions/IllegalArgumentException.h> 00026 #include <decaf/util/ConcurrentModificationException.h> 00027 #include <decaf/lang/Iterable.h> 00028 #include <decaf/util/Iterator.h> 00029 #include <decaf/util/List.h> 00030 #include <decaf/util/AbstractCollection.h> 00031 #include <memory> 00032 00033 namespace decaf { 00034 namespace util { 00035 00064 template< typename E > 00065 class AbstractList : public decaf::util::List<E>, 00066 public decaf::util::AbstractCollection<E> { 00067 protected: 00068 00069 int modCount; 00070 00071 private: 00072 00073 class SimpleListIterator : public ListIterator<E> { 00074 protected: 00075 00076 AbstractList<E>* parent; 00077 int numLeft; 00078 int expectedModCount; 00079 int lastPosition; 00080 00081 private: 00082 00083 SimpleListIterator( const SimpleListIterator& ); 00084 SimpleListIterator operator= ( const SimpleListIterator& ); 00085 00086 public: 00087 00088 SimpleListIterator( AbstractList<E>* parent, int start ) : 00089 ListIterator<E>(), parent(NULL), numLeft(0), expectedModCount(0), lastPosition(-1) { 00090 00091 if( parent == NULL ) { 00092 throw decaf::lang::exceptions::NullPointerException( 00093 __FILE__, __LINE__, "List Iterator constructed with NULL parent" ); 00094 } 00095 00096 if( start < 0 || start > parent->size() ) { 00097 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00098 __FILE__, __LINE__, "start index passed was negative or greater than size()" ); 00099 } 00100 00101 this->numLeft = parent->size() - start; 00102 this->parent = parent; 00103 this->expectedModCount = parent->modCount; 00104 } 00105 00106 virtual ~SimpleListIterator() {} 00107 00108 virtual bool hasNext() const { 00109 return this->numLeft > 0; 00110 } 00111 00112 virtual E next() { 00113 00114 if( this->expectedModCount != this->parent->modCount ) { 00115 throw ConcurrentModificationException( 00116 __FILE__, __LINE__, "Concurrent Modification of Parent List detected." ); 00117 } 00118 00119 try { 00120 00121 int index = this->parent->size() - this->numLeft; 00122 E result = this->parent->get( index ); 00123 this->lastPosition = index; 00124 this->numLeft--; 00125 00126 return result; 00127 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00128 throw decaf::util::NoSuchElementException( 00129 __FILE__, __LINE__, "Next called without a next element to process." ); 00130 } 00131 } 00132 00133 virtual void remove() { 00134 00135 if( this->lastPosition == -1 ) { 00136 throw decaf::lang::exceptions::IllegalStateException( 00137 __FILE__, __LINE__, "Remove called before next() was called." ); 00138 } 00139 00140 if( this->expectedModCount != this->parent->modCount ) { 00141 throw ConcurrentModificationException( 00142 __FILE__, __LINE__, "Concurrent Modification of Parent List detected." ); 00143 } 00144 00145 try { 00146 00147 if( this->lastPosition == this->parent->size() - this->numLeft ) { 00148 this->numLeft--; // we're removing after a call to previous() 00149 } 00150 00151 this->parent->removeAt( lastPosition ); 00152 00153 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00154 throw ConcurrentModificationException( 00155 __FILE__, __LINE__, "Concurrent Modification detected." ); 00156 } 00157 00158 this->expectedModCount = this->parent->modCount; 00159 this->lastPosition = -1; 00160 } 00161 00162 virtual void add( const E& value ) { 00163 00164 if( this->expectedModCount != this->parent->modCount ) { 00165 throw ConcurrentModificationException( 00166 __FILE__, __LINE__, "Concurrent Modification of Parent List detected." ); 00167 } 00168 00169 try { 00170 this->parent->add( this->parent->size() - this->numLeft, value ); 00171 this->expectedModCount = this->parent->modCount; 00172 this->lastPosition = -1; 00173 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00174 throw decaf::util::NoSuchElementException( 00175 __FILE__, __LINE__, "Add called without a next element to process." ); 00176 } 00177 } 00178 00179 virtual bool hasPrevious() const { 00180 return this->numLeft < this->parent->size(); 00181 } 00182 00183 virtual int nextIndex() const { 00184 return this->parent->size() - this->numLeft; 00185 } 00186 00187 virtual E previous() { 00188 00189 if( this->expectedModCount != this->parent->modCount ) { 00190 throw ConcurrentModificationException( 00191 __FILE__, __LINE__, "Concurrent Modification detected." ); 00192 } 00193 00194 try { 00195 00196 int index = this->parent->size() - this->numLeft - 1; 00197 E result = this->parent->get( index ); 00198 this->numLeft++; 00199 this->lastPosition = index; 00200 00201 return result; 00202 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00203 throw decaf::util::NoSuchElementException( 00204 __FILE__, __LINE__, "No previous element exists." ); 00205 } 00206 } 00207 00208 virtual int previousIndex() const { 00209 return this->parent->size() - this->numLeft - 1; 00210 } 00211 00212 virtual void set( const E& value ) { 00213 00214 if( this->expectedModCount != this->parent->modCount ) { 00215 throw ConcurrentModificationException( 00216 __FILE__, __LINE__, "Concurrent Modification detected." ); 00217 } 00218 00219 try { 00220 this->parent->set( this->lastPosition, value ); 00221 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00222 throw decaf::lang::exceptions::IllegalStateException(); 00223 } 00224 } 00225 }; 00226 00227 class ConstSimpleListIterator : public ListIterator<E> { 00228 protected: 00229 00230 const AbstractList<E>* parent; 00231 int numLeft; 00232 int expectedModCount; 00233 int lastPosition; 00234 00235 private: 00236 00237 ConstSimpleListIterator( const ConstSimpleListIterator& ); 00238 ConstSimpleListIterator operator= ( const ConstSimpleListIterator& ); 00239 00240 public: 00241 00242 ConstSimpleListIterator( const AbstractList<E>* parent, int start ) : 00243 ListIterator<E>(), parent(parent), numLeft(0), expectedModCount(0), lastPosition(-1) { 00244 00245 if( parent == NULL ) { 00246 throw decaf::lang::exceptions::NullPointerException( 00247 __FILE__, __LINE__, "List Iterator constructed with NULL parent" ); 00248 } 00249 00250 if( start < 0 || start > parent->size() ) { 00251 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00252 __FILE__, __LINE__, "start index passed was negative or greater than size()" ); 00253 } 00254 00255 this->numLeft = parent->size() - start; 00256 this->parent = parent; 00257 this->expectedModCount = parent->modCount; 00258 } 00259 00260 virtual ~ConstSimpleListIterator() {} 00261 00262 virtual bool hasNext() const { 00263 return this->numLeft > 0; 00264 } 00265 00266 virtual E next() { 00267 00268 if( this->expectedModCount != this->parent->modCount ) { 00269 throw ConcurrentModificationException( 00270 __FILE__, __LINE__, "Concurrent Modification of Parent List detected." ); 00271 } 00272 00273 try { 00274 00275 int index = this->parent->size() - this->numLeft; 00276 E result = this->parent->get( index ); 00277 this->lastPosition = index; 00278 this->numLeft--; 00279 00280 return result; 00281 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00282 throw decaf::util::NoSuchElementException( 00283 __FILE__, __LINE__, "Next called without a next element to process." ); 00284 } 00285 } 00286 00287 virtual void remove() { 00288 throw lang::exceptions::UnsupportedOperationException( 00289 __FILE__, __LINE__, 00290 "AbstractList::Iterator::remove - Const Iterator." ); 00291 } 00292 00293 virtual void add( const E& value DECAF_UNUSED ) { 00294 throw lang::exceptions::UnsupportedOperationException( 00295 __FILE__, __LINE__, 00296 "AbstractList::ListIterator::radd - Const Iterator." ); 00297 } 00298 00299 virtual bool hasPrevious() const { 00300 return this->numLeft < this->parent->size(); 00301 } 00302 00303 virtual int nextIndex() const { 00304 return this->parent->size() - this->numLeft; 00305 } 00306 00307 virtual E previous() { 00308 00309 if( this->expectedModCount != this->parent->modCount ) { 00310 throw ConcurrentModificationException( 00311 __FILE__, __LINE__, "Concurrent Modification detected." ); 00312 } 00313 00314 try { 00315 00316 int index = this->parent->size() - this->numLeft - 1; 00317 E result = this->parent->get( index ); 00318 this->numLeft++; 00319 this->lastPosition = index; 00320 00321 return result; 00322 } catch( decaf::lang::exceptions::IndexOutOfBoundsException& e ) { 00323 throw decaf::util::NoSuchElementException( 00324 __FILE__, __LINE__, "No previous element exists." ); 00325 } 00326 } 00327 00328 virtual int previousIndex() const { 00329 return this->parent->size() - this->numLeft - 1; 00330 } 00331 00332 virtual void set( const E& value DECAF_UNUSED ) { 00333 throw lang::exceptions::UnsupportedOperationException( 00334 __FILE__, __LINE__, 00335 "AbstractList::ListIterator::set - Const Iterator." ); 00336 } 00337 }; 00338 00339 public: 00340 00341 AbstractList() : modCount( 0 ) {} 00342 00343 virtual ~AbstractList() {} 00344 00345 virtual Iterator<E>* iterator() { 00346 return new SimpleListIterator( this, 0 ); 00347 } 00348 virtual Iterator<E>* iterator() const { 00349 return new ConstSimpleListIterator( this, 0 ); 00350 } 00351 00352 virtual ListIterator<E>* listIterator() { 00353 return new SimpleListIterator( this, 0 ); 00354 } 00355 virtual ListIterator<E>* listIterator() const { 00356 return new ConstSimpleListIterator( this, 0 ); 00357 } 00358 00359 virtual ListIterator<E>* listIterator( int index ) { 00360 return new SimpleListIterator( this, index ); 00361 } 00362 virtual ListIterator<E>* listIterator( int index ) const { 00363 return new ConstSimpleListIterator( this, index ); 00364 } 00365 00366 virtual void clear() { 00367 this->removeRange( 0, this->size() ); 00368 } 00369 00370 virtual bool add( const E& value ) { 00371 this->add( this->size(), value ); 00372 return true; 00373 } 00374 00375 virtual void add( int index DECAF_UNUSED, const E& element DECAF_UNUSED ) { 00376 throw decaf::lang::exceptions::UnsupportedOperationException( 00377 __FILE__, __LINE__, "Abstract list does not implement the add method." ); 00378 } 00379 00380 // Use this method since our own addAll will hide the base class version. 00381 using AbstractCollection<E>::addAll; 00382 00383 virtual bool addAll( int index, const Collection<E>& source ) { 00384 std::auto_ptr< decaf::util::Iterator<E> > iter( source.iterator() ); 00385 while( iter->hasNext() ) { 00386 this->add( index++, iter->next() ); 00387 } 00388 00389 return !source.isEmpty(); 00390 } 00391 00392 virtual E removeAt( int index DECAF_UNUSED ) { 00393 throw decaf::lang::exceptions::UnsupportedOperationException( 00394 __FILE__, __LINE__, "Abstract list does not implement the removeAt method." ); 00395 } 00396 00397 virtual E set( int index DECAF_UNUSED, const E& element DECAF_UNUSED ) { 00398 throw decaf::lang::exceptions::UnsupportedOperationException( 00399 __FILE__, __LINE__, "Abstract list does not implement the set method." ); 00400 } 00401 00402 virtual int indexOf( const E& value ) const { 00403 00404 std::auto_ptr< decaf::util::ListIterator<E> > iter( this->listIterator() ); 00405 00406 while( iter->hasNext() ) { 00407 00408 if( value == iter->next() ) { 00409 return iter->previousIndex(); 00410 } 00411 } 00412 00413 return -1; 00414 } 00415 00416 virtual int lastIndexOf( const E& value ) const { 00417 00418 std::auto_ptr< decaf::util::ListIterator<E> > iter( this->listIterator( this->size() ) ); 00419 00420 while( iter->hasPrevious() ) { 00421 00422 if( value == iter->previous() ) { 00423 return iter->nextIndex(); 00424 } 00425 } 00426 00427 return -1; 00428 } 00429 00430 protected: 00431 00432 void removeRange( int start, int end ) { 00433 std::auto_ptr< decaf::util::Iterator<E> > iter( this->listIterator( start ) ); 00434 for( int i = start; i < end; i++ ) { 00435 iter->next(); 00436 iter->remove(); 00437 } 00438 } 00439 00440 }; 00441 00442 }} 00443 00444 #endif /* _DECAF_UTIL_ABSTRACTLIST_H_ */