activemq-cpp-3.4.0

src/main/decaf/util/AbstractList.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 
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_ */