2 * list.cpp: a non-sucky linked list implementation
5 * Moonlight List (moonlight-list@lists.ximian.com)
7 * Copyright 2007 Novell, Inc. (http://www.novell.com)
9 * See the LICENSE file included with the distribution for details.
61 List::Clear (bool freeNodes
)
81 List::Append (List::Node
*node
)
100 List::Prepend (List::Node
*node
)
118 List::Prepend (List
*list
)
120 if (list
->head
== NULL
)
123 list
->tail
->next
= head
;
125 head
->prev
= list
->tail
;
131 length
+= list
->length
;
138 List::Insert (List::Node
*node
, int index
)
140 List::Node
*n
= head
;
144 while (n
->next
&& i
< index
) {
150 // Inserting @node before @n
151 node
->prev
= n
->prev
;
155 n
->prev
->next
= node
;
161 // Inserting @node after @n (means @n was the tail)
162 tail
= n
->next
= node
;
167 // @node will be the only node in the list
179 List::InsertAfter (List::Node
*node
, List::Node
*after
)
182 return Prepend (node
);
184 node
->next
= after
->next
;
188 if (node
->next
!= NULL
)
189 node
->next
->prev
= node
;
199 List::InsertBefore (List::Node
*node
, List::Node
*before
)
202 return Append (node
);
205 node
->prev
= before
->prev
;
207 if (before
->prev
!= NULL
)
208 before
->prev
->next
= node
;
221 List::Replace (List::Node
*node
, int index
)
225 if (!(n
= Index (index
)))
228 node
->next
= n
->next
;
229 node
->prev
= n
->prev
;
232 n
->prev
->next
= node
;
237 n
->next
->prev
= node
;
248 List::Find (NodeAction find
, void *data
)
250 List::Node
*n
= head
;
267 List::Remove (NodeAction find
, void *data
)
271 if ((n
= Find (find
, data
))) {
278 List::Remove (List::Node
*node
)
285 List::RemoveAt (int index
)
288 if (!(node
= Index (index
)))
296 List::Unlink (List::Node
*node
)
299 node
->prev
->next
= node
->next
;
304 node
->next
->prev
= node
->prev
;
316 List::Index (int index
)
318 List::Node
*n
= head
;
324 while (n
&& i
< index
) {
336 List::IndexOf (List::Node
*node
)
338 List::Node
*n
= head
;
341 while (n
&& n
!= node
) {
346 return n
== node
? i
: -1;
351 List::IndexOf (NodeAction find
, void *data
)
353 List::Node
*n
= head
;
371 List::ForEach (NodeAction action
, void *data
)
373 List::Node
*node
= head
;
379 while (node
&& move
) {
380 if (!action (node
, data
))
390 pthread_mutex_init (&lock
, NULL
);
396 pthread_mutex_destroy (&lock
);
406 empty
= list
->IsEmpty ();
418 length
= list
->Length ();
425 Queue::Clear (bool freeNodes
)
428 list
->Clear (freeNodes
);
433 Queue::Push (List::Node
*node
)
446 if ((node
= list
->First ()))
456 pthread_mutex_lock (&lock
);
462 pthread_mutex_unlock (&lock
);
472 Queue::MoveTo (Queue
&queue
)
475 while ((node
= list
->First ())) {
486 ArrayList::ArrayList ()
493 ArrayList::~ArrayList ()
499 ArrayList::SetCount (int value
)
501 EnsureCapacity (value
);
506 ArrayList::GetCapacity ()
512 ArrayList::SetCapacity (int capacity
)
514 if (capacity
== size
)
517 array
= (void **) g_realloc (array
, sizeof (void *) * capacity
);
519 for (int i
= size
; i
< capacity
; i
++)
525 ArrayList::EnsureCapacity (int capacity
)
528 SetCapacity (capacity
);
532 ArrayList::Add (void *item
)
534 EnsureCapacity (count
+ 1);
535 array
[count
] = item
;
539 //#define TEST_PROGRAM
544 class IntNode
: public List::Node
{
548 IntNode (int i
) { id
= i
; }
553 IntNodeFinder (List::Node
*node
, void *data
)
555 int val
= *((int *) data
);
557 return ((IntNode
*) node
)->id
== val
;
561 int main (int argc
, char **argv
)
568 node
= list
->Append (new IntNode (2));
569 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
570 node
= list
->Append (new IntNode (4));
571 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
572 node
= list
->Append (new IntNode (5));
573 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
574 node
= list
->Insert (new IntNode (3), 1);
575 printf ("inserted node with id = %d at index = %d\n",
576 ((IntNode
*) node
)->id
, list
->IndexOf (node
));
577 node
= list
->Prepend (new IntNode (1));
578 printf ("prepended node with id = %d\n", ((IntNode
*) node
)->id
);
579 node
= list
->Prepend (new IntNode (0));
580 printf ("prepended node with id = %d\n", ((IntNode
*) node
)->id
);
581 node
= list
->Insert (new IntNode (6), 6);
582 printf ("inserted node with id = %d at index = %d\n",
583 ((IntNode
*) node
)->id
, list
->IndexOf (node
));
585 printf ("\nlist contains (in order):\n");
586 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
587 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
589 printf ("\nlist contains (in reverse order):\n");
590 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
591 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
593 printf ("\nunlinking the last item in the list\n");
594 list
->Unlink (list
->Last ());
596 printf ("\nlist contains (in order):\n");
597 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
598 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
600 printf ("\nlist contains (in reverse order):\n");
601 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
602 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
604 printf ("\nunlinking the first item in the list\n");
605 list
->Unlink (list
->First ());
607 printf ("\nlist contains (in order):\n");
608 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
609 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
611 printf ("\nlist contains (in reverse order):\n");
612 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
613 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
615 printf ("\nreplacing 4 with 8\n");
617 int index
= list
->IndexOf (IntNodeFinder
, &id
);
618 if ((node
= list
->Replace (new IntNode (8), index
)))
621 printf ("unsuccessful\n");
623 printf ("\nlist contains (in order):\n");
624 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
625 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
627 printf ("\nlist contains (in reverse order):\n");
628 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
629 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
631 printf ("\nremoving 5\n");
633 list
->Remove (IntNodeFinder
, &id
);
635 printf ("\nlist contains (in order):\n");
636 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
637 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
639 printf ("\nlist contains (in reverse order):\n");
640 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
641 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
643 printf ("\nremoving 1\n");
645 list
->Remove (IntNodeFinder
, &id
);
647 printf ("\nlist contains (in order):\n");
648 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
649 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
651 printf ("\nlist contains (in reverse order):\n");
652 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
653 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
661 #endif /* TEST_PROGRAM */