1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxList implementation
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "list.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 // Sun CC compatibility (interference with xview/pkg.h, apparently...)
30 #if defined(SUN_CC) && defined(__XVIEW__)
41 #if !USE_SHARED_LIBRARY
42 IMPLEMENT_DYNAMIC_CLASS(wxNode
, wxObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxList
, wxObject
)
44 IMPLEMENT_DYNAMIC_CLASS(wxStringList
, wxList
)
47 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
57 previous
->next
= this;
60 next
->previous
= this;
64 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
65 wxObject
* object
, long the_key
)
71 key
.integer
= the_key
;
74 previous
->next
= this;
77 next
->previous
= this;
80 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
81 wxObject
* object
, const char *the_key
)
87 key
.string
= copystring (the_key
);
90 previous
->next
= this;
93 next
->previous
= this;
97 wxNode::~wxNode (void)
102 if (list
&& list
->destroy_data
)
105 if (list
&& list
->key_type
== wxKEY_STRING
&& key
.string
)
108 // Make next node point back to the previous node from here
110 next
->previous
= previous
;
112 // If there's a new end of list (deleting the last one)
113 // make sure the list knows about it.
114 list
->last_node
= previous
;
116 // Make the previous node point to the next node from here
118 previous
->next
= next
;
120 // Or if no previous node (start of list), make sure list points at
121 // the next node which becomes the first!.
123 list
->first_node
= next
;
126 wxList::wxList (void)
132 key_type
= wxKEY_NONE
;
135 wxList::wxList (int N
, wxObject
* Objects
[])
140 for (i
= 0; i
< N
; i
++)
142 wxNode
*next
= new wxNode (this, last
, NULL
, Objects
[i
]);
149 key_type
= wxKEY_NONE
;
152 wxList::wxList (const unsigned int the_key_type
)
158 key_type
= the_key_type
;
161 // Variable argument list, terminated by a zero
162 wxList::wxList (wxObject
* first_one
...)
167 va_start (ap
, first_one
);
169 wxNode
*last
= new wxNode (this, NULL
, NULL
, first_one
);
175 wxObject
*object
= va_arg (ap
, wxObject
*);
176 // if (object == NULL) // Doesn't work in Windows -- segment is non-zero for NULL!
178 if ((int) object
== 0)
180 if ((long) object
== 0)
185 wxNode
*node
= new wxNode (this, last
, NULL
, object
);
194 key_type
= wxKEY_NONE
;
197 fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
202 wxList::~wxList (void)
204 wxNode
*each
= first_node
;
207 wxNode
*next
= each
->Next ();
213 wxNode
*wxList::Append(wxObject
*object
)
215 wxNode
*node
= new wxNode(this, last_node
, NULL
, object
);
223 wxNode
*wxList::Nth (int i
) const
226 for (wxNode
* current
= First (); current
; current
= current
->Next ())
231 return NULL
; // No such element
235 wxNode
*wxList::Find (long key
) const
237 wxNode
*current
= First();
240 if (current
->key
.integer
== key
)
242 current
= current
->Next();
245 return NULL
; // Not found!
248 wxNode
*wxList::Find (const char *key
) const
250 wxNode
*current
= First();
253 if (!current
->key
.string
)
255 wxFatalError ("wxList: string key not present, probably did not Append correctly!");
258 if (strcmp (current
->key
.string
, key
) == 0)
260 current
= current
->Next();
263 return NULL
; // Not found!
267 wxNode
*wxList::Member (wxObject
* object
) const
269 for (wxNode
* current
= First (); current
; current
= current
->Next ())
271 wxObject
*each
= current
->Data ();
278 bool wxList::DeleteNode (wxNode
* node
)
288 bool wxList::DeleteObject (wxObject
* object
)
290 // Search list for object
291 for (wxNode
* current
= first_node
; current
; current
= current
->Next ())
293 if (current
->Data () == object
)
299 return FALSE
; // Did not find the object
304 // Insert new node at front of list
305 wxNode
*wxList::Insert (wxObject
* object
)
307 wxNode
*node
= new wxNode (this, NULL
, First (), object
);
310 if (!(node
->Next ()))
318 // Insert new node before given node.
319 wxNode
*wxList::Insert (wxNode
* position
, wxObject
* object
)
323 prev
= position
->Previous ();
325 wxNode
*node
= new wxNode (this, prev
, position
, object
);
339 wxNode
*wxList::Append (long key
, wxObject
* object
)
341 wxNode
*node
= new wxNode (this, last_node
, NULL
, object
, key
);
349 wxNode
*wxList::Append (const char *key
, wxObject
* object
)
351 wxNode
*node
= new wxNode (this, last_node
, NULL
, object
, key
);
359 void wxList::Clear (void)
361 wxNode
*current
= first_node
;
364 wxNode
*next
= current
->Next ();
373 //Executes function F with all items present in the list
374 void wxList::ForEach(wxListIterateFunction F
)
376 wxNode
*each
= first_node
;
378 { (*F
)( each
->Data ());
382 // Returns a pointer to the item which returns TRUE with function F
383 // or NULL if no such item found
384 wxObject
*wxList::FirstThat(wxListIterateFunction F
)
386 wxNode
*each
= first_node
;
388 { if ((*F
)( each
->Data ())) return each
->Data();
393 // Like FirstThat, but proceeds from the end backward
394 wxObject
*wxList::LastThat(wxListIterateFunction F
)
396 wxNode
*each
= last_node
;
398 { if ((*F
)( each
->Data ())) return each
->Data();
399 each
= each
->Previous();
404 // (stefan.hammes@urz.uni-heidelberg.de)
406 // function for sorting lists. the concept is borrowed from 'qsort'.
407 // by giving a sort function, arbitrary lists can be sorted.
409 // - put wxObject pointers into an array
410 // - sort the array with qsort
411 // - put back the sorted wxObject pointers into the list
413 // CAVE: the sort function receives pointers to wxObject pointers (wxObject **),
414 // so dereference right!
416 // int listcompare(const void *arg1, const void *arg2)
418 // return(compare(**(wxString **)arg1,
419 // **(wxString **)arg2));
426 // list.Append(new wxString("DEF"));
427 // list.Append(new wxString("GHI"));
428 // list.Append(new wxString("ABC"));
429 // list.Sort(listcompare);
432 void wxList::Sort(const wxSortCompareFunction compfunc
)
434 // allocate an array for the wxObject pointers of the list
435 const size_t num
= Number();
436 wxObject
**objArray
= new wxObject
*[num
];
437 wxObject
**objPtr
= objArray
;
439 // go through the list and put the pointers into the array
440 wxNode
*node
= First();
442 *objPtr
++ = node
->Data();
446 qsort((void *)objArray
,num
,sizeof(wxObject
*),compfunc
);
447 // put the sorted pointers back into the list
451 node
->SetData(*objPtr
++);
463 wxStringList::wxStringList (void):
468 // Variable argument list, terminated by a zero
469 // Makes new storage for the strings
470 wxStringList::wxStringList (const char *first
...)
475 key_type
= wxKEY_NONE
;
484 va_start (ap
, first
);
486 wxNode
*last
= new wxNode (this, NULL
, NULL
, (wxObject
*) copystring (first
));
492 char *s
= va_arg (ap
, char *);
502 wxNode
*node
= new wxNode (this, last
, NULL
, (wxObject
*) copystring (s
));
511 fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
516 wxStringList::~wxStringList (void)
518 wxNode
*each
= first_node
;
521 char *s
= (char *) each
->Data ();
523 wxNode
*next
= each
->Next ();
529 wxNode
*wxStringList::Add (const char *s
)
531 return Append ((wxObject
*) (copystring (s
)));
534 void wxStringList::Delete (const char *s
)
536 for (wxNode
* node
= First (); node
; node
= node
->Next ())
538 char *string
= (char *) node
->Data ();
539 if (string
== s
|| strcmp (string
, s
) == 0)
550 // Only makes new strings if arg is TRUE
551 char **wxStringList::ListToArray (bool new_copies
) const
553 char **string_array
= new char *[Number ()];
554 wxNode
*node
= First ();
556 for (i
= 0; i
< n
; i
++)
558 char *s
= (char *) node
->Data ();
560 string_array
[i
] = copystring (s
);
563 node
= node
->Next ();
569 wx_comparestrings (const void *arg1
, const void *arg2
)
571 char **s1
= (char **) arg1
;
572 char **s2
= (char **) arg2
;
574 return strcmp (*s1
, *s2
);
577 // Sort a list of strings - deallocates old nodes, allocates new
578 void wxStringList::Sort (void)
581 char **array
= new char *[N
];
584 for (wxNode
* node
= First (); node
; node
= node
->Next ())
585 array
[i
++] = (char *) node
->Data ();
587 qsort (array
, N
, sizeof (char *), wx_comparestrings
);
590 for (i
= 0; i
< N
; i
++)
591 Append ((wxObject
*) (array
[i
]));
596 // Checks whether s is a member of the list
597 bool wxStringList::Member (const char *s
) const
599 for (wxNode
* node
= First (); node
; node
= node
->Next ())
601 const char *s1
= (const char *) node
->Data ();
602 if (s
== s1
|| strcmp (s
, s1
) == 0)