|
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_LINKEDLIST_H_ 00019 #define _DECAF_UTIL_LINKEDLIST_H_ 00020 00021 #include <list> 00022 #include <memory> 00023 #include <decaf/util/NoSuchElementException.h> 00024 #include <decaf/lang/exceptions/UnsupportedOperationException.h> 00025 #include <decaf/lang/exceptions/IndexOutOfBoundsException.h> 00026 #include <decaf/lang/System.h> 00027 #include <decaf/lang/Integer.h> 00028 #include <decaf/util/Config.h> 00029 #include <decaf/util/Deque.h> 00030 #include <decaf/util/ArrayList.h> 00031 #include <decaf/util/Iterator.h> 00032 #include <decaf/util/ListIterator.h> 00033 #include <decaf/util/AbstractSequentialList.h> 00034 00035 namespace decaf { 00036 namespace util { 00037 00038 using decaf::lang::System; 00039 00054 template< typename E > 00055 class LinkedList : public AbstractSequentialList<E>, public Deque<E> { 00056 private: 00057 00058 template< typename U > 00059 class ListNode { 00060 public: 00061 00062 U value; 00063 ListNode<U>* prev; 00064 ListNode<U>* next; 00065 00066 private: 00067 00068 ListNode( const ListNode& ); 00069 ListNode& operator= ( const ListNode& ); 00070 00071 public: 00072 00073 ListNode() : value(), prev(NULL), next(NULL) { 00074 } 00075 00076 ListNode( const U& value ) : value(value), prev(NULL), next(NULL) { 00077 } 00078 00079 ListNode( ListNode<U>* prev, ListNode<U>* next, const U& value ) : 00080 value(value), prev(prev), next(next) { 00081 } 00082 00083 }; 00084 00085 private: 00086 00087 int listSize; 00088 ListNode<E> head; 00089 ListNode<E> tail; 00090 00091 public: 00092 00093 LinkedList() : 00094 AbstractSequentialList<E>(), listSize(0), head(), tail() { 00095 00096 this->head.next = &this->tail; 00097 this->tail.prev = &this->head; 00098 } 00099 00100 LinkedList( const LinkedList<E>& list ) : 00101 AbstractSequentialList<E>(), listSize(0), head(), tail() { 00102 00103 this->head.next = &this->tail; 00104 this->tail.prev = &this->head; 00105 00106 this->addAllAtLocation( 0, list ); 00107 } 00108 00109 LinkedList( const Collection<E>& collection ) : 00110 AbstractSequentialList<E>(), listSize(0), head(), tail() { 00111 00112 this->head.next = &this->tail; 00113 this->tail.prev = &this->head; 00114 00115 this->addAllAtLocation( 0, collection ); 00116 } 00117 00118 virtual ~LinkedList() { 00119 try{ 00120 this->purgeList(); 00121 } catch(...) {} 00122 } 00123 00124 public: 00125 00126 LinkedList<E>& operator= ( const LinkedList<E>& list ) { 00127 this->clear(); 00128 this->addAllAtLocation( 0, list ); 00129 return *this; 00130 } 00131 00132 LinkedList<E>& operator= ( const Collection<E>& collection ) { 00133 this->clear(); 00134 this->addAllAtLocation( 0, collection ); 00135 return *this; 00136 } 00137 00138 public: 00139 00140 virtual E get( int index ) const { 00141 00142 if( index < 0 || index >= this->listSize ) { 00143 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00144 __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index ); 00145 } 00146 00147 const ListNode<E>* location = NULL; 00148 00149 if( index < this->listSize / 2 ) { 00150 location = &this->head; 00151 for( int i = 0; i <= index; ++i ) { 00152 location = location->next; 00153 } 00154 } else { 00155 location = &this->tail; 00156 for( int i = this->listSize; i > index; --i ) { 00157 location = location->prev; 00158 } 00159 } 00160 00161 return location->value; 00162 } 00163 00164 virtual E set( int index, const E& element ) { 00165 00166 if( index < 0 || index >= this->listSize ) { 00167 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00168 __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index ); 00169 } 00170 00171 ListNode<E>* location = NULL; 00172 00173 if( index < this->listSize / 2 ) { 00174 location = &this->head; 00175 for( int i = 0; i <= index; ++i ) { 00176 location = location->next; 00177 } 00178 } else { 00179 location = &this->tail; 00180 for( int i = this->listSize; i > index; --i ) { 00181 location = location->prev; 00182 } 00183 } 00184 00185 E oldValue = location->value; 00186 location->value = element; 00187 00188 return oldValue; 00189 } 00190 00191 virtual bool add( const E& value ) { 00192 this->addToEnd( value ); 00193 return true; 00194 } 00195 00196 virtual void add( int index, const E& value ) { 00197 00198 if( index < 0 || index > this->listSize ) { 00199 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00200 __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index ); 00201 } 00202 00203 this->addAtLocation( index, value ); 00204 } 00205 00206 virtual bool addAll( const Collection<E>& collection ) { 00207 return this->addAllAtLocation( this->listSize, collection ); 00208 } 00209 00210 virtual bool addAll( int index, const Collection<E>& collection ) { 00211 return this->addAllAtLocation( index, collection ); 00212 } 00213 00214 virtual void copy( const Collection<E>& collection ) { 00215 this->clear(); 00216 this->addAllAtLocation( 0, collection ); 00217 } 00218 00219 virtual bool remove( const E& value ) { 00220 return this->removeFirstOccurrence( value ); 00221 } 00222 00223 virtual bool isEmpty() const { 00224 return this->listSize == 0; 00225 } 00226 00227 virtual int size() const { 00228 return this->listSize; 00229 } 00230 00231 virtual void clear() { 00232 this->purgeList(); 00233 this->head.next = &this->tail; 00234 this->tail.prev = &this->head; 00235 this->listSize = 0; 00236 AbstractList<E>::modCount++; 00237 } 00238 00239 virtual bool contains( const E& value ) const { 00240 return this->indexOf( value ) != -1; 00241 } 00242 00243 virtual int indexOf( const E& value ) const { 00244 00245 if( this->listSize == 0 ) { 00246 return -1; 00247 } 00248 00249 const ListNode<E>* location = this->head.next; 00250 00251 for( int i = 0; location != &this->tail; ++i, location = location->next ) { 00252 if( location->value == value ) { 00253 return i; 00254 } 00255 } 00256 00257 return -1; 00258 } 00259 00260 virtual int lastIndexOf( const E& value ) const { 00261 00262 if( this->listSize == 0 ) { 00263 return -1; 00264 } 00265 00266 const ListNode<E>* location = this->tail.prev; 00267 00268 for( int i = this->listSize - 1; location != &this->head; --i, location = location->prev ) { 00269 if( location->value == value ) { 00270 return i; 00271 } 00272 } 00273 00274 return -1; 00275 } 00276 00277 virtual std::vector<E> toArray() const { 00278 00279 std::vector<E> result; 00280 result.reserve( this->listSize ); 00281 00282 const ListNode<E>* current = this->head.next; 00283 00284 while( current != &this->tail ) { 00285 result.push_back( current->value ); 00286 current = current->next; 00287 } 00288 00289 return result; 00290 } 00291 00292 public: // Deque interface implementation. 00293 00294 virtual bool offer( const E& value ) { 00295 this->addLast( value ); 00296 return true; 00297 } 00298 00299 virtual bool poll( E& result ) { 00300 00301 if( this->listSize == 0 ) { 00302 return false; 00303 } 00304 00305 result = this->head.next->value; 00306 this->removeAtFront(); 00307 return true; 00308 } 00309 00310 virtual E remove() { 00311 return this->removeAtFront(); 00312 } 00313 00314 virtual bool peek( E& result ) const { 00315 00316 if( this->listSize == 0 ) { 00317 return false; 00318 } 00319 00320 result = this->head.next->value; 00321 return true; 00322 } 00323 00324 virtual E element() const { 00325 if( this->listSize == 0 ) { 00326 throw decaf::util::NoSuchElementException( 00327 __FILE__, __LINE__, "The list is Empty" ); 00328 } 00329 00330 return this->head.next->value; 00331 } 00332 00333 virtual void addFirst( const E& value ) { 00334 this->addToFront( value ); 00335 } 00336 00337 virtual void addLast( const E& value ) { 00338 this->addToEnd( value ); 00339 } 00340 00341 virtual E& getFirst() { 00342 if( this->listSize == 0 ) { 00343 throw decaf::util::NoSuchElementException( 00344 __FILE__, __LINE__, "The list is Empty" ); 00345 } 00346 00347 return this->head.next->value; 00348 } 00349 00350 virtual const E& getFirst() const { 00351 if( this->listSize == 0 ) { 00352 throw decaf::util::NoSuchElementException( 00353 __FILE__, __LINE__, "The list is Empty" ); 00354 } 00355 00356 return this->head.next->value; 00357 } 00358 00359 virtual E& getLast() { 00360 if( this->listSize == 0 ) { 00361 throw decaf::util::NoSuchElementException( 00362 __FILE__, __LINE__, "The list is Empty" ); 00363 } 00364 00365 return this->tail.prev->value; 00366 } 00367 00368 virtual const E& getLast() const { 00369 if( this->listSize == 0 ) { 00370 throw decaf::util::NoSuchElementException( 00371 __FILE__, __LINE__, "The list is Empty" ); 00372 } 00373 00374 return this->tail.prev->value; 00375 } 00376 00377 virtual bool offerFirst( const E& element ) { 00378 this->addToFront( element ); 00379 return true; 00380 } 00381 00382 virtual bool offerLast( const E& element ) { 00383 this->addToEnd( element ); 00384 return true; 00385 } 00386 00387 virtual E removeFirst() { 00388 return this->removeAtFront(); 00389 } 00390 00391 virtual E removeLast() { 00392 return this->removeAtEnd(); 00393 } 00394 00395 virtual bool pollFirst( E& result ) { 00396 if( this->listSize == 0 ) { 00397 return false; 00398 } 00399 00400 result = this->head.next->value; 00401 this->removeAtFront(); 00402 return true; 00403 } 00404 00405 virtual bool pollLast( E& result ) { 00406 if( this->listSize == 0 ) { 00407 return false; 00408 } 00409 00410 result = this->tail.prev->value; 00411 this->removeAtEnd(); 00412 return true; 00413 } 00414 00415 virtual bool peekFirst( E& result ) const { 00416 if( this->listSize == 0 ) { 00417 return false; 00418 } 00419 00420 result = this->head.next->value; 00421 return true; 00422 } 00423 00424 virtual bool peekLast( E& result ) const { 00425 if( this->listSize == 0 ) { 00426 return false; 00427 } 00428 00429 result = this->tail.prev->value; 00430 return true; 00431 } 00432 00433 virtual E pop() { 00434 return this->removeAtFront(); 00435 } 00436 00437 virtual void push( const E& element ) { 00438 this->addToFront( element ); 00439 } 00440 00441 virtual bool removeFirstOccurrence( const E& value ) { 00442 std::auto_ptr< Iterator<E> > iter( this->iterator() ); 00443 while( iter->hasNext() ) { 00444 if( iter->next() == value ) { 00445 iter->remove(); 00446 return true; 00447 } 00448 } 00449 00450 return false; 00451 } 00452 virtual bool removeLastOccurrence( const E& value ) { 00453 std::auto_ptr< Iterator<E> > iter( this->descendingIterator() ); 00454 while( iter->hasNext() ) { 00455 if( iter->next() == value ) { 00456 iter->remove(); 00457 return true; 00458 } 00459 } 00460 00461 return false; 00462 } 00463 00464 private: 00465 00466 class LinkedListIterator : public ListIterator<E> { 00467 private: 00468 00469 mutable LinkedList<E>* list; 00470 ListNode<E>* current; 00471 ListNode<E>* lastReturned; 00472 int index; 00473 int expectedModCount; 00474 00475 private: 00476 00477 LinkedListIterator( const LinkedListIterator& ); 00478 LinkedListIterator operator= ( const LinkedListIterator& ); 00479 00480 public: 00481 00482 LinkedListIterator( LinkedList<E>* list, int index ) : 00483 ListIterator<E>(), list(list), current(NULL), lastReturned(NULL), index(-1), expectedModCount(0) { 00484 00485 if( list == NULL ) { 00486 throw decaf::lang::exceptions::NullPointerException( 00487 __FILE__, __LINE__, "Parent LinkedList pointer was Null." ); 00488 } 00489 00490 if( index < 0 || index > list->listSize ) { 00491 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00492 __FILE__, __LINE__, "Given index {%d} is out of range.", index ); 00493 } 00494 00495 this->expectedModCount = list->modCount; 00496 00497 // index starts at -1 to indicate that we are before begin or that the 00498 // list is empty. We always want to start out one before so that the call 00499 // to next moves us onto the element in question; 00500 00501 if( index < this->list->listSize / 2 ) { 00502 this->current = &this->list->head; 00503 for( this->index = -1; this->index + 1 < index; ++this->index ) { 00504 this->current = this->current->next; 00505 } 00506 } else { 00507 this->current = &this->list->tail; 00508 for( this->index = this->list->listSize; this->index >= index; --this->index ) { 00509 this->current = this->current->prev; 00510 } 00511 } 00512 } 00513 00514 virtual ~LinkedListIterator() {} 00515 00516 virtual E next() { 00517 00518 if( this->expectedModCount != this->list->modCount ) { 00519 throw ConcurrentModificationException( 00520 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00521 } 00522 00523 if( this->current->next == &(this->list->tail) ) { 00524 throw NoSuchElementException( 00525 __FILE__, __LINE__, "No more elements to return from next()" ); 00526 } 00527 00528 this->current = this->current->next; 00529 this->lastReturned = this->current; 00530 this->index++; 00531 00532 return this->current->value; 00533 } 00534 00535 virtual bool hasNext() const { 00536 return ( this->current->next != &(this->list->tail) ); 00537 } 00538 00539 00540 virtual E previous() { 00541 if( this->expectedModCount != this->list->modCount ) { 00542 throw ConcurrentModificationException( 00543 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00544 } 00545 00546 if( this->current == &(this->list->head) ) { 00547 throw decaf::lang::exceptions::IllegalStateException( 00548 __FILE__, __LINE__, 00549 "No previous element, must call next() before calling previous()." ); 00550 } 00551 00552 this->lastReturned = this->current; 00553 this->current = this->current->prev; 00554 this->index--; 00555 00556 return this->lastReturned->value; 00557 } 00558 00559 virtual bool hasPrevious() const { 00560 return ( this->current != &(this->list->head) ); 00561 } 00562 00563 virtual void remove() { 00564 if( this->expectedModCount != this->list->modCount ) { 00565 throw ConcurrentModificationException( 00566 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00567 } 00568 00569 if( this->lastReturned == NULL ) { 00570 throw lang::exceptions::IllegalStateException( 00571 __FILE__, __LINE__, 00572 "Invalid State to call remove, must call next() before remove()" ); 00573 } 00574 00575 ListNode<E>* next = this->lastReturned->next; 00576 ListNode<E>* previous = this->lastReturned->prev; 00577 00578 next->prev = previous; 00579 previous->next = next; 00580 00581 // When iterating in reverse this would not be true 00582 if( this->current == this->lastReturned ) { 00583 this->index--; 00584 } 00585 this->current = previous; 00586 00587 delete this->lastReturned; 00588 this->lastReturned = NULL; 00589 00590 this->list->listSize--; 00591 this->list->modCount++; 00592 00593 this->expectedModCount++; 00594 } 00595 00596 virtual void add( const E& e ) { 00597 if( this->expectedModCount != this->list->modCount ) { 00598 throw ConcurrentModificationException( 00599 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00600 } 00601 00602 ListNode<E>* newNode = new ListNode<E>( this->current, this->current->next, e ); 00603 00604 this->current->next->prev = newNode; 00605 this->current->next = newNode; 00606 00607 this->current = newNode; 00608 this->lastReturned = NULL; 00609 00610 this->index++; 00611 this->expectedModCount++; 00612 this->list->modCount++; 00613 this->list->listSize++; 00614 } 00615 00616 virtual void set( const E& e ) { 00617 00618 if( this->expectedModCount != this->list->modCount ) { 00619 throw ConcurrentModificationException( 00620 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00621 } 00622 00623 if( this->lastReturned != NULL ) { 00624 this->lastReturned->value = e; 00625 } else { 00626 throw decaf::lang::exceptions::IllegalStateException( 00627 __FILE__, __LINE__, "Iterator next has not been called." ); 00628 } 00629 } 00630 00631 virtual int nextIndex() const { 00632 return this->index + 1; 00633 } 00634 00635 virtual int previousIndex() const { 00636 return this->index; 00637 } 00638 }; 00639 00640 class ConstLinkedListIterator : public ListIterator<E> { 00641 private: 00642 00643 const LinkedList<E>* list; 00644 const ListNode<E>* current; 00645 const ListNode<E>* lastReturned; 00646 int index; 00647 00648 private: 00649 00650 ConstLinkedListIterator( const ConstLinkedListIterator& ); 00651 ConstLinkedListIterator operator= ( const ConstLinkedListIterator& ); 00652 00653 public: 00654 00655 ConstLinkedListIterator( const LinkedList<E>* list, int index ) : 00656 ListIterator<E>(), list(list), current(NULL), lastReturned(NULL), index(-1) { 00657 00658 if( list == NULL ) { 00659 throw decaf::lang::exceptions::NullPointerException( 00660 __FILE__, __LINE__, "Parent LinkedList pointer was Null." ); 00661 } 00662 00663 if( index < 0 || index > list->listSize ) { 00664 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00665 __FILE__, __LINE__, "Given index {%d} is out of range.", index ); 00666 } 00667 00668 // index starts at -1 to indicate that we are before begin or that the 00669 // list is empty. We always want to start out one before so that the call 00670 // to next moves us onto the element in question; 00671 00672 if( index < this->list->listSize / 2 ) { 00673 this->current = &this->list->head; 00674 for( this->index = -1; this->index + 1 < index; ++this->index ) { 00675 this->current = this->current->next; 00676 } 00677 } else { 00678 this->current = &this->list->tail; 00679 for( this->index = this->list->listSize; this->index >= index; --this->index ) { 00680 this->current = this->current->prev; 00681 } 00682 } 00683 } 00684 00685 virtual ~ConstLinkedListIterator() {} 00686 00687 virtual E next() { 00688 00689 if( this->current->next == &(this->list->tail) ) { 00690 throw NoSuchElementException( 00691 __FILE__, __LINE__, "No more elements to return from this ListIterator" ); 00692 } 00693 00694 this->current = this->current->next; 00695 this->lastReturned = this->current; 00696 this->index++; 00697 00698 return this->current->value; 00699 } 00700 00701 virtual bool hasNext() const { 00702 return ( this->current->next != &(this->list->tail) ); 00703 } 00704 00705 virtual E previous() { 00706 00707 if( this->current == &(this->list->head) ) { 00708 throw decaf::lang::exceptions::IllegalStateException( 00709 __FILE__, __LINE__, 00710 "No previous element, must call next() before calling previous()." ); 00711 } 00712 00713 this->lastReturned = this->current; 00714 this->current = this->current->prev; 00715 this->index--; 00716 00717 return this->lastReturned->value; 00718 } 00719 00720 virtual bool hasPrevious() const { 00721 return ( this->current != &(this->list->head) ); 00722 } 00723 00724 virtual void remove() { 00725 throw lang::exceptions::UnsupportedOperationException( 00726 __FILE__, __LINE__, "Cannot write to a const ListIterator." ); 00727 } 00728 00729 virtual void add( const E& e DECAF_UNUSED ) { 00730 throw lang::exceptions::UnsupportedOperationException( 00731 __FILE__, __LINE__, "Cannot write to a const ListIterator." ); 00732 } 00733 00734 virtual void set( const E& e DECAF_UNUSED ) { 00735 throw lang::exceptions::UnsupportedOperationException( 00736 __FILE__, __LINE__, "Cannot write to a const ListIterator." ); 00737 } 00738 00739 virtual int nextIndex() const { 00740 return this->index + 1; 00741 } 00742 00743 virtual int previousIndex() const { 00744 return this->index; 00745 } 00746 }; 00747 00748 class ReverseIterator : public Iterator<E> { 00749 private: 00750 00751 LinkedList<E>* list; 00752 ListNode<E>* current; 00753 int expectedModCount; 00754 bool canRemove; 00755 00756 private: 00757 00758 ReverseIterator( const ReverseIterator& ); 00759 ReverseIterator operator= ( const ReverseIterator& ); 00760 00761 public: 00762 00763 ReverseIterator( LinkedList<E>* list ) : 00764 Iterator<E>(), list( list ), current(NULL), expectedModCount(0), canRemove(false) { 00765 00766 if( list == NULL ) { 00767 throw decaf::lang::exceptions::NullPointerException( 00768 __FILE__, __LINE__, "Parent LinkedList pointer was Null." ); 00769 } 00770 00771 this->expectedModCount = this->list->modCount; 00772 this->current = &list->tail; 00773 } 00774 00775 virtual ~ReverseIterator() {} 00776 00777 virtual bool hasNext() const { 00778 return this->current->prev != &(this->list->head); 00779 } 00780 00781 virtual E next() { 00782 00783 if( this->expectedModCount != this->list->modCount ) { 00784 throw ConcurrentModificationException( 00785 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00786 } 00787 00788 if( this->current->prev == &(this->list->head) ) { 00789 throw NoSuchElementException( 00790 __FILE__, __LINE__, "No more elements to return from next()" ); 00791 } 00792 00793 this->current = this->current->prev; 00794 this->canRemove = true; 00795 00796 return this->current->value; 00797 } 00798 00799 virtual void remove() { 00800 if( this->expectedModCount != this->list->modCount ) { 00801 throw ConcurrentModificationException( 00802 __FILE__, __LINE__, "List modified outside of this Iterator." ); 00803 } 00804 00805 if( !this->canRemove ) { 00806 throw lang::exceptions::IllegalStateException( 00807 __FILE__, __LINE__, 00808 "Invalid State to call remove, must call next() before remove()" ); 00809 } 00810 00811 ListNode<E>* next = this->current->prev; 00812 ListNode<E>* prev = this->current->next; 00813 00814 next->next = prev; 00815 prev->prev = next; 00816 00817 delete this->current; 00818 00819 this->current = prev; 00820 00821 this->list->listSize--; 00822 this->list->modCount++; 00823 this->expectedModCount++; 00824 this->canRemove = false; 00825 } 00826 }; 00827 00828 class ConstReverseIterator : public Iterator<E> { 00829 private: 00830 00831 const LinkedList<E>* list; 00832 const ListNode<E>* current; 00833 00834 private: 00835 00836 ConstReverseIterator( const ConstReverseIterator& ); 00837 ConstReverseIterator operator= ( const ConstReverseIterator& ); 00838 00839 public: 00840 00841 ConstReverseIterator( const LinkedList<E>* list ) : 00842 Iterator<E>(), list( list ), current(NULL) { 00843 00844 if( list == NULL ) { 00845 throw decaf::lang::exceptions::NullPointerException( 00846 __FILE__, __LINE__, "Parent LinkedList pointer was Null." ); 00847 } 00848 00849 this->current = &list->tail; 00850 } 00851 00852 virtual ~ConstReverseIterator() {} 00853 00854 virtual bool hasNext() const { 00855 return this->current->prev != &(this->list->head); 00856 } 00857 00858 virtual E next() { 00859 00860 if( this->current->prev == &(this->list->head) ) { 00861 throw NoSuchElementException( 00862 __FILE__, __LINE__, "No more elements to return from next()" ); 00863 } 00864 00865 this->current = this->current->prev; 00866 00867 return this->current->value; 00868 } 00869 00870 virtual void remove() { 00871 throw lang::exceptions::UnsupportedOperationException( 00872 __FILE__, __LINE__, "Cannot write to a const Iterator." ); 00873 } 00874 }; 00875 00876 public: 00877 00878 using AbstractSequentialList<E>::listIterator; 00879 00880 virtual ListIterator<E>* listIterator( int index ) { 00881 return new LinkedListIterator( this, index ); 00882 } 00883 virtual ListIterator<E>* listIterator( int index ) const { 00884 return new ConstLinkedListIterator( this, index ); 00885 } 00886 00887 virtual Iterator<E>* descendingIterator() { 00888 return new ReverseIterator( this ); 00889 } 00890 virtual Iterator<E>* descendingIterator() const { 00891 return new ConstReverseIterator( this ); 00892 } 00893 00894 private: 00895 00896 E removeAtFront() { 00897 00898 if( this->head.next == &this->tail ) { 00899 throw NoSuchElementException( 00900 __FILE__, __LINE__, "The Collection is empty." ); 00901 } 00902 00903 ListNode<E>* oldNode = this->head.next; 00904 E result = oldNode->value; 00905 00906 this->head.next = oldNode->next; 00907 this->head.next->prev = &this->head; 00908 00909 delete oldNode; 00910 00911 this->listSize--; 00912 AbstractList<E>::modCount++; 00913 00914 return result; 00915 } 00916 00917 E removeAtEnd() { 00918 00919 if( this->head.next == &this->tail ) { 00920 throw NoSuchElementException( 00921 __FILE__, __LINE__, "The Collection is empty." ); 00922 } 00923 00924 ListNode<E>* oldNode = this->tail.prev; 00925 E result = oldNode->value; 00926 00927 this->tail.prev = oldNode->prev; 00928 this->tail.prev->next = &this->tail; 00929 00930 delete oldNode; 00931 00932 this->listSize--; 00933 AbstractList<E>::modCount++; 00934 00935 return result; 00936 } 00937 00938 void addToFront( const E& value ) { 00939 00940 ListNode<E>* newHead = new ListNode<E>( &this->head, this->head.next, value ); 00941 00942 (this->head.next)->prev = newHead; 00943 this->head.next = newHead; 00944 00945 this->listSize++; 00946 AbstractList<E>::modCount++; 00947 } 00948 00949 void addToEnd( const E& value ) { 00950 00951 ListNode<E>* newTail = new ListNode<E>( this->tail.prev, &this->tail, value ); 00952 00953 (this->tail.prev)->next = newTail; 00954 this->tail.prev = newTail; 00955 00956 this->listSize++; 00957 AbstractList<E>::modCount++; 00958 } 00959 00960 void addAtLocation( int index, const E& value ) { 00961 00962 ListNode<E>* location = NULL; 00963 00964 if( index <= this->listSize / 2 ) { 00965 location = this->head.next; 00966 for( int i = 0; i < index; ++i ) { 00967 location = location->next; 00968 } 00969 } else { 00970 location = &this->tail; 00971 for( int i = this->listSize; i > index; --i ) { 00972 location = location->prev; 00973 } 00974 } 00975 00976 ListNode<E>* newNode = new ListNode<E>( location->prev, location, value ); 00977 00978 (location->prev)->next = newNode; 00979 location->prev = newNode; 00980 00981 this->listSize++; 00982 AbstractList<E>::modCount++; 00983 } 00984 00985 bool addAllAtLocation( int index, const Collection<E>& collection ) { 00986 00987 if( index < 0 || index > this->listSize ) { 00988 throw decaf::lang::exceptions::IndexOutOfBoundsException( 00989 __FILE__, __LINE__, "Index for add is outside bounds of this LinkedList." ); 00990 } 00991 00992 int csize = collection.size(); 00993 if( csize == 0 ) { 00994 return false; 00995 } 00996 00997 std::auto_ptr< ArrayList<E> > copy; 00998 std::auto_ptr< Iterator<E> > iter; 00999 01000 if( this == &collection ) { 01001 copy.reset( new ArrayList<E>( collection ) ); 01002 iter.reset( copy->iterator() ); 01003 } else { 01004 iter.reset( collection.iterator() ); 01005 } 01006 01007 ListNode<E>* newNode = NULL; 01008 ListNode<E>* previous = NULL; 01009 01010 if( index < this->listSize / 2 ) { 01011 previous = &this->head; 01012 for( int i = 0; i < index; ++i ) { 01013 previous = previous->next; 01014 } 01015 } else { 01016 previous = &this->tail; 01017 for( int i = this->listSize; i >= index; --i ) { 01018 previous = previous->prev; 01019 } 01020 } 01021 01022 while( iter->hasNext() ) { 01023 newNode = new ListNode<E>( previous, previous->next, iter->next() ); 01024 previous->next->prev = newNode; 01025 previous->next = newNode; 01026 previous = newNode; 01027 } 01028 01029 this->listSize += csize; 01030 AbstractList<E>::modCount++; 01031 01032 return true; 01033 } 01034 01035 void purgeList() { 01036 ListNode<E>* current = this->head.next; 01037 ListNode<E>* temp = NULL; 01038 while( current != &this->tail ) { 01039 temp = current; 01040 current = current->next; 01041 delete temp; 01042 } 01043 } 01044 }; 01045 01046 }} 01047 01048 #endif /* _DECAF_UTIL_LINKEDLIST_H_ */