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