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.
69 List::Clear (bool freeNodes
)
89 List::Append (List::Node
*node
)
108 List::Prepend (List::Node
*node
)
127 List::Insert (List::Node
*node
, int index
)
129 List::Node
*n
= head
;
133 while (n
->next
&& i
< index
) {
139 // Inserting @node before @n
140 node
->prev
= n
->prev
;
144 n
->prev
->next
= node
;
150 // Inserting @node after @n (means @n was the tail)
151 tail
= n
->next
= node
;
156 // @node will be the only node in the list
168 List::InsertAfter (List::Node
*node
, List::Node
*after
)
171 return Prepend (node
);
173 node
->next
= after
->next
;
177 if (node
->next
!= NULL
)
178 node
->next
->prev
= node
;
188 List::InsertBefore (List::Node
*node
, List::Node
*before
)
191 return Append (node
);
194 node
->prev
= before
->prev
;
196 if (before
->prev
!= NULL
)
197 before
->prev
->next
= node
;
210 List::Replace (List::Node
*node
, int index
)
214 if (!(n
= Index (index
)))
217 node
->next
= n
->next
;
218 node
->prev
= n
->prev
;
221 n
->prev
->next
= node
;
226 n
->next
->prev
= node
;
237 List::Find (NodeAction find
, void *data
)
239 List::Node
*n
= head
;
256 List::Remove (NodeAction find
, void *data
)
260 if ((n
= Find (find
, data
))) {
267 List::Remove (List::Node
*node
)
274 List::RemoveAt (int index
)
277 if (!(node
= Index (index
)))
285 List::Unlink (List::Node
*node
)
288 node
->prev
->next
= node
->next
;
293 node
->next
->prev
= node
->prev
;
305 List::Index (int index
)
307 List::Node
*n
= head
;
313 while (n
&& i
< index
) {
325 List::IndexOf (List::Node
*node
)
327 List::Node
*n
= head
;
330 while (n
&& n
!= node
) {
335 return n
== node
? i
: -1;
340 List::IndexOf (NodeAction find
, void *data
)
342 List::Node
*n
= head
;
360 List::ForEach (NodeAction action
, void *data
)
362 List::Node
*node
= head
;
368 while (node
&& move
) {
369 if (!action (node
, data
))
379 pthread_mutex_init (&lock
, NULL
);
385 pthread_mutex_destroy (&lock
);
395 empty
= list
->IsEmpty ();
407 length
= list
->Length ();
414 Queue::Clear (bool freeNodes
)
417 list
->Clear (freeNodes
);
422 Queue::Push (List::Node
*node
)
435 if ((node
= list
->First ()))
445 pthread_mutex_lock (&lock
);
451 pthread_mutex_unlock (&lock
);
465 ArrayList::ArrayList ()
472 ArrayList::~ArrayList ()
478 ArrayList::GetCount ()
484 ArrayList::SetCount (int value
)
486 EnsureCapacity (value
);
491 ArrayList::GetCapacity ()
497 ArrayList::SetCapacity (int capacity
)
499 if (capacity
== size
)
502 array
= (void **) g_realloc (array
, sizeof (void *) * capacity
);
504 for (int i
= size
; i
< capacity
; i
++)
510 ArrayList::EnsureCapacity (int capacity
)
513 SetCapacity (capacity
);
517 ArrayList::Add (void *item
)
519 EnsureCapacity (count
+ 1);
520 array
[count
] = item
;
525 ArrayList::operator [] (int index
)
527 return array
[index
];
531 //#define TEST_PROGRAM
536 class IntNode
: public List::Node
{
540 IntNode (int i
) { id
= i
; }
545 IntNodeCompare (List::Node
*n0
, List::Node
*n1
)
547 IntNode
*in0
= (IntNode
*) n0
;
548 IntNode
*in1
= (IntNode
*) n1
;
550 return in0
->id
- in1
->id
;
554 IntNodeFinder (List::Node
*node
, void *data
)
556 int val
= *((int *) data
);
558 return ((IntNode
*) node
)->id
== val
;
562 int main (int argc
, char **argv
)
569 node
= list
->Append (new IntNode (2));
570 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
571 node
= list
->Append (new IntNode (4));
572 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
573 node
= list
->Append (new IntNode (5));
574 printf ("appended node with id = %d\n", ((IntNode
*) node
)->id
);
575 node
= list
->Insert (new IntNode (3), 1);
576 printf ("inserted node with id = %d at index = %d\n",
577 ((IntNode
*) node
)->id
, list
->IndexOf (node
));
578 node
= list
->Prepend (new IntNode (1));
579 printf ("prepended node with id = %d\n", ((IntNode
*) node
)->id
);
580 node
= list
->Prepend (new IntNode (0));
581 printf ("prepended node with id = %d\n", ((IntNode
*) node
)->id
);
582 node
= list
->Insert (new IntNode (6), 6);
583 printf ("inserted node with id = %d at index = %d\n",
584 ((IntNode
*) node
)->id
, list
->IndexOf (node
));
586 printf ("\nlist contains (in order):\n");
587 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
588 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
590 printf ("\nlist contains (in reverse order):\n");
591 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
592 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
594 printf ("\nunlinking the last item in the list\n");
595 list
->Unlink (list
->Last ());
597 printf ("\nlist contains (in order):\n");
598 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
599 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
601 printf ("\nlist contains (in reverse order):\n");
602 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
603 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
605 printf ("\nunlinking the first item in the list\n");
606 list
->Unlink (list
->First ());
608 printf ("\nlist contains (in order):\n");
609 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
610 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
612 printf ("\nlist contains (in reverse order):\n");
613 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
614 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
616 printf ("\nreplacing 4 with 8\n");
618 int index
= list
->IndexOf (IntNodeFinder
, &id
);
619 if ((node
= list
->Replace (new IntNode (8), index
)))
622 printf ("unsuccessful\n");
624 printf ("\nlist contains (in order):\n");
625 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
626 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
628 printf ("\nlist contains (in reverse order):\n");
629 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
630 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
632 printf ("\nremoving 5\n");
634 list
->Remove (IntNodeFinder
, &id
);
636 printf ("\nlist contains (in order):\n");
637 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
638 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
640 printf ("\nlist contains (in reverse order):\n");
641 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
642 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
644 printf ("\nremoving 1\n");
646 list
->Remove (IntNodeFinder
, &id
);
648 printf ("\nlist contains (in order):\n");
649 for (node
= list
->First (); node
!= NULL
; node
= node
->next
)
650 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
652 printf ("\nlist contains (in reverse order):\n");
653 for (node
= list
->Last (); node
!= NULL
; node
= node
->prev
)
654 printf ("node id = %d\n", ((IntNode
*) node
)->id
);
662 #endif /* TEST_PROGRAM */