activemq-cpp-3.6.0
LinkedList.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _DECAF_UTIL_LINKEDLIST_H_
19 #define _DECAF_UTIL_LINKEDLIST_H_
20 
21 #include <list>
22 #include <memory>
26 #include <decaf/lang/System.h>
27 #include <decaf/lang/Integer.h>
28 #include <decaf/util/Config.h>
29 #include <decaf/util/Deque.h>
30 #include <decaf/util/ArrayList.h>
31 #include <decaf/util/Iterator.h>
34 
35 namespace decaf {
36 namespace util {
37 
38  using decaf::lang::System;
39 
54  template< typename E >
55  class LinkedList : public AbstractSequentialList<E>, public Deque<E> {
56  private:
57 
58  template< typename U >
59  class ListNode {
60  public:
61 
62  U value;
63  ListNode<U>* prev;
64  ListNode<U>* next;
65 
66  private:
67 
68  ListNode(const ListNode&);
69  ListNode& operator=(const ListNode&);
70 
71  public:
72 
73  ListNode() : value(), prev(NULL), next(NULL) {}
74 
75  ListNode(const U& value) : value(value), prev(NULL), next(NULL) {}
76 
77  ListNode(ListNode<U>* prev, ListNode<U>* next, const U& value) :
78  value(value), prev(prev), next(next) {
79  }
80 
81  };
82 
83  private:
84 
85  int listSize;
86  ListNode<E> head;
87  ListNode<E> tail;
88 
89  public:
90 
91  LinkedList() : AbstractSequentialList<E>(), listSize(0), head(), tail() {
92 
93  this->head.next = &this->tail;
94  this->tail.prev = &this->head;
95  }
96 
97  LinkedList(const LinkedList<E>& list) : AbstractSequentialList<E>(), listSize(0), head(), tail() {
98 
99  this->head.next = &this->tail;
100  this->tail.prev = &this->head;
101 
102  this->addAllAtLocation(0, list);
103  }
104 
105  LinkedList(const Collection<E>& collection) : AbstractSequentialList<E>(), listSize(0), head(), tail() {
106 
107  this->head.next = &this->tail;
108  this->tail.prev = &this->head;
109 
110  this->addAllAtLocation(0, collection);
111  }
112 
113  virtual ~LinkedList() {
114  try{
115  this->purgeList();
116  } catch(...) {}
117  }
118 
119  public:
120 
122  this->clear();
123  this->addAllAtLocation(0, list);
124  return *this;
125  }
126 
127  LinkedList<E>& operator=(const Collection<E>& collection) {
128  this->clear();
129  this->addAllAtLocation(0, collection);
130  return *this;
131  }
132 
133  public:
134 
135  virtual E get(int index) const {
136 
137  if (index < 0 || index >= this->listSize) {
139  __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index );
140  }
141 
142  const ListNode<E>* location = NULL;
143 
144  if (index < this->listSize / 2) {
145  location = &this->head;
146  for (int i = 0; i <= index; ++i) {
147  location = location->next;
148  }
149  } else {
150  location = &this->tail;
151  for (int i = this->listSize; i > index; --i) {
152  location = location->prev;
153  }
154  }
155 
156  return location->value;
157  }
158 
159  virtual E set(int index, const E& element) {
160 
161  if (index < 0 || index >= this->listSize) {
163  __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index );
164  }
165 
166  ListNode<E>* location = NULL;
167 
168  if (index < this->listSize / 2) {
169  location = &this->head;
170  for (int i = 0; i <= index; ++i) {
171  location = location->next;
172  }
173  } else {
174  location = &this->tail;
175  for (int i = this->listSize; i > index; --i) {
176  location = location->prev;
177  }
178  }
179 
180  E oldValue = location->value;
181  location->value = element;
182 
183  return oldValue;
184  }
185 
186  virtual bool add(const E& value) {
187  this->addToEnd(value);
188  return true;
189  }
190 
191  virtual void add(int index, const E& value) {
192 
193  if (index < 0 || index > this->listSize) {
195  __FILE__, __LINE__, "Index given is outside bounds of this list {%d}", index );
196  }
197 
198  this->addAtLocation(index, value);
199  }
200 
201  virtual bool addAll(const Collection<E>& collection) {
202  return this->addAllAtLocation(this->listSize, collection);
203  }
204 
205  virtual bool addAll(int index, const Collection<E>& collection) {
206  return this->addAllAtLocation(index, collection);
207  }
208 
209  virtual void copy(const Collection<E>& collection) {
210  this->clear();
211  this->addAllAtLocation(0, collection);
212  }
213 
214  virtual bool remove(const E& value) {
215  return this->removeFirstOccurrence(value);
216  }
217 
218  virtual bool isEmpty() const {
219  return this->listSize == 0;
220  }
221 
222  virtual int size() const {
223  return this->listSize;
224  }
225 
226  virtual void clear() {
227  this->purgeList();
228  this->head.next = &this->tail;
229  this->tail.prev = &this->head;
230  this->listSize = 0;
232  }
233 
234  virtual bool contains(const E& value) const {
235  return this->indexOf(value) != -1;
236  }
237 
238  virtual int indexOf(const E& value) const {
239 
240  if (this->listSize == 0) {
241  return -1;
242  }
243 
244  const ListNode<E>* location = this->head.next;
245 
246  for (int i = 0; location != &this->tail; ++i, location = location->next) {
247  if (location->value == value) {
248  return i;
249  }
250  }
251 
252  return -1;
253  }
254 
255  virtual int lastIndexOf(const E& value) const {
256 
257  if (this->listSize == 0) {
258  return -1;
259  }
260 
261  const ListNode<E>* location = this->tail.prev;
262 
263  for (int i = this->listSize - 1; location != &this->head; --i, location = location->prev) {
264  if (location->value == value) {
265  return i;
266  }
267  }
268 
269  return -1;
270  }
271 
272  virtual std::vector<E> toArray() const {
273 
274  std::vector<E> result;
275  result.reserve(this->listSize);
276 
277  const ListNode<E>* current = this->head.next;
278 
279  while (current != &this->tail) {
280  result.push_back(current->value);
281  current = current->next;
282  }
283 
284  return result;
285  }
286 
287  public: // Deque interface implementation.
288 
289  virtual bool offer(const E& value) {
290  this->addLast(value);
291  return true;
292  }
293 
294  virtual bool poll(E& result) {
295 
296  if (this->listSize == 0) {
297  return false;
298  }
299 
300  result = this->head.next->value;
301  this->removeAtFront();
302  return true;
303  }
304 
305  virtual E remove() {
306  return this->removeAtFront();
307  }
308 
309  virtual bool peek(E& result) const {
310 
311  if (this->listSize == 0) {
312  return false;
313  }
314 
315  result = this->head.next->value;
316  return true;
317  }
318 
319  virtual E element() const {
320  if (this->listSize == 0) {
321  throw decaf::util::NoSuchElementException(__FILE__, __LINE__, "The list is Empty");
322  }
323 
324  return this->head.next->value;
325  }
326 
327  virtual void addFirst(const E& value) {
328  this->addToFront(value);
329  }
330 
331  virtual void addLast(const E& value) {
332  this->addToEnd(value);
333  }
334 
335  virtual E& getFirst() {
336  if (this->listSize == 0) {
337  throw decaf::util::NoSuchElementException(__FILE__, __LINE__, "The list is Empty");
338  }
339 
340  return this->head.next->value;
341  }
342 
343  virtual const E& getFirst() const {
344  if (this->listSize == 0) {
345  throw decaf::util::NoSuchElementException(__FILE__, __LINE__, "The list is Empty");
346  }
347 
348  return this->head.next->value;
349  }
350 
351  virtual E& getLast() {
352  if (this->listSize == 0) {
353  throw decaf::util::NoSuchElementException(__FILE__, __LINE__, "The list is Empty");
354  }
355 
356  return this->tail.prev->value;
357  }
358 
359  virtual const E& getLast() const {
360  if (this->listSize == 0) {
361  throw decaf::util::NoSuchElementException(__FILE__, __LINE__, "The list is Empty");
362  }
363 
364  return this->tail.prev->value;
365  }
366 
367  virtual bool offerFirst(const E& element) {
368  this->addToFront(element);
369  return true;
370  }
371 
372  virtual bool offerLast(const E& element) {
373  this->addToEnd(element);
374  return true;
375  }
376 
377  virtual E removeFirst() {
378  return this->removeAtFront();
379  }
380 
381  virtual E removeLast() {
382  return this->removeAtEnd();
383  }
384 
385  virtual bool pollFirst(E& result) {
386  if (this->listSize == 0) {
387  return false;
388  }
389 
390  result = this->head.next->value;
391  this->removeAtFront();
392  return true;
393  }
394 
395  virtual bool pollLast(E& result) {
396  if (this->listSize == 0) {
397  return false;
398  }
399 
400  result = this->tail.prev->value;
401  this->removeAtEnd();
402  return true;
403  }
404 
405  virtual bool peekFirst(E& result) const {
406  if (this->listSize == 0) {
407  return false;
408  }
409 
410  result = this->head.next->value;
411  return true;
412  }
413 
414  virtual bool peekLast(E& result) const {
415  if (this->listSize == 0) {
416  return false;
417  }
418 
419  result = this->tail.prev->value;
420  return true;
421  }
422 
423  virtual E pop() {
424  return this->removeAtFront();
425  }
426 
427  virtual void push(const E& element) {
428  this->addToFront(element);
429  }
430 
431  virtual bool removeFirstOccurrence(const E& value) {
432  std::auto_ptr<Iterator<E> > iter(this->iterator());
433  while (iter->hasNext()) {
434  if (iter->next() == value) {
435  iter->remove();
436  return true;
437  }
438  }
439 
440  return false;
441  }
442 
443  virtual bool removeLastOccurrence(const E& value) {
444  std::auto_ptr<Iterator<E> > iter(this->descendingIterator());
445  while (iter->hasNext()) {
446  if (iter->next() == value) {
447  iter->remove();
448  return true;
449  }
450  }
451 
452  return false;
453  }
454 
455  private:
456 
457  class LinkedListIterator : public ListIterator<E> {
458  private:
459 
460  mutable LinkedList<E>* list;
461  ListNode<E>* current;
462  ListNode<E>* lastReturned;
463  int index;
464  int expectedModCount;
465 
466  private:
467 
468  LinkedListIterator(const LinkedListIterator&);
469  LinkedListIterator operator=(const LinkedListIterator&);
470 
471  public:
472 
473  LinkedListIterator(LinkedList<E>* list, int index) :
474  ListIterator<E>(), list(list), current(NULL), lastReturned(NULL), index(-1), expectedModCount(0) {
475 
476  if (list == NULL) {
478  __FILE__, __LINE__, "Parent LinkedList pointer was Null." );
479  }
480 
481  if (index < 0 || index > list->listSize) {
483  __FILE__, __LINE__, "Given index {%d} is out of range.", index );
484  }
485 
486  this->expectedModCount = list->modCount;
487 
488  // index starts at -1 to indicate that we are before begin or that the
489  // list is empty. We always want to start out one before so that the call
490  // to next moves us onto the element in question;
491 
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;
496  }
497  } else {
498  this->current = &this->list->tail;
499  for (this->index = this->list->listSize; this->index >= index; --this->index) {
500  this->current = this->current->prev;
501  }
502  }
503  }
504 
505  virtual ~LinkedListIterator() {}
506 
507  virtual E next() {
508 
509  if (this->expectedModCount != this->list->modCount) {
510  throw ConcurrentModificationException(
511  __FILE__, __LINE__, "List modified outside of this Iterator." );
512  }
513 
514  if (this->current->next == &(this->list->tail)) {
515  throw NoSuchElementException(
516  __FILE__, __LINE__, "No more elements to return from next()" );
517  }
518 
519  this->current = this->current->next;
520  this->lastReturned = this->current;
521  this->index++;
522 
523  return this->current->value;
524  }
525 
526  virtual bool hasNext() const {
527  return (this->current->next != &this->list->tail);
528  }
529 
530 
531  virtual E previous() {
532  if (this->expectedModCount != this->list->modCount) {
533  throw ConcurrentModificationException(
534  __FILE__, __LINE__, "List modified outside of this Iterator." );
535  }
536 
537  if (this->current == &(this->list->head)) {
539  __FILE__, __LINE__,
540  "No previous element, must call next() before calling previous()." );
541  }
542 
543  this->lastReturned = this->current;
544  this->current = this->current->prev;
545  this->index--;
546 
547  return this->lastReturned->value;
548  }
549 
550  virtual bool hasPrevious() const {
551  return (this->current != &this->list->head);
552  }
553 
554  virtual void remove() {
555  if (this->expectedModCount != this->list->modCount) {
556  throw ConcurrentModificationException(
557  __FILE__, __LINE__, "List modified outside of this Iterator." );
558  }
559 
560  if (this->lastReturned == NULL) {
561  throw lang::exceptions::IllegalStateException(
562  __FILE__, __LINE__,
563  "Invalid State to call remove, must call next() before remove()" );
564  }
565 
566  ListNode<E>* next = this->lastReturned->next;
567  ListNode<E>* previous = this->lastReturned->prev;
568 
569  next->prev = previous;
570  previous->next = next;
571 
572  // When iterating in reverse this would not be true
573  if (this->current == this->lastReturned) {
574  this->index--;
575  }
576  this->current = previous;
577 
578  delete this->lastReturned;
579  this->lastReturned = NULL;
580 
581  this->list->listSize--;
582  this->list->modCount++;
583 
584  this->expectedModCount++;
585  }
586 
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." );
591  }
592 
593  ListNode<E>* newNode = new ListNode<E>( this->current, this->current->next, e );
594 
595  this->current->next->prev = newNode;
596  this->current->next = newNode;
597 
598  this->current = newNode;
599  this->lastReturned = NULL;
600 
601  this->index++;
602  this->expectedModCount++;
603  this->list->modCount++;
604  this->list->listSize++;
605  }
606 
607  virtual void set(const E& e) {
608 
609  if (this->expectedModCount != this->list->modCount) {
610  throw ConcurrentModificationException(
611  __FILE__, __LINE__, "List modified outside of this Iterator." );
612  }
613 
614  if (this->lastReturned != NULL) {
615  this->lastReturned->value = e;
616  } else {
618  __FILE__, __LINE__, "Iterator next has not been called." );
619  }
620  }
621 
622  virtual int nextIndex() const {
623  return this->index + 1;
624  }
625 
626  virtual int previousIndex() const {
627  return this->index;
628  }
629  };
630 
631  class ConstLinkedListIterator : public ListIterator<E> {
632  private:
633 
634  const LinkedList<E>* list;
635  const ListNode<E>* current;
636  const ListNode<E>* lastReturned;
637  int index;
638 
639  private:
640 
641  ConstLinkedListIterator(const ConstLinkedListIterator&);
642  ConstLinkedListIterator operator=(const ConstLinkedListIterator&);
643 
644  public:
645 
646  ConstLinkedListIterator(const LinkedList<E>* list, int index) :
647  ListIterator<E>(), list(list), current(NULL), lastReturned(NULL), index(-1) {
648 
649  if (list == NULL) {
651  __FILE__, __LINE__, "Parent LinkedList pointer was Null." );
652  }
653 
654  if (index < 0 || index > list->listSize) {
656  __FILE__, __LINE__, "Given index {%d} is out of range.", index );
657  }
658 
659  // index starts at -1 to indicate that we are before begin or that the
660  // list is empty. We always want to start out one before so that the call
661  // to next moves us onto the element in question;
662 
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;
667  }
668  } else {
669  this->current = &this->list->tail;
670  for (this->index = this->list->listSize; this->index >= index; --this->index) {
671  this->current = this->current->prev;
672  }
673  }
674  }
675 
676  virtual ~ConstLinkedListIterator() {}
677 
678  virtual E next() {
679 
680  if (this->current->next == &(this->list->tail)) {
681  throw NoSuchElementException(
682  __FILE__, __LINE__, "No more elements to return from this ListIterator" );
683  }
684 
685  this->current = this->current->next;
686  this->lastReturned = this->current;
687  this->index++;
688 
689  return this->current->value;
690  }
691 
692  virtual bool hasNext() const {
693  return (this->current->next != &(this->list->tail));
694  }
695 
696  virtual E previous() {
697 
698  if (this->current == &(this->list->head)) {
700  __FILE__, __LINE__,
701  "No previous element, must call next() before calling previous()." );
702  }
703 
704  this->lastReturned = this->current;
705  this->current = this->current->prev;
706  this->index--;
707 
708  return this->lastReturned->value;
709  }
710 
711  virtual bool hasPrevious() const {
712  return (this->current != &(this->list->head));
713  }
714 
715  virtual void remove() {
716  throw lang::exceptions::UnsupportedOperationException(
717  __FILE__, __LINE__, "Cannot write to a const ListIterator." );
718  }
719 
720  virtual void add( const E& e DECAF_UNUSED ) {
721  throw lang::exceptions::UnsupportedOperationException(
722  __FILE__, __LINE__, "Cannot write to a const ListIterator." );
723  }
724 
725  virtual void set( const E& e DECAF_UNUSED ) {
726  throw lang::exceptions::UnsupportedOperationException(
727  __FILE__, __LINE__, "Cannot write to a const ListIterator." );
728  }
729 
730  virtual int nextIndex() const {
731  return this->index + 1;
732  }
733 
734  virtual int previousIndex() const {
735  return this->index;
736  }
737  };
738 
739  class ReverseIterator : public Iterator<E> {
740  private:
741 
742  LinkedList<E>* list;
743  ListNode<E>* current;
744  int expectedModCount;
745  bool canRemove;
746 
747  private:
748 
749  ReverseIterator(const ReverseIterator&);
750  ReverseIterator operator=(const ReverseIterator&);
751 
752  public:
753 
754  ReverseIterator(LinkedList<E>* list) :
755  Iterator<E>(), list(list), current(NULL), expectedModCount(0), canRemove(false) {
756 
757  if (list == NULL) {
759  __FILE__, __LINE__, "Parent LinkedList pointer was Null." );
760  }
761 
762  this->expectedModCount = this->list->modCount;
763  this->current = &list->tail;
764  }
765 
766  virtual ~ReverseIterator() {}
767 
768  virtual bool hasNext() const {
769  return this->current->prev != &(this->list->head);
770  }
771 
772  virtual E next() {
773 
774  if (this->expectedModCount != this->list->modCount) {
775  throw ConcurrentModificationException(
776  __FILE__, __LINE__, "List modified outside of this Iterator." );
777  }
778 
779  if (this->current->prev == &(this->list->head)) {
780  throw NoSuchElementException(
781  __FILE__, __LINE__, "No more elements to return from next()" );
782  }
783 
784  this->current = this->current->prev;
785  this->canRemove = true;
786 
787  return this->current->value;
788  }
789 
790  virtual void remove() {
791  if (this->expectedModCount != this->list->modCount) {
792  throw ConcurrentModificationException(
793  __FILE__, __LINE__, "List modified outside of this Iterator." );
794  }
795 
796  if (!this->canRemove) {
797  throw lang::exceptions::IllegalStateException(
798  __FILE__, __LINE__,
799  "Invalid State to call remove, must call next() before remove()" );
800  }
801 
802  ListNode<E>* next = this->current->prev;
803  ListNode<E>* prev = this->current->next;
804 
805  next->next = prev;
806  prev->prev = next;
807 
808  delete this->current;
809 
810  this->current = prev;
811 
812  this->list->listSize--;
813  this->list->modCount++;
814  this->expectedModCount++;
815  this->canRemove = false;
816  }
817  };
818 
819  class ConstReverseIterator : public Iterator<E> {
820  private:
821 
822  const LinkedList<E>* list;
823  const ListNode<E>* current;
824 
825  private:
826 
827  ConstReverseIterator(const ConstReverseIterator&);
828  ConstReverseIterator operator=(const ConstReverseIterator&);
829 
830  public:
831 
832  ConstReverseIterator(const LinkedList<E>* list) : Iterator<E>(), list(list), current(NULL) {
833 
834  if (list == NULL) {
836  __FILE__, __LINE__, "Parent LinkedList pointer was Null." );
837  }
838 
839  this->current = &list->tail;
840  }
841 
842  virtual ~ConstReverseIterator() {}
843 
844  virtual bool hasNext() const {
845  return this->current->prev != &(this->list->head);
846  }
847 
848  virtual E next() {
849 
850  if (this->current->prev == &(this->list->head)) {
851  throw NoSuchElementException(
852  __FILE__, __LINE__, "No more elements to return from next()" );
853  }
854 
855  this->current = this->current->prev;
856 
857  return this->current->value;
858  }
859 
860  virtual void remove() {
861  throw lang::exceptions::UnsupportedOperationException(
862  __FILE__, __LINE__, "Cannot write to a const Iterator." );
863  }
864  };
865 
866  public:
867 
868  using AbstractSequentialList<E>::listIterator;
869 
870  virtual ListIterator<E>* listIterator(int index) {
871  return new LinkedListIterator(this, index);
872  }
873  virtual ListIterator<E>* listIterator(int index) const {
874  return new ConstLinkedListIterator(this, index);
875  }
876 
878  return new ReverseIterator(this);
879  }
880  virtual Iterator<E>* descendingIterator() const {
881  return new ConstReverseIterator(this);
882  }
883 
884  private:
885 
886  E removeAtFront() {
887 
888  if (this->head.next == &this->tail) {
890  __FILE__, __LINE__, "The Collection is empty." );
891  }
892 
893  ListNode<E>* oldNode = this->head.next;
894  E result = oldNode->value;
895 
896  this->head.next = oldNode->next;
897  this->head.next->prev = &this->head;
898 
899  delete oldNode;
900 
901  this->listSize--;
902  AbstractList<E>::modCount++;
903 
904  return result;
905  }
906 
907  E removeAtEnd() {
908 
909  if (this->head.next == &this->tail) {
910  throw NoSuchElementException(
911  __FILE__, __LINE__, "The Collection is empty." );
912  }
913 
914  ListNode<E>* oldNode = this->tail.prev;
915  E result = oldNode->value;
916 
917  this->tail.prev = oldNode->prev;
918  this->tail.prev->next = &this->tail;
919 
920  delete oldNode;
921 
922  this->listSize--;
923  AbstractList<E>::modCount++;
924 
925  return result;
926  }
927 
928  void addToFront(const E& value) {
929 
930  ListNode<E>* newHead = new ListNode<E> (&this->head, this->head.next, value);
931 
932  (this->head.next)->prev = newHead;
933  this->head.next = newHead;
934 
935  this->listSize++;
936  AbstractList<E>::modCount++;
937  }
938 
939  void addToEnd(const E& value) {
940 
941  ListNode<E>* newTail = new ListNode<E> (this->tail.prev, &this->tail, value);
942 
943  (this->tail.prev)->next = newTail;
944  this->tail.prev = newTail;
945 
946  this->listSize++;
947  AbstractList<E>::modCount++;
948  }
949 
950  void addAtLocation(int index, const E& value) {
951 
952  ListNode<E>* location = NULL;
953 
954  if (index <= this->listSize / 2) {
955  location = this->head.next;
956  for (int i = 0; i < index; ++i) {
957  location = location->next;
958  }
959  } else {
960  location = &this->tail;
961  for (int i = this->listSize; i > index; --i) {
962  location = location->prev;
963  }
964  }
965 
966  ListNode<E>* newNode = new ListNode<E> (location->prev, location, value);
967 
968  (location->prev)->next = newNode;
969  location->prev = newNode;
970 
971  this->listSize++;
972  AbstractList<E>::modCount++;
973  }
974 
975  bool addAllAtLocation(int index, const Collection<E>& collection) {
976 
977  if (index < 0 || index > this->listSize) {
979  __FILE__, __LINE__, "Index for add is outside bounds of this LinkedList." );
980  }
981 
982  int csize = collection.size();
983  if (csize == 0) {
984  return false;
985  }
986 
987  std::auto_ptr<ArrayList<E> > copy;
988  std::auto_ptr<Iterator<E> > iter;
989 
990  if (this == &collection) {
991  copy.reset(new ArrayList<E> (collection));
992  iter.reset(copy->iterator());
993  } else {
994  iter.reset(collection.iterator());
995  }
996 
997  ListNode<E>* newNode = NULL;
998  ListNode<E>* previous = NULL;
999 
1000  if (index < this->listSize / 2) {
1001  previous = &this->head;
1002  for (int i = 0; i < index; ++i) {
1003  previous = previous->next;
1004  }
1005  } else {
1006  previous = &this->tail;
1007  for (int i = this->listSize; i >= index; --i) {
1008  previous = previous->prev;
1009  }
1010  }
1011 
1012  while (iter->hasNext()) {
1013  newNode = new ListNode<E> (previous, previous->next, iter->next());
1014  previous->next->prev = newNode;
1015  previous->next = newNode;
1016  previous = newNode;
1017  }
1018 
1019  this->listSize += csize;
1020  AbstractList<E>::modCount++;
1021 
1022  return true;
1023  }
1024 
1025  void purgeList() {
1026  ListNode<E>* current = this->head.next;
1027  ListNode<E>* temp = NULL;
1028  while (current != &this->tail) {
1029  temp = current;
1030  current = current->next;
1031  delete temp;
1032  }
1033  }
1034  };
1035 
1036 }}
1037 
1038 #endif /* _DECAF_UTIL_LINKEDLIST_H_ */