• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#import "LinkedList.h"
2#import <Foundation/Foundation.h>
3#import "AMutableArray.h"
4#import "RuntimeException.h"
5
6@implementation LLNode
7
8@synthesize next;
9@synthesize prev;
10@synthesize item;
11
12+ (LLNode *) newNode:(LLNode *)aPrev element:(id)anElement next:(LLNode *)aNext
13{
14    return [[LLNode alloc] init:aPrev element:anElement next:aNext];
15}
16
17- (id) init:(LLNode *)aPrev element:(id)anElement next:(LLNode *)aNext
18{
19    self = [super init];
20    if (self) {
21        item = anElement;
22        next = aNext;
23        prev = aPrev;
24    }
25    return self;
26}
27
28- (void) dealloc
29{
30    [item release];
31    [next release];
32    [prev release];
33    [super dealloc];
34}
35
36@end
37
38@implementation ListIterator
39
40+ (ListIterator *) newIterator:(LinkedList *)anLL
41{
42    return [[ListIterator alloc] init:anLL withIndex:0];
43}
44
45+ (ListIterator *) newIterator:(LinkedList *)anLL withIndex:(NSInteger)anIndex
46{
47    return [[ListIterator alloc] init:anLL withIndex:anIndex];
48}
49
50- (id) init:(LinkedList *)anLL withIndex:(NSInteger)anIndex
51{
52    self = [super init];
53    if ( self ) {
54        ll = anLL;
55        index = anIndex;
56        lastReturned = nil;
57        expectedModCount = ll.modCount;
58        next = (index == count) ? nil : [ll node:anIndex];
59        nextIndex = index;
60    }
61    return self;
62}
63
64- (BOOL) hasNext
65{
66    return nextIndex < count;
67}
68
69- (id) next
70{
71    [self checkForComodification];
72    if (![self hasNext])
73        @throw [[[NoSuchElementException alloc] init] autorelease];
74    lastReturned = next;
75    next = next.next;
76    nextIndex++;
77    return lastReturned.item;
78}
79
80- (BOOL) hasPrevious
81{
82    return nextIndex > 0;
83}
84
85- (id) previous
86{
87    [self checkForComodification];
88    if (![self hasPrevious])
89        @throw [[[NoSuchElementException alloc] init] autorelease];
90    lastReturned = next = (next == nil) ? ll.last : next.prev;
91    nextIndex--;
92    return lastReturned.item;
93}
94
95- (NSInteger) nextIndex
96{
97    return nextIndex;
98}
99
100- (NSInteger) previousIndex
101{
102    return nextIndex - 1;
103}
104
105- (void) remove
106{
107    [self checkForComodification];
108    if (lastReturned == nil)
109        @throw [[[IllegalStateException alloc] init] autorelease];
110    LLNode *lastNext = lastReturned.next;
111    [ll unlink:lastReturned];
112    if (next == lastReturned)
113        next = lastNext;
114    else
115        nextIndex--;
116    lastReturned = nil;
117    expectedModCount++;
118}
119
120- (void) set:(id)e
121{
122    if (lastReturned == nil)
123        @throw [[[IllegalStateException alloc] init] autorelease];
124    [self checkForComodification];
125    lastReturned.item = e;
126}
127
128- (void) add:(id)e
129{
130    [self checkForComodification];
131    lastReturned = nil;
132    if (next == nil)
133        [ll linkLast:e];
134    else
135        [ll linkBefore:e succ:next];
136    nextIndex++;
137    expectedModCount++;
138}
139
140- (void) checkForComodification
141{
142    if (ll.modCount != expectedModCount)
143        @throw [[[ConcurrentModificationException alloc] init] autorelease];
144}
145
146- (void) dealloc
147{
148    [lastReturned release];
149    [next release];
150    [super dealloc];
151}
152
153@end
154
155@implementation DescendingIterator
156
157+ (DescendingIterator *)newIterator:(LinkedList *)anLL
158{
159    return [[DescendingIterator alloc] init:anLL];
160}
161
162- (id) init:(LinkedList *)anLL
163{
164    self = [super init:anLL withIndex:[anLL count]];
165    if ( self ) {
166
167    }
168    return self;
169}
170
171- (BOOL) hasNext
172{
173    return [self hasPrevious];
174}
175
176- (id) next
177{
178    return [self previous];
179}
180
181- (void) remove
182{
183    [self remove];
184}
185
186- (void) dealloc
187{
188    [super dealloc];
189}
190
191@end
192
193//long const serialVersionUID = 876323262645176354L;
194
195@implementation LinkedList
196
197@synthesize first;
198@synthesize last;
199@synthesize count;
200@synthesize modCount;
201
202+ (LinkedList *)newLinkedList
203{
204    return [[LinkedList alloc] init];
205}
206
207+ (LinkedList *)newLinkedList:(NSArray *)c
208{
209    return [[LinkedList alloc] initWithC:c];
210}
211
212/**
213 * Constructs an empty list.
214 */
215- (id) init
216{
217    self = [super init];
218    if ( self ) {
219        count = 0;
220    }
221    return self;
222}
223
224
225/**
226 * Constructs a list containing the elements of the specified
227 * collection, in the order they are returned by the collection's
228 * iterator.
229 *
230 * @param  c the collection whose elements are to be placed into this list
231 * @throws NullPointerException if the specified collection is null
232 */
233- (id) initWithC:(NSArray *)c
234{
235    self = [super init];
236    if ( self ) {
237        count = 0;
238        [self addAll:c];
239    }
240    return self;
241}
242
243
244- (void) dealloc
245{
246    [first release];
247    [last release];
248    [super dealloc];
249}
250
251/**
252 * Links e as first element.
253 */
254- (void) linkFirst:(id)e
255{
256    LLNode *f = first;
257    LLNode *newNode = [[LLNode newNode:nil element:e next:f] autorelease];
258    first = newNode;
259    if (f == nil)
260        last = newNode;
261    else
262        f.prev = newNode;
263    count++;
264    modCount++;
265}
266
267
268/**
269 * Links e as last element.
270 */
271- (void) linkLast:(id)e
272{
273    LLNode *l = last;
274    LLNode *newNode = [[LLNode newNode:l element:e next:nil] autorelease];
275    last = newNode;
276    if (l == nil)
277        first = newNode;
278    else
279        l.next = newNode;
280    count++;
281    modCount++;
282}
283
284
285/**
286 * Inserts element e before non-null LLNode succ.
287 */
288- (void) linkBefore:(id)e succ:(LLNode *)succ
289{
290    LLNode *pred = succ.prev;
291    LLNode *newNode = [[LLNode newNode:pred element:e next:succ] autorelease];
292    succ.prev = newNode;
293    if (pred == nil)
294        first = newNode;
295    else
296        pred.next = newNode;
297    count++;
298    modCount++;
299}
300
301
302/**
303 * Unlinks non-null first node f.
304 */
305- (id) unlinkFirst:(LLNode *)f
306{
307    id element = f.item;
308    LLNode *next = f.next;
309    f.item = nil;
310    f.next = nil;
311    first = next;
312    if (next == nil)
313        last = nil;
314    else
315        next.prev = nil;
316    count--;
317    modCount++;
318    return element;
319}
320
321
322/**
323 * Unlinks non-null last node l.
324 */
325- (id) unlinkLast:(LLNode *)l
326{
327    id element = l.item;
328    LLNode *prev = l.prev;
329    l.item = nil;
330    l.prev = nil;
331    last = prev;
332    if (prev == nil)
333        first = nil;
334    else
335        prev.next = nil;
336    count--;
337    modCount++;
338    return element;
339}
340
341
342/**
343 * Unlinks non-null node x.
344 */
345- (LLNode *) unlink:(LLNode *)x
346{
347    id element = x.item;
348    LLNode *next = x.next;
349    LLNode *prev = x.prev;
350    if (prev == nil) {
351        first = next;
352    }
353    else {
354        prev.next = next;
355        x.prev = nil;
356    }
357    if (next == nil) {
358        last = prev;
359    }
360    else {
361        next.prev = prev;
362        x.next = nil;
363    }
364    x.item = nil;
365    count--;
366    modCount++;
367    return element;
368}
369
370
371/**
372 * Returns the first element in this list.
373 *
374 * @return the first element in this list
375 * @throws NoSuchElementException if this list is empty
376 */
377- (LLNode *) first
378{
379    LLNode *f = first;
380    if (f == nil)
381        @throw [[[NoSuchElementException alloc] init] autorelease];
382    return f.item;
383}
384
385
386/**
387 * Returns the last element in this list.
388 *
389 * @return the last element in this list
390 * @throws NoSuchElementException if this list is empty
391 */
392- (LLNode *) last
393{
394    LLNode *l = last;
395    if (l == nil)
396        @throw [[[NoSuchElementException alloc] init] autorelease];
397    return l.item;
398}
399
400
401/**
402 * Removes and returns the first element from this list.
403 *
404 * @return the first element from this list
405 * @throws NoSuchElementException if this list is empty
406 */
407- (LLNode *) removeFirst
408{
409    LLNode *f = first;
410    if (f == nil)
411        @throw [[[NoSuchElementException alloc] init] autorelease];
412    return [self unlinkFirst:f];
413}
414
415
416/**
417 * Removes and returns the last element from this list.
418 *
419 * @return the last element from this list
420 * @throws NoSuchElementException if this list is empty
421 */
422- (LLNode *) removeLast
423{
424    LLNode *l = last;
425    if (l == nil)
426        @throw [[[NoSuchElementException alloc] init] autorelease];
427    return [self unlinkLast:l];
428}
429
430
431/**
432 * Inserts the specified element at the beginning of this list.
433 *
434 * @param e the element to add
435 */
436- (void) addFirst:(LLNode *)e
437{
438    [self linkFirst:e];
439}
440
441
442/**
443 * Appends the specified element to the end of this list.
444 *
445 * <p>This method is equivalent to {@link #add}.
446 *
447 * @param e the element to add
448 */
449- (void) addLast:(LLNode *)e
450{
451    [self linkLast:e];
452}
453
454
455/**
456 * Returns {@code true} if this list contains the specified element.
457 * More formally, returns {@code true} if and only if this list contains
458 * at least one element {@code e} such that
459 * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
460 *
461 * @param o element whose presence in this list is to be tested
462 * @return {@code true} if this list contains the specified element
463 */
464- (BOOL) contains:(id)o
465{
466    return [self indexOf:o] != -1;
467}
468
469
470/**
471 * Returns the number of elements in this list.
472 *
473 * @return the number of elements in this list
474 */
475- (NSInteger) count
476{
477    return count;
478}
479
480
481/**
482 * Appends the specified element to the end of this list.
483 *
484 * <p>This method is equivalent to {@link #addLast}.
485 *
486 * @param e element to be appended to this list
487 * @return {@code true} (as specified by {@link Collection#add})
488 */
489- (BOOL) add:(LLNode *)e
490{
491    [self linkLast:e];
492    return YES;
493}
494
495
496/**
497 * Removes the first occurrence of the specified element from this list,
498 * if it is present.  If this list does not contain the element, it is
499 * unchanged.  More formally, removes the element with the lowest index
500 * {@code i} such that
501 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
502 * (if such an element exists).  Returns {@code true} if this list
503 * contained the specified element (or equivalently, if this list
504 * changed as a result of the call).
505 *
506 * @param o element to be removed from this list, if present
507 * @return {@code true} if this list contained the specified element
508 */
509- (BOOL) remove:(id)o
510{
511    if (o == nil) {
512
513        for (LLNode *x = first; x != nil; x = x.next) {
514            if (x.item == nil) {
515                [self unlink:x];
516                return YES;
517            }
518        }
519
520    }
521    else {
522
523        for (LLNode *x = first; x != nil; x = x.next) {
524            if ([o isEqualTo:x.item]) {
525                [self unlink:x];
526                return YES;
527            }
528        }
529
530    }
531    return NO;
532}
533
534
535/**
536 * Appends all of the elements in the specified collection to the end of
537 * this list, in the order that they are returned by the specified
538 * collection's iterator.  The behavior of this operation is undefined if
539 * the specified collection is modified while the operation is in
540 * progress.  (Note that this will occur if the specified collection is
541 * this list, and it's nonempty.)
542 *
543 * @param c collection containing elements to be added to this list
544 * @return {@code true} if this list changed as a result of the call
545 * @throws NullPointerException if the specified collection is null
546 */
547- (BOOL) addAll:(NSArray *)c
548{
549    return [self addAll:count c:c];
550}
551
552
553/**
554 * Inserts all of the elements in the specified collection into this
555 * list, starting at the specified position.  Shifts the element
556 * currently at that position (if any) and any subsequent elements to
557 * the right (increases their indices).  The new elements will appear
558 * in the list in the order that they are returned by the
559 * specified collection's iterator.
560 *
561 * @param index index at which to insert the first element
562 * from the specified collection
563 * @param c collection containing elements to be added to this list
564 * @return {@code true} if this list changed as a result of the call
565 * @throws IndexOutOfBoundsException {@inheritDoc}
566 * @throws NullPointerException if the specified collection is null
567 */
568- (BOOL) addAll:(NSInteger)index c:(NSArray *)c
569{
570    [self checkPositionIndex:index];
571    AMutableArray *a = [AMutableArray arrayWithArray:c];
572    NSInteger numNew = [a count];
573    if (numNew == 0)
574        return NO;
575    LLNode *pred, *succ;
576    if (index == count) {
577        succ = nil;
578        pred = last;
579    }
580    else {
581        succ = [self node:index];
582        pred = succ.prev;
583    }
584
585    for (id o in a) {
586        id e = (id)o;
587        LLNode *newNode = [[LLNode newNode:pred element:e next:nil] autorelease];
588        if (pred == nil)
589            first = newNode;
590        else
591            pred.next = newNode;
592        pred = newNode;
593    }
594
595    if (succ == nil) {
596        last = pred;
597    }
598    else {
599        pred.next = succ;
600        succ.prev = pred;
601    }
602    count += numNew;
603    modCount++;
604    return YES;
605}
606
607
608/**
609 * Removes all of the elements from this list.
610 * The list will be empty after this call returns.
611 */
612- (void) clear
613{
614
615    for (LLNode *x = first; x != nil; ) {
616        LLNode *next = x.next;
617        x.item = nil;
618        x.next = nil;
619        x.prev = nil;
620        x = next;
621    }
622
623    first = last = nil;
624    count = 0;
625    modCount++;
626}
627
628
629/**
630 * Returns the element at the specified position in this list.
631 *
632 * @param index index of the element to return
633 * @return the element at the specified position in this list
634 * @throws IndexOutOfBoundsException {@inheritDoc}
635 */
636- (id) get:(NSInteger)index
637{
638    [self checkElementIndex:index];
639    return [self node:index].item;
640}
641
642
643/**
644 * Replaces the element at the specified position in this list with the
645 * specified element.
646 *
647 * @param index index of the element to replace
648 * @param element element to be stored at the specified position
649 * @return the element previously at the specified position
650 * @throws IndexOutOfBoundsException {@inheritDoc}
651 */
652- (id) set:(NSInteger)index element:(id)element
653{
654    [self checkElementIndex:index];
655    LLNode *x = [self node:index];
656    id oldVal = x.item;
657    x.item = element;
658    return oldVal;
659}
660
661
662/**
663 * Inserts the specified element at the specified position in this list.
664 * Shifts the element currently at that position (if any) and any
665 * subsequent elements to the right (adds one to their indices).
666 *
667 * @param index index at which the specified element is to be inserted
668 * @param element element to be inserted
669 * @throws IndexOutOfBoundsException {@inheritDoc}
670 */
671- (void) add:(NSInteger)index element:(LLNode *)element
672{
673    [self checkPositionIndex:index];
674    if (index == count)
675        [self linkLast:element];
676    else
677        [self linkBefore:element succ:[self node:index]];
678}
679
680
681/**
682 * Removes the element at the specified position in this list.  Shifts any
683 * subsequent elements to the left (subtracts one from their indices).
684 * Returns the element that was removed from the list.
685 *
686 * @param index the index of the element to be removed
687 * @return the element previously at the specified position
688 * @throws IndexOutOfBoundsException {@inheritDoc}
689 */
690- (LLNode *) removeIdx:(NSInteger)index
691{
692    [self checkElementIndex:index];
693    return [self unlink:[self node:index]];
694}
695
696
697/**
698 * Tells if the argument is the index of an existing element.
699 */
700- (BOOL) isElementIndex:(NSInteger)index
701{
702    return index >= 0 && index < count;
703}
704
705
706/**
707 * Tells if the argument is the index of a valid position for an
708 * iterator or an add operation.
709 */
710- (BOOL) isPositionIndex:(NSInteger)index
711{
712    return index >= 0 && index <= count;
713}
714
715
716/**
717 * Constructs an IndexOutOfBoundsException detail message.
718 * Of the many possible refactorings of the error handling code,
719 * this "outlining" performs best with both server and client VMs.
720 */
721- (NSString *) outOfBoundsMsg:(NSInteger)index
722{
723    return [NSString stringWithFormat:@"Index: %d, Size: %d", index, count];
724}
725
726- (void) checkElementIndex:(NSInteger)index
727{
728    if (![self isElementIndex:index])
729        @throw [[IndexOutOfBoundsException newException:[self outOfBoundsMsg:index]] autorelease];
730}
731
732- (void) checkPositionIndex:(NSInteger)index
733{
734    if (![self isPositionIndex:index])
735        @throw [[IndexOutOfBoundsException newException:[self outOfBoundsMsg:index]] autorelease];
736}
737
738
739/**
740 * Returns the (non-null) LLNode at the specified element index.
741 */
742- (LLNode *) node:(NSInteger)index
743{
744    if (index < (count >> 1)) {
745        LLNode *x = first;
746
747        for (NSInteger i = 0; i < index; i++)
748            x = x.next;
749
750        return x;
751    }
752    else {
753        LLNode *x = last;
754
755        for (NSInteger i = count - 1; i > index; i--)
756            x = x.prev;
757
758        return x;
759    }
760}
761
762
763/**
764 * Returns the index of the first occurrence of the specified element
765 * in this list, or -1 if this list does not contain the element.
766 * More formally, returns the lowest index {@code i} such that
767 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
768 * or -1 if there is no such index.
769 *
770 * @param o element to search for
771 * @return the index of the first occurrence of the specified element in
772 * this list, or -1 if this list does not contain the element
773 */
774- (NSInteger) indexOf:(id)o
775{
776    NSInteger index = 0;
777    if (o == nil) {
778
779        for (LLNode *x = first; x != nil; x = x.next) {
780            if (x.item == nil)
781                return index;
782            index++;
783        }
784
785    }
786    else {
787
788        for (LLNode *x = first; x != nil; x = x.next) {
789            if ([o isEqualTo:x.item])
790                return index;
791            index++;
792        }
793
794    }
795    return -1;
796}
797
798
799/**
800 * Returns the index of the last occurrence of the specified element
801 * in this list, or -1 if this list does not contain the element.
802 * More formally, returns the highest index {@code i} such that
803 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
804 * or -1 if there is no such index.
805 *
806 * @param o element to search for
807 * @return the index of the last occurrence of the specified element in
808 * this list, or -1 if this list does not contain the element
809 */
810- (NSInteger) lastIndexOf:(id)o
811{
812    NSInteger index = count;
813    if (o == nil) {
814
815        for (LLNode *x = last; x != nil; x = x.prev) {
816            index--;
817            if (x.item == nil)
818                return index;
819        }
820
821    }
822    else {
823
824        for (LLNode *x = last; x != nil; x = x.prev) {
825            index--;
826            if ([o isEqualTo:x.item])
827                return index;
828        }
829
830    }
831    return -1;
832}
833
834
835/**
836 * Retrieves, but does not remove, the head (first element) of this list.
837 *
838 * @return the head of this list, or {@code null} if this list is empty
839 * @since 1.5
840 */
841- (LLNode *) peek
842{
843    LLNode *f = first;
844    return (f == nil) ? nil : f.item;
845}
846
847
848/**
849 * Retrieves, but does not remove, the head (first element) of this list.
850 *
851 * @return the head of this list
852 * @throws NoSuchElementException if this list is empty
853 * @since 1.5
854 */
855- (LLNode *) element
856{
857    return [self first];
858}
859
860
861/**
862 * Retrieves and removes the head (first element) of this list.
863 *
864 * @return the head of this list, or {@code null} if this list is empty
865 * @since 1.5
866 */
867- (LLNode *) poll
868{
869    LLNode *f = first;
870    return (f == nil) ? nil : [self unlinkFirst:f];
871}
872
873
874/**
875 * Retrieves and removes the head (first element) of this list.
876 *
877 * @return the head of this list
878 * @throws NoSuchElementException if this list is empty
879 * @since 1.5
880 */
881- (LLNode *) remove
882{
883    return [self removeFirst];
884}
885
886
887/**
888 * Adds the specified element as the tail (last element) of this list.
889 *
890 * @param e the element to add
891 * @return {@code true} (as specified by {@link Queue#offer})
892 * @since 1.5
893 */
894- (BOOL) offer:(LLNode *)e
895{
896    return [self add:e];
897}
898
899
900/**
901 * Inserts the specified element at the front of this list.
902 *
903 * @param e the element to insert
904 * @return {@code true} (as specified by {@link Deque#offerFirst})
905 * @since 1.6
906 */
907- (BOOL) offerFirst:(LLNode *)e
908{
909    [self addFirst:e];
910    return YES;
911}
912
913
914/**
915 * Inserts the specified element at the end of this list.
916 *
917 * @param e the element to insert
918 * @return {@code true} (as specified by {@link Deque#offerLast})
919 * @since 1.6
920 */
921- (BOOL) offerLast:(LLNode *)e
922{
923    [self addLast:e];
924    return YES;
925}
926
927
928/**
929 * Retrieves, but does not remove, the first element of this list,
930 * or returns {@code null} if this list is empty.
931 *
932 * @return the first element of this list, or {@code null}
933 * if this list is empty
934 * @since 1.6
935 */
936- (LLNode *) peekFirst
937{
938    LLNode *f = first;
939    return (f == nil) ? nil : f.item;
940}
941
942
943/**
944 * Retrieves, but does not remove, the last element of this list,
945 * or returns {@code null} if this list is empty.
946 *
947 * @return the last element of this list, or {@code null}
948 * if this list is empty
949 * @since 1.6
950 */
951- (LLNode *) peekLast
952{
953    LLNode *l = last;
954    return (l == nil) ? nil : l.item;
955}
956
957
958/**
959 * Retrieves and removes the first element of this list,
960 * or returns {@code null} if this list is empty.
961 *
962 * @return the first element of this list, or {@code null} if
963 * this list is empty
964 * @since 1.6
965 */
966- (LLNode *) pollFirst
967{
968    LLNode *f = first;
969    return (f == nil) ? nil : [self unlinkFirst:f];
970}
971
972
973/**
974 * Retrieves and removes the last element of this list,
975 * or returns {@code null} if this list is empty.
976 *
977 * @return the last element of this list, or {@code null} if
978 * this list is empty
979 * @since 1.6
980 */
981- (LLNode *) pollLast
982{
983    LLNode *l = last;
984    return (l == nil) ? nil : [self unlinkLast:l];
985}
986
987
988/**
989 * Pushes an element onto the stack represented by this list.  In other
990 * words, inserts the element at the front of this list.
991 *
992 * <p>This method is equivalent to {@link #addFirst}.
993 *
994 * @param e the element to push
995 * @since 1.6
996 */
997- (void) push:(LLNode *)e
998{
999    [self addFirst:e];
1000}
1001
1002
1003/**
1004 * Pops an element from the stack represented by this list.  In other
1005 * words, removes and returns the first element of this list.
1006 *
1007 * <p>This method is equivalent to {@link #removeFirst()}.
1008 *
1009 * @return the element at the front of this list (which is the top
1010 * of the stack represented by this list)
1011 * @throws NoSuchElementException if this list is empty
1012 * @since 1.6
1013 */
1014- (LLNode *) pop
1015{
1016    return [self removeFirst];
1017}
1018
1019
1020/**
1021 * Removes the first occurrence of the specified element in this
1022 * list (when traversing the list from head to tail).  If the list
1023 * does not contain the element, it is unchanged.
1024 *
1025 * @param o element to be removed from this list, if present
1026 * @return {@code true} if the list contained the specified element
1027 * @since 1.6
1028 */
1029- (BOOL) removeFirstOccurrence:(id)o
1030{
1031    return [self remove:o];
1032}
1033
1034
1035/**
1036 * Removes the last occurrence of the specified element in this
1037 * list (when traversing the list from head to tail).  If the list
1038 * does not contain the element, it is unchanged.
1039 *
1040 * @param o element to be removed from this list, if present
1041 * @return {@code true} if the list contained the specified element
1042 * @since 1.6
1043 */
1044- (BOOL) removeLastOccurrence:(id)o
1045{
1046    if (o == nil) {
1047
1048        for (LLNode *x = last; x != nil; x = x.prev) {
1049            if (x.item == nil) {
1050                [self unlink:x];
1051                return YES;
1052            }
1053        }
1054
1055    }
1056    else {
1057
1058        for (LLNode *x = last; x != nil; x = x.prev) {
1059            if ([o isEqualTo:x.item]) {
1060                [self unlink:x];
1061                return YES;
1062            }
1063        }
1064
1065    }
1066    return NO;
1067}
1068
1069
1070/**
1071 * Returns a list-iterator of the elements in this list (in proper
1072 * sequence), starting at the specified position in the list.
1073 * Obeys the general contract of {@code List.listIterator(NSInteger)}.<p>
1074 *
1075 * The list-iterator is <i>fail-fast</i>: if the list is structurally
1076 * modified at any time after the Iterator is created, in any way except
1077 * through the list-iterator's own {@code remove} or {@code add}
1078 * methods, the list-iterator will throw a
1079 * {@code ConcurrentModificationException}.  Thus, in the face of
1080 * concurrent modification, the iterator fails quickly and cleanly, rather
1081 * than risking arbitrary, non-deterministic behavior at an undetermined
1082 * time in the future.
1083 *
1084 * @param index index of the first element to be returned from the
1085 * list-iterator (by a call to {@code next})
1086 * @return a ListIterator of the elements in this list (in proper
1087 * sequence), starting at the specified position in the list
1088 * @throws IndexOutOfBoundsException {@inheritDoc}
1089 * @see List#listIterator(NSInteger)
1090 */
1091- (ListIterator *) listIterator:(NSInteger)index
1092{
1093    [self checkPositionIndex:index];
1094    return [[ListIterator newIterator:self withIndex:index] autorelease];
1095}
1096
1097
1098/**
1099 * @since 1.6
1100 */
1101- (NSEnumerator *) descendingIterator
1102{
1103    return [[[DescendingIterator alloc] init] autorelease];
1104}
1105
1106/*
1107- (LinkedList *) superClone:(NSZone *)zone
1108{
1109
1110    @try {
1111        return (LinkedList *)[super copyWithZone:zone];
1112    }
1113    @catch (CloneNotSupportedException * e) {
1114        @throw [[[NSException exceptionWithName:@"InternalException" reason:@"Attempted to Clone non-cloneable List" userInfo:nil] autorelease];
1115    }
1116}
1117*/
1118
1119/**
1120 * Returns a shallow copy of this {@code LinkedList}. (The elements
1121 * themselves are not cloned.)
1122 *
1123 * @return a shallow copy of this {@code LinkedList} instance
1124 */
1125- (id) copyWithZone:(NSZone *)zone
1126{
1127    LinkedList *clone = [LinkedList allocWithZone:zone];
1128    clone.first = nil;
1129    clone.last = nil;
1130    clone.count = 0;
1131    clone.modCount = 0;
1132
1133    for (LLNode *x = first; x != nil; x = x.next)
1134        [clone add:x.item];
1135
1136    clone.count = count;
1137    clone.first = first;
1138    clone.last = last;
1139    return clone;
1140}
1141
1142
1143/**
1144 * Returns an array containing all of the elements in this list
1145 * in proper sequence (from first to last element).
1146 *
1147 * <p>The returned array will be "safe" in that no references to it are
1148 * maintained by this list.  (In other words, this method must allocate
1149 * a new array).  The caller is thus free to modify the returned array.
1150 *
1151 * <p>This method acts as bridge between array-based and collection-based
1152 * APIs.
1153 *
1154 * @return an array containing all of the elements in this list
1155 * in proper sequence
1156 */
1157- (NSArray *) toArray
1158{
1159    AMutableArray *result = [AMutableArray arrayWithCapacity:10];
1160
1161    for (LLNode *x = first; x != nil; x = x.next)
1162        [result addObject:x.item];
1163
1164    return result;
1165}
1166
1167
1168/**
1169 * Returns an array containing all of the elements in this list in
1170 * proper sequence (from first to last element); the runtime type of
1171 * the returned array is that of the specified array.  If the list fits
1172 * in the specified array, it is returned therein.  Otherwise, a new
1173 * array is allocated with the runtime type of the specified array and
1174 * the size of this list.
1175 *
1176 * <p>If the list fits in the specified array with room to spare (i.e.,
1177 * the array has more elements than the list), the element in the array
1178 * immediately following the end of the list is set to {@code null}.
1179 * (This is useful in determining the length of the list <i>only</i> if
1180 * the caller knows that the list does not contain any null elements.)
1181 *
1182 * <p>Like the {@link #toArray()} method, this method acts as bridge between
1183 * array-based and collection-based APIs.  Further, this method allows
1184 * precise control over the runtime type of the output array, and may,
1185 * under certain circumstances, be used to save allocation costs.
1186 *
1187 * <p>Suppose {@code x} is a list known to contain only strings.
1188 * The following code can be used to dump the list into a newly
1189 * allocated array of {@code String}:
1190 *
1191 * <pre>
1192 * String[] y = x.toArray(new String[0]);</pre>
1193 *
1194 * Note that {@code toArray(new Object[0])} is identical in function to
1195 * {@code toArray()}.
1196 *
1197 * @param a the array into which the elements of the list are to
1198 * be stored, if it is big enough; otherwise, a new array of the
1199 * same runtime type is allocated for this purpose.
1200 * @return an array containing the elements of the list
1201 * @throws ArrayStoreException if the runtime type of the specified array
1202 * is not a supertype of the runtime type of every element in
1203 * this list
1204 * @throws NullPointerException if the specified array is null
1205 */
1206- (NSArray *) toArray:(AMutableArray *)a
1207{
1208    if ( [a count] < count )
1209        a = (AMutableArray *)[AMutableArray arrayWithArray:a];
1210    AMutableArray *result = a;
1211
1212    for (LLNode *x = first; x != nil; x = x.next)
1213        [result addObject:x.item];
1214
1215    if ([a count] > count)
1216        [a replaceObjectAtIndex:count withObject:nil];
1217    return a;
1218}
1219
1220
1221/**
1222 * Saves the state of this {@code LinkedList} instance to a stream
1223 * (that is, serializes it).
1224 *
1225 * @serialData The size of the list (the number of elements it
1226 * contains) is emitted (NSInteger), followed by all of its
1227 * elements (each an Object) in the proper order.
1228 */
1229- (void) writeObject:(NSOutputStream *)s
1230{
1231/*
1232    [s defaultWriteObject];
1233    [s writeInt:count];
1234
1235    for (LLNode *x = first; x != nil; x = x.next)
1236        [s writeObject:x.item];
1237 */
1238}
1239
1240
1241/**
1242 * Reconstitutes this {@code LinkedList} instance from a stream
1243 * (that is, deserializes it).
1244 */
1245- (void) readObject:(NSInputStream *)s
1246{
1247/*
1248    [s defaultReadObject];
1249    NSInteger len = [s readInt];
1250
1251    for (NSInteger i = 0; i < len; i++)
1252        [self linkLast:(id)[s readObject]];
1253 */
1254}
1255
1256@end
1257