|
activemq-cpp-3.3.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_ARRAYLIST_H_ 00019 #define _DECAF_UTIL_ARRAYLIST_H_ 00020 00021 #include <memory> 00022 #include <decaf/util/NoSuchElementException.h> 00023 #include <decaf/lang/exceptions/UnsupportedOperationException.h> 00024 #include <decaf/lang/exceptions/IndexOutOfBoundsException.h> 00025 #include <decaf/lang/System.h> 00026 #include <decaf/lang/Integer.h> 00027 #include <decaf/util/Config.h> 00028 #include <decaf/util/Iterator.h> 00029 #include <decaf/util/ListIterator.h> 00030 #include <decaf/util/List.h> 00031 #include <decaf/util/AbstractList.h> 00032 00033 namespace decaf { 00034 namespace util { 00035 00036 using decaf::lang::System; 00037 00038 template< typename E > 00039 class ArrayList : public decaf::util::AbstractList<E> { 00040 private: 00041 00042 E* elements; 00043 int capacity; 00044 int head; 00045 int curSize; 00046 00047 public: 00048 00049 ArrayList() : AbstractList<E>(), elements( NULL ), capacity( 0 ), head( 0 ), curSize( 0 ) { 00050 this->ensureCapacity( 10 ); 00051 } 00052 00053 ArrayList( const Collection<E>& collection ) : AbstractList<E>(), elements( NULL ), 00054 capacity( 0 ), head( 0 ), curSize( 0 ) { 00055 00056 this->capacity = collection.size() + ( collection.size() / 10 ); 00057 this->elements = new E[this->capacity]; 00058 00059 std::auto_ptr< Iterator<E> > iter( collection.iterator() ); 00060 while( iter->hasNext() ) { 00061 this->elements[this->head++] = iter->next(); 00062 this->curSize++; 00063 } 00064 } 00065 00066 ArrayList( const ArrayList<E>& arrayList ) : AbstractList<E>(), elements( NULL ), 00067 capacity( 0 ), head( 0 ), curSize( 0 ) { 00068 00069 this->capacity = arrayList.size() + ( arrayList.size() / 10 ); 00070 this->elements = new E[this->capacity]; 00071 00072 std::auto_ptr< Iterator<E> > iter( arrayList.iterator() ); 00073 while( iter->hasNext() ) { 00074 this->elements[this->head++] = iter->next(); 00075 this->curSize++; 00076 } 00077 } 00078 00079 ArrayList( int initialCapacity ) : AbstractList<E>(), elements( NULL ), 00080 capacity( initialCapacity ), head( 0 ), curSize( 0 ) { 00081 00082 if( initialCapacity < 0 ) { 00083 throw decaf::lang::exceptions::IllegalArgumentException( 00084 __FILE__, __LINE__, "Initial Capacity argument cannot be negative." ); 00085 } 00086 00087 this->elements = new E[this->capacity]; 00088 } 00089 00090 virtual ~ArrayList() { 00091 try{ 00092 delete [] elements; 00093 } 00094 DECAF_CATCHALL_NOTHROW() 00095 } 00096 00097 public: 00098 00099 ArrayList<E>& operator= ( const ArrayList<E>& list ) { 00100 this->clear(); 00101 this->addAll( list ); 00102 return *this; 00103 } 00104 00105 ArrayList<E>& operator= ( const Collection<E>& collection ) { 00106 this->clear(); 00107 this->addAll( 0, collection ); 00108 return *this; 00109 } 00110 00111 public: 00112 00122 void ensureCapacity( int minimumCapacity ) { 00123 00124 if( minimumCapacity < 0 || this->capacity >= minimumCapacity ) { 00125 return; 00126 } 00127 00128 int newCapacity = minimumCapacity == 0 ? 10 : minimumCapacity; 00129 00130 E* newElements = new E[newCapacity]; 00131 if( this->curSize > 0 ) { 00132 decaf::lang::System::arraycopy( this->elements, this->head, newElements, 0, this->curSize ); 00133 } 00134 delete [] this->elements; 00135 this->elements = newElements; 00136 this->capacity = newCapacity; 00137 AbstractList<E>::modCount++; 00138 } 00139 00144 void trimToSize() { 00145 00146 if( this->curSize < this->capacity ) { 00147 00148 int newCapacity = this->curSize == 0 ? 10 : this->curSize; 00149 00150 E* newElements = new E[newCapacity]; 00151 if( this->curSize > 0 ) { 00152 System::arraycopy( this->elements, 0, newElements, 0, this->curSize ); 00153 } 00154 00155 delete [] this->elements; 00156 this->elements = newElements; 00157 this->capacity = newCapacity; 00158 } 00159 00160 AbstractList<E>::modCount++; 00161 } 00162 00163 public: 00164 00165 virtual void clear() { 00166 delete [] this->elements; 00167 this->curSize = 0; 00168 this->capacity = 10; 00169 this->elements = new E[this->capacity]; 00170 AbstractList<E>::modCount++; 00171 } 00172 00173 virtual bool isEmpty() const { 00174 return this->curSize == 0; 00175 } 00176 00177 virtual int size() const { 00178 return this->curSize; 00179 } 00180 00181 virtual E set( int index, const E& element ) { 00182 00183 if( index < 0 || index >= this->curSize ) { 00184 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00185 __FILE__, __LINE__, 00186 "List::get - Index greater than size() or negative" ); 00187 } 00188 00189 E oldValue = this->elements[index]; 00190 this->elements[index] = element; 00191 00192 return oldValue; 00193 } 00194 00195 virtual E get( int index ) const { 00196 00197 if( index < 0 || index >= this->curSize ) { 00198 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00199 __FILE__, __LINE__, 00200 "List::get - Index greater than size() or negative" ); 00201 } 00202 00203 return this->elements[index]; 00204 } 00205 00206 virtual bool add( const E& value ) { 00207 00208 this->expandEnd( 1 ); 00209 this->elements[this->curSize++] = value; 00210 AbstractList<E>::modCount++; 00211 00212 return true; 00213 } 00214 00215 virtual void add( int index, const E& element ) { 00216 00217 if( index < 0 || index > this->curSize ) { 00218 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00219 __FILE__, __LINE__, 00220 "Index was negative or greater than size()" ); 00221 } 00222 00223 if( index == 0 ) { 00224 this->expandFront( 1 ); 00225 } else if( index == this->curSize ) { 00226 this->expandEnd( 1 ); 00227 } else { 00228 this->expandMiddle( index, 1 ); 00229 } 00230 00231 this->elements[index] = element; 00232 this->curSize++; 00233 AbstractList<E>::modCount++; 00234 } 00235 00236 virtual bool addAll( const Collection<E>& collection ) { 00237 00238 int csize = collection.size(); 00239 if( csize == 0 ) { 00240 return false; 00241 } 00242 00243 std::vector<E> array = collection.toArray(); 00244 00245 this->expandEnd( csize ); 00246 00247 for( int i = 0; i < csize; ++i ) { 00248 this->elements[this->curSize++] = array[i]; 00249 } 00250 00251 AbstractList<E>::modCount++; 00252 00253 return true; 00254 } 00255 00256 virtual bool addAll( int index, const Collection<E>& collection ) { 00257 00258 if( index < 0 || index > this->curSize ) { 00259 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00260 __FILE__, __LINE__, 00261 "List::addAll - Index greater than size()" ); 00262 } 00263 00264 int csize = collection.size(); 00265 if( csize == 0 ) { 00266 return false; 00267 } 00268 00269 std::vector<E> array = collection.toArray(); 00270 00271 if( index == 0 ) { 00272 this->expandFront( csize ); 00273 } else if( index == this->curSize ) { 00274 this->expandEnd( csize ); 00275 } else { 00276 this->expandMiddle( index, csize ); 00277 } 00278 00279 for( int i = 0; i < csize; ++i, ++this->curSize ) { 00280 this->elements[index++] = array[i]; 00281 } 00282 00283 AbstractList<E>::modCount++; 00284 00285 return true; 00286 } 00287 00288 virtual bool remove( const E& value ) { 00289 00290 int result = indexOf( value ); 00291 if( result != -1 ) { 00292 this->removeAt( result ); 00293 return true; 00294 } 00295 00296 return false; 00297 } 00298 00299 virtual E removeAt( int index ) { 00300 00301 if( index < 0 || index >= this->curSize ) { 00302 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00303 __FILE__, __LINE__, 00304 "List::removeAt - Index greater than size() or negative" ); 00305 } 00306 00307 E old = this->elements[index]; 00308 00309 System::arraycopy( this->elements, 0, this->elements, 0, index ); 00310 00311 if( this->curSize > index ) { 00312 System::arraycopy( this->elements, index + 1, this->elements, index, this->curSize - index - 1 ); 00313 } 00314 00315 this->elements[--this->curSize] = E(); 00316 AbstractList<E>::modCount++; 00317 00318 return old; 00319 } 00320 00321 virtual bool contains( const E& value ) const { 00322 return this->indexOf( value ) != -1; 00323 } 00324 00325 virtual int indexOf( const E& value ) const { 00326 00327 for( int i = 0; i < this->curSize; ++i ) { 00328 if( this->elements[i] == value ) { 00329 return i; 00330 } 00331 } 00332 00333 return -1; 00334 } 00335 00336 virtual int lastIndexOf( const E& value ) const { 00337 00338 for( int i = this->curSize - 1; i >= 0 ; --i ) { 00339 if( this->elements[i] == value ) { 00340 return i; 00341 } 00342 } 00343 00344 return -1; 00345 } 00346 00347 virtual std::vector<E> toArray() const { 00348 00349 std::vector<E> result; 00350 00351 for( int i = 0; i < this->curSize; ++i ) { 00352 result.push_back( this->elements[i] ); 00353 } 00354 00355 return result; 00356 } 00357 00358 virtual std::string toString() const { 00359 00360 std::string result; 00361 00362 result.append( "decaf::util::ArrayList [ size = " ); 00363 result.append( decaf::lang::Integer::toString( this->curSize ) ); 00364 result.append( " ]"); 00365 00366 return result; 00367 } 00368 00369 private: 00370 00371 void expandFront( int amount ) { 00372 00373 if( amount == 0 ) { 00374 return; 00375 } 00376 00377 E* previous = this->elements; 00378 00379 if( amount > this->capacity - this->curSize ) { 00380 this->capacity = this->capacity + amount + 11; 00381 this->elements = new E[this->capacity]; 00382 } 00383 00384 if( this->curSize > 0 ) { 00385 System::arraycopy( previous, 0, this->elements, amount, this->curSize ); 00386 } 00387 00388 if( previous != this->elements ) { 00389 delete [] previous; 00390 } 00391 } 00392 00393 void expandEnd( int amount ) { 00394 00395 if( amount == 0 ) { 00396 return; 00397 } 00398 00399 E* previous = this->elements; 00400 00401 if( amount > this->capacity - this->curSize ) { 00402 this->capacity = this->capacity + amount + 11; 00403 this->elements = new E[this->capacity]; 00404 System::arraycopy( previous, 0, this->elements, 0, this->curSize ); 00405 } 00406 00407 if( previous != this->elements ) { 00408 delete [] previous; 00409 } 00410 } 00411 00412 void expandMiddle( int index, int amount ) { 00413 00414 if( amount == 0 ) { 00415 return; 00416 } 00417 00418 E* previous = this->elements; 00419 00420 if( amount > this->capacity - this->curSize ) { 00421 this->capacity = this->capacity + amount + 11; 00422 this->elements = new E[this->capacity]; 00423 } 00424 00425 if( this->curSize > 0 ) { 00426 System::arraycopy( previous, 0, this->elements, 0, index ); 00427 } 00428 00429 if( this->curSize > index ) { 00430 System::arraycopy( previous, index, this->elements, index + amount, this->curSize - index ); 00431 } 00432 00433 if( previous != this->elements ) { 00434 delete [] previous; 00435 } 00436 } 00437 00438 }; 00439 00440 }} 00441 00442 #endif /* _DECAF_UTIL_ARRAYLIST_H_ */