18 #ifndef _DECAF_UTIL_LINKEDLIST_H_
19 #define _DECAF_UTIL_LINKEDLIST_H_
54 template<
typename E >
58 template<
typename U >
68 ListNode(
const ListNode&);
73 ListNode() : value(), prev(
NULL), next(
NULL) {}
75 ListNode(
const U& value) : value(value), prev(
NULL), next(
NULL) {}
77 ListNode(ListNode<U>* prev, ListNode<U>* next,
const U& value) :
78 value(value), prev(prev), next(next) {
93 this->head.next = &this->tail;
94 this->tail.prev = &this->head;
99 this->head.next = &this->tail;
100 this->tail.prev = &this->head;
102 this->addAllAtLocation(0, list);
107 this->head.next = &this->tail;
108 this->tail.prev = &this->head;
110 this->addAllAtLocation(0, collection);
123 this->addAllAtLocation(0, list);
129 this->addAllAtLocation(0, collection);
135 virtual E
get(
int index)
const {
137 if (index < 0 || index >= this->listSize) {
139 __FILE__, __LINE__,
"Index given is outside bounds of this list {%d}", index );
142 const ListNode<E>* location =
NULL;
144 if (index < this->listSize / 2) {
145 location = &this->head;
146 for (
int i = 0; i <= index; ++i) {
147 location = location->next;
150 location = &this->tail;
151 for (
int i = this->listSize; i > index; --i) {
152 location = location->prev;
156 return location->value;
161 if (index < 0 || index >= this->listSize) {
163 __FILE__, __LINE__,
"Index given is outside bounds of this list {%d}", index );
166 ListNode<E>* location =
NULL;
168 if (index < this->listSize / 2) {
169 location = &this->head;
170 for (
int i = 0; i <= index; ++i) {
171 location = location->next;
174 location = &this->tail;
175 for (
int i = this->listSize; i > index; --i) {
176 location = location->prev;
180 E oldValue = location->value;
186 virtual bool add(
const E& value) {
187 this->addToEnd(value);
191 virtual void add(
int index,
const E& value) {
193 if (index < 0 || index > this->listSize) {
195 __FILE__, __LINE__,
"Index given is outside bounds of this list {%d}", index );
198 this->addAtLocation(index, value);
202 return this->addAllAtLocation(this->listSize, collection);
206 return this->addAllAtLocation(index, collection);
211 this->addAllAtLocation(0, collection);
214 virtual bool remove(
const E& value) {
219 return this->listSize == 0;
223 return this->listSize;
228 this->head.next = &this->tail;
229 this->tail.prev = &this->head;
235 return this->
indexOf(value) != -1;
240 if (this->listSize == 0) {
244 const ListNode<E>* location = this->head.next;
246 for (
int i = 0; location != &this->tail; ++i, location = location->next) {
247 if (location->value == value) {
257 if (this->listSize == 0) {
261 const ListNode<E>* location = this->tail.prev;
263 for (
int i = this->listSize - 1; location != &this->head; --i, location = location->prev) {
264 if (location->value == value) {
274 std::vector<E> result;
275 result.reserve(this->listSize);
277 const ListNode<E>* current = this->head.next;
279 while (current != &this->tail) {
280 result.push_back(current->value);
281 current = current->next;
289 virtual bool offer(
const E& value) {
296 if (this->listSize == 0) {
300 result = this->head.next->value;
301 this->removeAtFront();
306 return this->removeAtFront();
309 virtual bool peek(E& result)
const {
311 if (this->listSize == 0) {
315 result = this->head.next->value;
320 if (this->listSize == 0) {
324 return this->head.next->value;
328 this->addToFront(value);
332 this->addToEnd(value);
336 if (this->listSize == 0) {
340 return this->head.next->value;
344 if (this->listSize == 0) {
348 return this->head.next->value;
352 if (this->listSize == 0) {
356 return this->tail.prev->value;
360 if (this->listSize == 0) {
364 return this->tail.prev->value;
368 this->addToFront(element);
373 this->addToEnd(element);
378 return this->removeAtFront();
382 return this->removeAtEnd();
386 if (this->listSize == 0) {
390 result = this->head.next->value;
391 this->removeAtFront();
396 if (this->listSize == 0) {
400 result = this->tail.prev->value;
406 if (this->listSize == 0) {
410 result = this->head.next->value;
415 if (this->listSize == 0) {
419 result = this->tail.prev->value;
424 return this->removeAtFront();
428 this->addToFront(element);
432 std::auto_ptr<Iterator<E> > iter(this->
iterator());
433 while (iter->hasNext()) {
434 if (iter->next() == value) {
445 while (iter->hasNext()) {
446 if (iter->next() == value) {
461 ListNode<E>* current;
462 ListNode<E>* lastReturned;
464 int expectedModCount;
468 LinkedListIterator(
const LinkedListIterator&);
469 LinkedListIterator
operator=(
const LinkedListIterator&);
474 ListIterator<E>(), list(list), current(
NULL), lastReturned(
NULL), index(-1), expectedModCount(0) {
478 __FILE__, __LINE__,
"Parent LinkedList pointer was Null." );
481 if (index < 0 || index > list->listSize) {
483 __FILE__, __LINE__,
"Given index {%d} is out of range.", index );
486 this->expectedModCount = list->
modCount;
492 if (index < this->list->listSize / 2) {
493 this->current = &this->list->head;
494 for (this->index = -1; this->index + 1 < index; ++this->index) {
495 this->current = this->current->next;
498 this->current = &this->list->tail;
499 for (this->index = this->list->listSize; this->index >= index; --this->index) {
500 this->current = this->current->prev;
505 virtual ~LinkedListIterator() {}
509 if (this->expectedModCount != this->list->
modCount) {
510 throw ConcurrentModificationException(
511 __FILE__, __LINE__,
"List modified outside of this Iterator." );
514 if (this->current->next == &(this->list->tail)) {
515 throw NoSuchElementException(
516 __FILE__, __LINE__,
"No more elements to return from next()" );
519 this->current = this->current->next;
520 this->lastReturned = this->current;
523 return this->current->value;
526 virtual bool hasNext()
const {
527 return (this->current->next != &this->list->tail);
531 virtual E previous() {
532 if (this->expectedModCount != this->list->
modCount) {
533 throw ConcurrentModificationException(
534 __FILE__, __LINE__,
"List modified outside of this Iterator." );
537 if (this->current == &(this->list->head)) {
540 "No previous element, must call next() before calling previous()." );
543 this->lastReturned = this->current;
544 this->current = this->current->prev;
547 return this->lastReturned->value;
550 virtual bool hasPrevious()
const {
551 return (this->current != &this->list->head);
554 virtual void remove() {
555 if (this->expectedModCount != this->list->
modCount) {
556 throw ConcurrentModificationException(
557 __FILE__, __LINE__,
"List modified outside of this Iterator." );
560 if (this->lastReturned ==
NULL) {
561 throw lang::exceptions::IllegalStateException(
563 "Invalid State to call remove, must call next() before remove()" );
566 ListNode<E>* next = this->lastReturned->next;
567 ListNode<E>* previous = this->lastReturned->prev;
569 next->prev = previous;
570 previous->next = next;
573 if (this->current == this->lastReturned) {
576 this->current = previous;
578 delete this->lastReturned;
579 this->lastReturned =
NULL;
581 this->list->listSize--;
584 this->expectedModCount++;
587 virtual void add(
const E& e) {
588 if (this->expectedModCount != this->list->
modCount) {
589 throw ConcurrentModificationException(
590 __FILE__, __LINE__,
"List modified outside of this Iterator." );
593 ListNode<E>* newNode =
new ListNode<E>( this->current, this->current->next, e );
595 this->current->next->prev = newNode;
596 this->current->next = newNode;
598 this->current = newNode;
599 this->lastReturned =
NULL;
602 this->expectedModCount++;
604 this->list->listSize++;
607 virtual void set(
const E& e) {
609 if (this->expectedModCount != this->list->
modCount) {
610 throw ConcurrentModificationException(
611 __FILE__, __LINE__,
"List modified outside of this Iterator." );
614 if (this->lastReturned !=
NULL) {
615 this->lastReturned->value = e;
618 __FILE__, __LINE__,
"Iterator next has not been called." );
622 virtual int nextIndex()
const {
623 return this->index + 1;
626 virtual int previousIndex()
const {
631 class ConstLinkedListIterator :
public ListIterator<E> {
634 const LinkedList<E>* list;
635 const ListNode<E>* current;
636 const ListNode<E>* lastReturned;
641 ConstLinkedListIterator(
const ConstLinkedListIterator&);
642 ConstLinkedListIterator
operator=(
const ConstLinkedListIterator&);
646 ConstLinkedListIterator(
const LinkedList<E>* list,
int index) :
647 ListIterator<E>(), list(list), current(
NULL), lastReturned(
NULL), index(-1) {
651 __FILE__, __LINE__,
"Parent LinkedList pointer was Null." );
654 if (index < 0 || index > list->listSize) {
656 __FILE__, __LINE__,
"Given index {%d} is out of range.", index );
663 if (index < this->list->listSize / 2) {
664 this->current = &this->list->head;
665 for (this->index = -1; this->index + 1 < index; ++this->index) {
666 this->current = this->current->next;
669 this->current = &this->list->tail;
670 for (this->index = this->list->listSize; this->index >= index; --this->index) {
671 this->current = this->current->prev;
676 virtual ~ConstLinkedListIterator() {}
680 if (this->current->next == &(this->list->tail)) {
681 throw NoSuchElementException(
682 __FILE__, __LINE__,
"No more elements to return from this ListIterator" );
685 this->current = this->current->next;
686 this->lastReturned = this->current;
689 return this->current->value;
692 virtual bool hasNext()
const {
693 return (this->current->next != &(this->list->tail));
696 virtual E previous() {
698 if (this->current == &(this->list->head)) {
701 "No previous element, must call next() before calling previous()." );
704 this->lastReturned = this->current;
705 this->current = this->current->prev;
708 return this->lastReturned->value;
711 virtual bool hasPrevious()
const {
712 return (this->current != &(this->list->head));
715 virtual void remove() {
716 throw lang::exceptions::UnsupportedOperationException(
717 __FILE__, __LINE__,
"Cannot write to a const ListIterator." );
721 throw lang::exceptions::UnsupportedOperationException(
722 __FILE__, __LINE__,
"Cannot write to a const ListIterator." );
726 throw lang::exceptions::UnsupportedOperationException(
727 __FILE__, __LINE__,
"Cannot write to a const ListIterator." );
730 virtual int nextIndex()
const {
731 return this->index + 1;
734 virtual int previousIndex()
const {
739 class ReverseIterator :
public Iterator<E> {
743 ListNode<E>* current;
744 int expectedModCount;
749 ReverseIterator(
const ReverseIterator&);
750 ReverseIterator
operator=(
const ReverseIterator&);
754 ReverseIterator(LinkedList<E>* list) :
755 Iterator<E>(), list(list), current(
NULL), expectedModCount(0), canRemove(false) {
759 __FILE__, __LINE__,
"Parent LinkedList pointer was Null." );
762 this->expectedModCount = this->list->modCount;
763 this->current = &list->tail;
766 virtual ~ReverseIterator() {}
768 virtual bool hasNext()
const {
769 return this->current->prev != &(this->list->head);
774 if (this->expectedModCount != this->list->modCount) {
775 throw ConcurrentModificationException(
776 __FILE__, __LINE__,
"List modified outside of this Iterator." );
779 if (this->current->prev == &(this->list->head)) {
780 throw NoSuchElementException(
781 __FILE__, __LINE__,
"No more elements to return from next()" );
784 this->current = this->current->prev;
785 this->canRemove =
true;
787 return this->current->value;
790 virtual void remove() {
791 if (this->expectedModCount != this->list->modCount) {
792 throw ConcurrentModificationException(
793 __FILE__, __LINE__,
"List modified outside of this Iterator." );
796 if (!this->canRemove) {
797 throw lang::exceptions::IllegalStateException(
799 "Invalid State to call remove, must call next() before remove()" );
802 ListNode<E>* next = this->current->prev;
803 ListNode<E>* prev = this->current->next;
808 delete this->current;
810 this->current = prev;
812 this->list->listSize--;
813 this->list->modCount++;
814 this->expectedModCount++;
815 this->canRemove =
false;
819 class ConstReverseIterator :
public Iterator<E> {
822 const LinkedList<E>* list;
823 const ListNode<E>* current;
827 ConstReverseIterator(
const ConstReverseIterator&);
828 ConstReverseIterator
operator=(
const ConstReverseIterator&);
832 ConstReverseIterator(
const LinkedList<E>* list) : Iterator<E>(), list(list), current(
NULL) {
836 __FILE__, __LINE__,
"Parent LinkedList pointer was Null." );
839 this->current = &list->tail;
842 virtual ~ConstReverseIterator() {}
844 virtual bool hasNext()
const {
845 return this->current->prev != &(this->list->head);
850 if (this->current->prev == &(this->list->head)) {
851 throw NoSuchElementException(
852 __FILE__, __LINE__,
"No more elements to return from next()" );
855 this->current = this->current->prev;
857 return this->current->value;
860 virtual void remove() {
861 throw lang::exceptions::UnsupportedOperationException(
862 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
868 using AbstractSequentialList<E>::listIterator;
871 return new LinkedListIterator(
this, index);
874 return new ConstLinkedListIterator(
this, index);
878 return new ReverseIterator(
this);
881 return new ConstReverseIterator(
this);
888 if (this->head.next == &this->tail) {
890 __FILE__, __LINE__,
"The Collection is empty." );
893 ListNode<E>* oldNode = this->head.next;
894 E result = oldNode->value;
896 this->head.next = oldNode->next;
897 this->head.next->prev = &this->head;
902 AbstractList<E>::modCount++;
909 if (this->head.next == &this->tail) {
910 throw NoSuchElementException(
911 __FILE__, __LINE__,
"The Collection is empty." );
914 ListNode<E>* oldNode = this->tail.prev;
915 E result = oldNode->value;
917 this->tail.prev = oldNode->prev;
918 this->tail.prev->next = &this->tail;
923 AbstractList<E>::modCount++;
928 void addToFront(
const E& value) {
930 ListNode<E>* newHead =
new ListNode<E> (&this->head, this->head.next, value);
932 (this->head.next)->prev = newHead;
933 this->head.next = newHead;
936 AbstractList<E>::modCount++;
939 void addToEnd(
const E& value) {
941 ListNode<E>* newTail =
new ListNode<E> (this->tail.prev, &this->tail, value);
943 (this->tail.prev)->next = newTail;
944 this->tail.prev = newTail;
947 AbstractList<E>::modCount++;
950 void addAtLocation(
int index,
const E& value) {
952 ListNode<E>* location =
NULL;
954 if (index <= this->listSize / 2) {
955 location = this->head.next;
956 for (
int i = 0; i < index; ++i) {
957 location = location->next;
960 location = &this->tail;
961 for (
int i = this->listSize; i > index; --i) {
962 location = location->prev;
966 ListNode<E>* newNode =
new ListNode<E> (location->prev, location, value);
968 (location->prev)->next = newNode;
969 location->prev = newNode;
972 AbstractList<E>::modCount++;
975 bool addAllAtLocation(
int index,
const Collection<E>& collection) {
977 if (index < 0 || index > this->listSize) {
979 __FILE__, __LINE__,
"Index for add is outside bounds of this LinkedList." );
982 int csize = collection.size();
987 std::auto_ptr<ArrayList<E> >
copy;
988 std::auto_ptr<Iterator<E> > iter;
990 if (
this == &collection) {
991 copy.reset(
new ArrayList<E> (collection));
992 iter.reset(copy->iterator());
994 iter.reset(collection.iterator());
997 ListNode<E>* newNode =
NULL;
998 ListNode<E>* previous =
NULL;
1000 if (index < this->listSize / 2) {
1001 previous = &this->head;
1002 for (
int i = 0; i < index; ++i) {
1003 previous = previous->next;
1006 previous = &this->tail;
1007 for (
int i = this->listSize; i >= index; --i) {
1008 previous = previous->prev;
1012 while (iter->hasNext()) {
1013 newNode =
new ListNode<E> (previous, previous->next, iter->next());
1014 previous->next->prev = newNode;
1015 previous->next = newNode;
1019 this->listSize += csize;
1020 AbstractList<E>::modCount++;
1026 ListNode<E>* current = this->head.next;
1027 ListNode<E>* temp =
NULL;
1028 while (current != &this->tail) {
1030 current = current->next;