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"
30 // Sun CC compatibility (interference with xview/pkg.h, apparently...)
31 #if defined(SUN_CC) && defined(__XVIEW__)
42 #if !USE_SHARED_LIBRARY
43 IMPLEMENT_DYNAMIC_CLASS(wxNode
, wxObject
)
44 IMPLEMENT_DYNAMIC_CLASS(wxList
, wxObject
)
45 IMPLEMENT_DYNAMIC_CLASS(wxStringList
, wxList
)
48 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
55 key
.string
= (char *) NULL
;
58 previous
->next
= this;
61 next
->previous
= this;
65 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
66 wxObject
* object
, long the_key
)
72 key
.integer
= the_key
;
75 previous
->next
= this;
78 next
->previous
= this;
81 wxNode::wxNode (wxList
* the_list
, wxNode
* last_one
, wxNode
* next_one
,
82 wxObject
* object
, const char *the_key
)
88 key
.string
= copystring (the_key
);
91 previous
->next
= this;
94 next
->previous
= this;
98 wxNode::~wxNode (void)
103 if (list
&& list
->destroy_data
)
106 if (list
&& list
->key_type
== wxKEY_STRING
&& key
.string
)
109 // Make next node point back to the previous node from here
111 next
->previous
= previous
;
113 // If there's a new end of list (deleting the last one)
114 // make sure the list knows about it.
115 list
->last_node
= previous
;
117 // Make the previous node point to the next node from here
119 previous
->next
= next
;
121 // Or if no previous node (start of list), make sure list points at
122 // the next node which becomes the first!.
124 list
->first_node
= next
;
127 wxList::wxList (void)
129 first_node
= (wxNode
*) NULL
;
130 last_node
= (wxNode
*) NULL
;
133 key_type
= wxKEY_NONE
;
136 wxList::wxList (int N
, wxObject
* Objects
[])
138 wxNode
*last
= (wxNode
*) NULL
;
141 for (i
= 0; i
< N
; i
++)
143 wxNode
*next
= new wxNode (this, last
, (wxNode
*) NULL
, Objects
[i
]);
150 key_type
= wxKEY_NONE
;
153 wxList::wxList (const unsigned int the_key_type
)
157 first_node
= (wxNode
*) NULL
;
158 last_node
= (wxNode
*) NULL
;
159 key_type
= the_key_type
;
162 // Variable argument list, terminated by a zero
163 wxList::wxList (wxObject
* first_one
...)
168 va_start (ap
, first_one
);
170 wxNode
*last
= new wxNode (this, (wxNode
*) NULL
, (wxNode
*) NULL
, first_one
);
176 wxObject
*object
= va_arg (ap
, wxObject
*);
177 // if (object == NULL) // Doesn't work in Windows -- segment is non-zero for NULL!
179 if ((int) object
== 0)
181 if ((long) object
== 0)
186 wxNode
*node
= new wxNode (this, last
, (wxNode
*) NULL
, object
);
195 key_type
= wxKEY_NONE
;
198 fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
203 wxList::~wxList (void)
205 wxNode
*each
= first_node
;
208 wxNode
*next
= each
->Next ();
214 wxNode
*wxList::Append(wxObject
*object
)
216 wxNode
*node
= new wxNode(this, last_node
, (wxNode
*) NULL
, object
);
224 wxNode
*wxList::Nth (int i
) const
227 for (wxNode
* current
= First (); current
; current
= current
->Next ())
232 return (wxNode
*) NULL
; // No such element
236 wxNode
*wxList::Find (long key
) const
238 wxNode
*current
= First();
241 if (current
->key
.integer
== key
)
243 current
= current
->Next();
246 return (wxNode
*) NULL
; // Not found!
249 wxNode
*wxList::Find (const char *key
) const
251 wxNode
*current
= First();
254 if (!current
->key
.string
)
256 wxFatalError (_("wxList: string key not present, probably did not Append correctly!"));
259 if (strcmp (current
->key
.string
, key
) == 0)
261 current
= current
->Next();
264 return (wxNode
*) NULL
; // Not found!
268 wxNode
*wxList::Member (wxObject
* object
) const
270 for (wxNode
* current
= First (); current
; current
= current
->Next ())
272 wxObject
*each
= current
->Data ();
276 return (wxNode
*) NULL
;
279 bool wxList::DeleteNode (wxNode
* node
)
289 bool wxList::DeleteObject (wxObject
* object
)
291 // Search list for object
292 for (wxNode
* current
= first_node
; current
; current
= current
->Next ())
294 if (current
->Data () == object
)
300 return FALSE
; // Did not find the object
305 // Insert new node at front of list
306 wxNode
*wxList::Insert (wxObject
* object
)
308 wxNode
*node
= new wxNode (this, (wxNode
*) NULL
, First (), object
);
311 if (!(node
->Next ()))
319 // Insert new node before given node.
320 wxNode
*wxList::Insert (wxNode
* position
, wxObject
* object
)
322 wxNode
*prev
= (wxNode
*) NULL
;
324 prev
= position
->Previous ();
326 wxNode
*node
= new wxNode (this, prev
, position
, object
);
340 wxNode
*wxList::Append (long key
, wxObject
* object
)
342 wxNode
*node
= new wxNode (this, last_node
, (wxNode
*) NULL
, object
, key
);
350 wxNode
*wxList::Append (const char *key
, wxObject
* object
)
352 wxNode
*node
= new wxNode (this, last_node
, (wxNode
*) NULL
, object
, key
);
360 void wxList::Clear (void)
362 wxNode
*current
= first_node
;
365 wxNode
*next
= current
->Next ();
369 first_node
= (wxNode
*) NULL
;
370 last_node
= (wxNode
*) NULL
;
374 //Executes function F with all items present in the list
375 void wxList::ForEach(wxListIterateFunction F
)
377 wxNode
*each
= first_node
;
379 { (*F
)( each
->Data ());
383 // Returns a pointer to the item which returns TRUE with function F
384 // or NULL if no such item found
385 wxObject
*wxList::FirstThat(wxListIterateFunction F
)
387 wxNode
*each
= first_node
;
389 { if ((*F
)( each
->Data ())) return each
->Data();
392 return (wxNode
*) NULL
;
394 // Like FirstThat, but proceeds from the end backward
395 wxObject
*wxList::LastThat(wxListIterateFunction F
)
397 wxNode
*each
= last_node
;
399 { if ((*F
)( each
->Data ())) return each
->Data();
400 each
= each
->Previous();
402 return (wxNode
*) NULL
;
405 // (stefan.hammes@urz.uni-heidelberg.de)
407 // function for sorting lists. the concept is borrowed from 'qsort'.
408 // by giving a sort function, arbitrary lists can be sorted.
410 // - put wxObject pointers into an array
411 // - sort the array with qsort
412 // - put back the sorted wxObject pointers into the list
414 // CAVE: the sort function receives pointers to wxObject pointers (wxObject **),
415 // so dereference right!
417 // int listcompare(const void *arg1, const void *arg2)
419 // return(compare(**(wxString **)arg1,
420 // **(wxString **)arg2));
427 // list.Append(new wxString("DEF"));
428 // list.Append(new wxString("GHI"));
429 // list.Append(new wxString("ABC"));
430 // list.Sort(listcompare);
433 void wxList::Sort(const wxSortCompareFunction compfunc
)
435 // allocate an array for the wxObject pointers of the list
436 const size_t num
= Number();
437 wxObject
**objArray
= new wxObject
*[num
];
438 wxObject
**objPtr
= objArray
;
440 // go through the list and put the pointers into the array
441 wxNode
*node
= First();
443 *objPtr
++ = node
->Data();
447 qsort((void *)objArray
,num
,sizeof(wxObject
*),compfunc
);
448 // put the sorted pointers back into the list
452 node
->SetData(*objPtr
++);
464 wxStringList::wxStringList (void):
469 wxStringList::wxStringList (const wxStringList
& list
)
474 // Variable argument list, terminated by a zero
475 // Makes new storage for the strings
476 wxStringList::wxStringList (const char *first
...)
481 key_type
= wxKEY_NONE
;
482 first_node
= (wxNode
*) NULL
;
483 last_node
= (wxNode
*) NULL
;
490 va_start (ap
, first
);
492 wxNode
*last
= new wxNode (this, (wxNode
*) NULL
, (wxNode
*) NULL
, (wxObject
*) copystring (first
));
498 char *s
= va_arg (ap
, char *);
508 wxNode
*node
= new wxNode (this, last
, (wxNode
*) NULL
, (wxObject
*) copystring (s
));
517 fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
522 wxStringList::~wxStringList (void)
527 void wxStringList::Clear(void)
529 wxNode
*each
= First();
532 char *s
= (char *) each
->Data ();
534 wxNode
*next
= each
->Next ();
541 wxNode
*wxStringList::Add (const char *s
)
543 return Append ((wxObject
*) (copystring (s
)));
546 void wxStringList::Delete (const char *s
)
548 for (wxNode
* node
= First (); node
; node
= node
->Next ())
550 char *string
= (char *) node
->Data ();
551 if (string
== s
|| strcmp (string
, s
) == 0)
562 // Only makes new strings if arg is TRUE
563 char **wxStringList::ListToArray (bool new_copies
) const
565 char **string_array
= new char *[Number ()];
566 wxNode
*node
= First ();
568 for (i
= 0; i
< n
; i
++)
570 char *s
= (char *) node
->Data ();
572 string_array
[i
] = copystring (s
);
575 node
= node
->Next ();
581 wx_comparestrings (const void *arg1
, const void *arg2
)
583 char **s1
= (char **) arg1
;
584 char **s2
= (char **) arg2
;
586 return strcmp (*s1
, *s2
);
589 // Sort a list of strings - deallocates old nodes, allocates new
590 void wxStringList::Sort (void)
593 char **array
= new char *[N
];
596 for (wxNode
* node
= First (); node
; node
= node
->Next ())
597 array
[i
++] = (char *) node
->Data ();
599 qsort (array
, N
, sizeof (char *), wx_comparestrings
);
602 for (i
= 0; i
< N
; i
++)
603 Append ((wxObject
*) (array
[i
]));
608 // Checks whether s is a member of the list
609 bool wxStringList::Member (const char *s
) const
611 for (wxNode
* node
= First (); node
; node
= node
->Next ())
613 const char *s1
= (const char *) node
->Data ();
614 if (s
== s1
|| strcmp (s
, s1
) == 0)
620 void wxStringList::operator= (const wxStringList
& list
)
624 wxNode
*node
= list
.First();
627 char *s
= (char *) node
->Data ();
633 char* wxStringList::operator[] (int i
) const
635 wxASSERT_MSG( (i
< Number()), "Invalid index for wxStringList" );
637 return (char*) (Nth(i
)->Data());