00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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--;
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
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 if (value == iter->next()) {
00408 return iter->previousIndex();
00409 }
00410 }
00411
00412 return -1;
00413 }
00414
00415 virtual int lastIndexOf(const E& value) const {
00416
00417 std::auto_ptr< decaf::util::ListIterator<E> > iter( this->listIterator( this->size() ) );
00418
00419 while (iter->hasPrevious()) {
00420 if (value == iter->previous()) {
00421 return iter->nextIndex();
00422 }
00423 }
00424
00425 return -1;
00426 }
00427
00428 protected:
00429
00430 void removeRange(int start, int end) {
00431 std::auto_ptr<decaf::util::Iterator<E> > iter(this->listIterator(start));
00432 for (int i = start; i < end; i++) {
00433 iter->next();
00434 iter->remove();
00435 }
00436 }
00437
00438 };
00439
00440 }}
00441
00442 #endif