]> git.saurik.com Git - wxWidgets.git/blame - include/wx/list.h
Added metal styles
[wxWidgets.git] / include / wx / list.h
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: list.h
3// Purpose: wxList, wxStringList classes
4// Author: Julian Smart
fd3f686c 5// Modified by: VZ at 16/11/98: WX_DECLARE_LIST() and typesafe lists added
c801d85f
KB
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Julian Smart
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
fd3f686c
VZ
12/*
13 All this is quite ugly but serves two purposes:
14 1. Be almost 100% compatible with old, untyped, wxList class
15 2. Ensure compile-time type checking for the linked lists
16
17 The idea is to have one base class (wxListBase) working with "void *" data,
18 but to hide these untyped functions - i.e. make them protected, so they
19 can only be used from derived classes which have inline member functions
20 working with right types. This achieves the 2nd goal. As for the first one,
21 we provide a special derivation of wxListBase called wxList which looks just
22 like the old class.
23*/
24
34138703
JS
25#ifndef _WX_LISTH__
26#define _WX_LISTH__
c801d85f 27
12028905 28#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) && \
df5168c4 29 !(defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
0d3820b3 30#pragma interface "list.h"
c801d85f
KB
31#endif
32
fd3f686c
VZ
33// -----------------------------------------------------------------------------
34// headers
35// -----------------------------------------------------------------------------
36
c801d85f
KB
37#include "wx/defs.h"
38#include "wx/object.h"
3bef6c4c 39#include "wx/string.h"
c801d85f 40
df5168c4
MB
41#if wxUSE_STL
42 #include "wx/beforestd.h"
ed1288c1
VZ
43 #include <algorithm>
44 #include <iterator>
df5168c4
MB
45 #include <list>
46 #include "wx/afterstd.h"
df5168c4
MB
47#endif
48
49// ----------------------------------------------------------------------------
50// types
51// ----------------------------------------------------------------------------
52
53// type of compare function for list sort operation (as in 'qsort'): it should
54// return a negative value, 0 or positive value if the first element is less
55// than, equal or greater than the second
5e967044 56
df5168c4
MB
57extern "C"
58{
59typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2);
60}
61
bddd7a8d 62class WXDLLIMPEXP_BASE wxObjectListNode;
fd3f686c
VZ
63typedef wxObjectListNode wxNode;
64
df5168c4
MB
65//
66typedef int (* LINKAGEMODE wxListIterateFunction)(void *current);
c801d85f 67
df5168c4 68// ----------------------------------------------------------------------------
fd3f686c 69// constants
df5168c4
MB
70// ----------------------------------------------------------------------------
71
72#if !defined(wxENUM_KEY_TYPE_DEFINED)
73#define wxENUM_KEY_TYPE_DEFINED
74
fd3f686c
VZ
75enum wxKeyType
76{
77 wxKEY_NONE,
78 wxKEY_INTEGER,
79 wxKEY_STRING
80};
81
df5168c4 82#endif
fd3f686c 83
df5168c4 84#if wxUSE_STL
fd3f686c 85
df5168c4
MB
86#define wxLIST_COMPATIBILITY
87
88#define WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl) \
f794be6a 89 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
6de44038
VZ
90#define WX_DECLARE_LIST_PTR_3(elT, dummy1, liT, dummy2, decl) \
91 WX_DECLARE_LIST_3(elT, dummy1, liT, dummy2, decl)
df5168c4
MB
92
93#define WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
f794be6a 94 WX_DECLARE_LIST_WITH_DECL(elT, liT, decl)
6de44038
VZ
95#define WX_DECLARE_LIST_PTR_2(elT, liT, dummy, decl) \
96 WX_DECLARE_LIST_2(elT, liT, dummy, decl) \
df5168c4 97
f794be6a 98#define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \
df5168c4
MB
99 WX_DECLARE_LIST_XO(elT*, liT, decl)
100
ed1288c1 101#define WX_DECLARE_LIST_XO(elT, liT, decl) \
df5168c4
MB
102 decl liT : public std::list<elT> \
103 { \
ed1288c1
VZ
104 private: \
105 bool m_destroy; \
106 private: \
107 class SortCompareFunction \
108 { \
109 private: \
110 wxSortCompareFunction m_CompFunc; \
111 public: \
112 SortCompareFunction( wxSortCompareFunction compfunc ) \
113 : m_CompFunc( compfunc ) {} \
114 bool operator()( const elT X, const elT Y ) const \
115 { return ( m_CompFunc( X, Y ) < 0 ); } \
116 }; \
df5168c4 117 \
ed1288c1
VZ
118 typedef elT _WX_LIST_ITEM_TYPE_##liT; \
119 static void DeleteFunction( const _WX_LIST_ITEM_TYPE_##liT X ); \
120 public: \
121 class compatibility_iterator \
df5168c4 122 { \
ed1288c1
VZ
123 private: \
124 typedef liT::iterator iterator; \
125 friend class liT; \
126 private: \
df5168c4
MB
127 iterator m_iter; \
128 liT * m_list; \
129 public: \
ed1288c1
VZ
130 compatibility_iterator() \
131 : m_iter(), m_list( NULL ) {} \
132 compatibility_iterator( liT* li, iterator i ) \
133 : m_iter( i ), m_list( li ) {} \
134 compatibility_iterator( const liT* li, iterator i ) \
135 : m_iter( i ), m_list( const_cast< liT* >( li ) ) {} \
136 \
137 compatibility_iterator* operator->() { return this; } \
138 const compatibility_iterator* operator->() const { return this; } \
139 \
140 bool operator==(const compatibility_iterator& i) \
141 { return (m_list == i.m_list) && (m_iter == i.m_iter); } \
142 bool operator!=(const compatibility_iterator& i) \
143 { return !( operator==( i ) ); } \
df5168c4 144 operator bool() const \
ed1288c1 145 { return m_list ? m_iter != m_list->end() : false; } \
df5168c4 146 bool operator !() const \
ed1288c1 147 { return !( operator bool() ); } \
df5168c4 148 \
df5168c4 149 elT GetData() const \
ed1288c1
VZ
150 { return *m_iter; } \
151 void SetData( elT e ) \
152 { *m_iter = e; } \
153 \
154 compatibility_iterator GetNext() const \
df5168c4 155 { \
ed1288c1
VZ
156 iterator i = m_iter; \
157 return compatibility_iterator( m_list, ++i ); \
df5168c4 158 } \
ed1288c1 159 compatibility_iterator GetPrevious() const \
df5168c4 160 { \
ed1288c1
VZ
161 iterator i = m_iter; \
162 return compatibility_iterator( m_list, --i ); \
df5168c4 163 } \
ed1288c1 164 int IndexOf() const \
df5168c4 165 { \
ed1288c1
VZ
166 return m_list ? \
167 m_iter != m_list->end() ? \
168 std::distance( m_list->begin(), m_iter ) : \
169 wxNOT_FOUND : \
170 wxNOT_FOUND; \
df5168c4 171 } \
df5168c4 172 }; \
ed1288c1
VZ
173 public: \
174 liT() : m_destroy( false ) {} \
175 \
176 compatibility_iterator Find( const elT e ) const \
df5168c4 177 { \
ed1288c1
VZ
178 liT* _this = const_cast< liT* >( this ); \
179 return compatibility_iterator( _this, \
180 std::find( _this->begin(), _this->end(), e ) ); \
df5168c4 181 } \
df5168c4 182 \
ed1288c1
VZ
183 bool IsEmpty() const \
184 { return empty(); } \
185 size_t GetCount() const \
186 { return size(); } \
187 int Number() const \
188 { return static_cast< int >( GetCount() ); } \
189 \
190 compatibility_iterator Item( size_t idx ) const \
df5168c4 191 { \
ed1288c1
VZ
192 iterator i = const_cast< liT* >(this)->begin(); \
193 std::advance( i, idx ); \
194 return compatibility_iterator( this, i ); \
195 } \
196 compatibility_iterator GetFirst() const \
197 { \
198 return compatibility_iterator( this, \
199 const_cast< liT* >(this)->begin() ); \
200 } \
201 compatibility_iterator GetLast() const \
202 { \
203 iterator i = const_cast< liT* >(this)->end(); \
204 return compatibility_iterator( this, !empty() ? --i : i ); \
205 } \
206 compatibility_iterator Member( elT e ) const \
207 { return Find( e ); } \
208 compatibility_iterator Nth( int n ) const \
209 { return Item( n ); } \
210 int IndexOf( elT e ) const \
211 { return Find( e ).IndexOf(); } \
212 \
213 compatibility_iterator Append( elT e ) \
214 { \
215 push_back( e ); \
216 return GetLast(); \
217 } \
218 compatibility_iterator Insert( elT e ) \
219 { \
220 push_front( e ); \
221 return compatibility_iterator( this, begin() ); \
222 } \
223 compatibility_iterator Insert( compatibility_iterator & i, elT e ) \
224 { \
225 return compatibility_iterator( this, insert( i.m_iter, e ) ); \
226 } \
227 compatibility_iterator Insert( size_t idx, elT e ) \
228 { \
229 return compatibility_iterator( this, \
230 insert( Item( idx ).m_iter, e ) ); \
231 } \
232 \
233 void DeleteContents( bool destroy ) \
234 { m_destroy = destroy; } \
235 bool GetDeleteContents() const \
236 { return m_destroy; } \
237 void Erase( const compatibility_iterator& i ) \
238 { \
239 if ( m_destroy ) \
240 DeleteFunction( i->GetData() ); \
241 erase( i.m_iter ); \
242 } \
243 bool DeleteNode( const compatibility_iterator& i ) \
244 { \
245 if( i ) \
df5168c4 246 { \
ed1288c1 247 Erase( i ); \
df5168c4
MB
248 return true; \
249 } \
250 return false; \
251 } \
ed1288c1 252 bool DeleteObject( elT e ) \
df5168c4 253 { \
ed1288c1 254 return DeleteNode( Find( e ) ); \
df5168c4 255 } \
ed1288c1 256 void Clear() \
df5168c4 257 { \
ed1288c1
VZ
258 if ( m_destroy ) \
259 std::for_each( begin(), end(), DeleteFunction ); \
260 clear(); \
df5168c4 261 } \
ed1288c1
VZ
262 \
263 void Sort( wxSortCompareFunction compfunc ) \
264 { sort( SortCompareFunction( compfunc ) ); } \
265 \
266 ~liT() { Clear(); } \
df5168c4
MB
267 }
268
269#define WX_DECLARE_LIST(elementtype, listname) \
f794be6a 270 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class)
6de44038
VZ
271#define WX_DECLARE_LIST_PTR(elementtype, listname) \
272 WX_DECLARE_LIST(elementtype, listname)
df5168c4
MB
273
274#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
f794be6a 275 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
6de44038
VZ
276#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
277 WX_DECLARE_EXPORTED_LIST(elementtype, listname)
df5168c4
MB
278
279#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
f794be6a 280 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class usergoo)
6de44038
VZ
281#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
282 WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo)
df5168c4
MB
283
284// this macro must be inserted in your program after
285// #include <wx/listimpl.cpp>
286#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
287
288#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
289#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
290
291#else // if !wxUSE_STL
292
293// due to circular header dependencies this function has to be declared here
294// (normally it's found in utils.h which includes itself list.h...)
0bd4d463 295#if WXWIN_COMPATIBILITY_2_4
ff98bd68 296extern WXDLLIMPEXP_BASE wxChar* copystring(const wxChar *s);
0bd4d463 297#endif
df5168c4
MB
298
299class WXDLLEXPORT wxObjectListNode;
300typedef wxObjectListNode wxNode;
301
302// undef it to get rid of old, deprecated functions
303#define wxLIST_COMPATIBILITY
fd3f686c
VZ
304
305// -----------------------------------------------------------------------------
306// key stuff: a list may be optionally keyed on integer or string key
307// -----------------------------------------------------------------------------
308
309union wxListKeyValue
c801d85f 310{
c801d85f 311 long integer;
9d2f3c71 312 wxChar *string;
c801d85f
KB
313};
314
fd3f686c
VZ
315// a struct which may contain both types of keys
316//
317// implementation note: on one hand, this class allows to have only one function
318// for any keyed operation instead of 2 almost equivalent. OTOH, it's needed to
319// resolve ambiguity which we would otherwise have with wxStringList::Find() and
320// wxList::Find(const char *).
bddd7a8d 321class WXDLLIMPEXP_BASE wxListKey
fd3f686c
VZ
322{
323public:
324 // implicit ctors
f2af4afb
GD
325 wxListKey() : m_keyType(wxKEY_NONE)
326 { }
327 wxListKey(long i) : m_keyType(wxKEY_INTEGER)
328 { m_key.integer = i; }
329 wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING)
330 { m_key.string = wxStrdup(s); }
331 wxListKey(const wxString& s) : m_keyType(wxKEY_STRING)
332 { m_key.string = wxStrdup(s.c_str()); }
fd3f686c
VZ
333
334 // accessors
335 wxKeyType GetKeyType() const { return m_keyType; }
9d2f3c71 336 const wxChar *GetString() const
fd3f686c
VZ
337 { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; }
338 long GetNumber() const
339 { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; }
340
6164d85e
JS
341 // comparison
342 // Note: implementation moved to list.cpp to prevent BC++ inline
343 // expansion warning.
344 bool operator==(wxListKeyValue value) const ;
fd3f686c
VZ
345
346 // dtor
347 ~wxListKey()
348 {
349 if ( m_keyType == wxKEY_STRING )
350 free(m_key.string);
351 }
352
353private:
354 wxKeyType m_keyType;
355 wxListKeyValue m_key;
356};
357
358// -----------------------------------------------------------------------------
359// wxNodeBase class is a (base for) node in a double linked list
360// -----------------------------------------------------------------------------
361
16cba29d 362extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey;
2432b92d 363
bddd7a8d 364class WXDLLIMPEXP_BASE wxListBase;
fbfb3fb3 365
bddd7a8d 366class WXDLLIMPEXP_BASE wxNodeBase
fd3f686c
VZ
367{
368friend class wxListBase;
369public:
370 // ctor
371 wxNodeBase(wxListBase *list = (wxListBase *)NULL,
372 wxNodeBase *previous = (wxNodeBase *)NULL,
373 wxNodeBase *next = (wxNodeBase *)NULL,
374 void *data = NULL,
2432b92d 375 const wxListKey& key = wxDefaultListKey);
fd3f686c
VZ
376
377 virtual ~wxNodeBase();
378
f03fc89f 379 // FIXME no check is done that the list is really keyed on strings
9d2f3c71 380 const wxChar *GetKeyString() const { return m_key.string; }
74e34480 381 long GetKeyInteger() const { return m_key.integer; }
fd3f686c 382
4fabb575 383 // Necessary for some existing code
9d2f3c71 384 void SetKeyString(wxChar* s) { m_key.string = s; }
4fabb575
JS
385 void SetKeyInteger(long i) { m_key.integer = i; }
386
fd3f686c 387#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
388 // compatibility methods, use Get* instead.
389 wxDEPRECATED( wxNode *Next() const );
390 wxDEPRECATED( wxNode *Previous() const );
391 wxDEPRECATED( wxObject *Data() const );
fd3f686c
VZ
392#endif // wxLIST_COMPATIBILITY
393
394protected:
395 // all these are going to be "overloaded" in the derived classes
396 wxNodeBase *GetNext() const { return m_next; }
397 wxNodeBase *GetPrevious() const { return m_previous; }
398
399 void *GetData() const { return m_data; }
400 void SetData(void *data) { m_data = data; }
401
3c67202d 402 // get 0-based index of this node within the list or wxNOT_FOUND
77c5eefb
VZ
403 int IndexOf() const;
404
fd3f686c 405 virtual void DeleteData() { }
df5168c4
MB
406public:
407 // for wxList::iterator
408 void** GetDataPtr() const { return &(((wxNodeBase*)this)->m_data); }
fd3f686c
VZ
409private:
410 // optional key stuff
411 wxListKeyValue m_key;
412
413 void *m_data; // user data
414 wxNodeBase *m_next, // next and previous nodes in the list
415 *m_previous;
416
417 wxListBase *m_list; // list we belong to
f2af4afb
GD
418
419 DECLARE_NO_COPY_CLASS(wxNodeBase)
fd3f686c
VZ
420};
421
422// -----------------------------------------------------------------------------
423// a double-linked list class
424// -----------------------------------------------------------------------------
f98bd52a 425
446e5259 426class WXDLLIMPEXP_BASE wxList;
b1d4dd7a 427
bddd7a8d 428class WXDLLIMPEXP_BASE wxListBase : public wxObject
fd3f686c 429{
bddd7a8d 430friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode()
bcaa23de 431friend class wxHashTableBase; // should be able to call untyped Find()
788722ac
JS
432private:
433 // common part of all ctors
434 void Init(wxKeyType keyType = wxKEY_NONE); // Must be declared before it's used (for VC++ 1.5)
fd3f686c
VZ
435public:
436 // default ctor & dtor
f2af4afb
GD
437 wxListBase(wxKeyType keyType = wxKEY_NONE)
438 { Init(keyType); }
fd3f686c
VZ
439 virtual ~wxListBase();
440
441 // accessors
442 // count of items in the list
443 size_t GetCount() const { return m_count; }
c801d85f 444
f644b28c 445 // return true if this list is empty
b79a8705
VZ
446 bool IsEmpty() const { return m_count == 0; }
447
fd3f686c 448 // operations
e146b8c8 449
fd3f686c 450 // delete all nodes
db9504c5 451 void Clear();
e146b8c8 452
fd3f686c
VZ
453 // instruct it to destroy user data when deleting nodes
454 void DeleteContents(bool destroy) { m_destroy = destroy; }
455
907789a0
RR
456 // query if to delete
457 bool GetDeleteContents() const
458 { return m_destroy; }
e146b8c8 459
907789a0
RR
460 // get the keytype
461 wxKeyType GetKeyType() const
462 { return m_keyType; }
463
464 // set the keytype (required by the serial code)
465 void SetKeyType(wxKeyType keyType)
466 { wxASSERT( m_count==0 ); m_keyType = keyType; }
467
e146b8c8 468#ifdef wxLIST_COMPATIBILITY
b1d4dd7a
RL
469 // compatibility methods from old wxList
470 wxDEPRECATED( int Number() const ); // use GetCount instead.
471 wxDEPRECATED( wxNode *First() const ); // use GetFirst
472 wxDEPRECATED( wxNode *Last() const ); // use GetLast
473 wxDEPRECATED( wxNode *Nth(size_t n) const ); // use Item
474
475 // kludge for typesafe list migration in core classes.
476 wxDEPRECATED( operator wxList&() const );
e146b8c8
VZ
477#endif // wxLIST_COMPATIBILITY
478
fd3f686c 479protected:
a3ef5bf5 480
fd3f686c
VZ
481 // all methods here are "overloaded" in derived classes to provide compile
482 // time type checking
483
484 // create a node for the list of this type
485 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next,
486 void *data,
2432b92d 487 const wxListKey& key = wxDefaultListKey) = 0;
fd3f686c 488
a3ef5bf5
JS
489// Can't access these from derived classes otherwise (bug in Salford C++?)
490#ifdef __SALFORDC__
491public:
492#endif
493
fd3f686c
VZ
494 // ctors
495 // from an array
496 wxListBase(size_t count, void *elements[]);
497 // from a sequence of objects
498 wxListBase(void *object, ... /* terminate with NULL */);
499
a3ef5bf5 500protected:
00e09270
VZ
501 void Assign(const wxListBase& list)
502 { Clear(); DoCopy(list); }
fd3f686c
VZ
503
504 // get list head/tail
505 wxNodeBase *GetFirst() const { return m_nodeFirst; }
506 wxNodeBase *GetLast() const { return m_nodeLast; }
507
508 // by (0-based) index
509 wxNodeBase *Item(size_t index) const;
510
511 // get the list item's data
2b5f62a0
VZ
512 void *operator[](size_t n) const
513 {
514 wxNodeBase *node = Item(n);
515
516 return node ? node->GetData() : (wxNodeBase *)NULL;
517 }
fd3f686c
VZ
518
519 // operations
520 // append to end of list
890f8a7c
RR
521 wxNodeBase *Prepend(void *object)
522 { return (wxNodeBase *)wxListBase::Insert(object); }
523 // append to beginning of list
fd3f686c
VZ
524 wxNodeBase *Append(void *object);
525 // insert a new item at the beginning of the list
a802c3a1 526 wxNodeBase *Insert(void *object) { return Insert( (wxNodeBase*)NULL, object); }
d8996187
VZ
527 // insert a new item at the given position
528 wxNodeBase *Insert(size_t pos, void *object)
529 { return pos == GetCount() ? Append(object)
530 : Insert(Item(pos), object); }
fd3f686c
VZ
531 // insert before given node or at front of list if prev == NULL
532 wxNodeBase *Insert(wxNodeBase *prev, void *object);
533
534 // keyed append
535 wxNodeBase *Append(long key, void *object);
9d2f3c71 536 wxNodeBase *Append(const wxChar *key, void *object);
fd3f686c
VZ
537
538 // removes node from the list but doesn't delete it (returns pointer
539 // to the node or NULL if it wasn't found in the list)
540 wxNodeBase *DetachNode(wxNodeBase *node);
f644b28c 541 // delete element from list, returns false if node not found
fd3f686c
VZ
542 bool DeleteNode(wxNodeBase *node);
543 // finds object pointer and deletes node (and object if DeleteContents
f644b28c 544 // is on), returns false if object not found
77c5eefb 545 bool DeleteObject(void *object);
fd3f686c
VZ
546
547 // search (all return NULL if item not found)
548 // by data
22d080f3 549 wxNodeBase *Find(const void *object) const;
fd3f686c
VZ
550
551 // by key
552 wxNodeBase *Find(const wxListKey& key) const;
553
3c67202d 554 // get 0-based index of object or wxNOT_FOUND
77c5eefb
VZ
555 int IndexOf( void *object ) const;
556
fd3f686c
VZ
557 // this function allows the sorting of arbitrary lists by giving
558 // a function to compare two list elements. The list is sorted in place.
6164d85e 559 void Sort(const wxSortCompareFunction compfunc);
fd3f686c
VZ
560
561 // functions for iterating over the list
562 void *FirstThat(wxListIterateFunction func);
563 void ForEach(wxListIterateFunction func);
564 void *LastThat(wxListIterateFunction func);
e146b8c8 565
df5168c4
MB
566 // for STL interface, "last" points to one after the last node
567 // of the controlled sequence (NULL for the end of the list)
568 void Reverse();
569 void DeleteNodes(wxNodeBase* first, wxNodeBase* last);
fd3f686c
VZ
570private:
571 // helpers
fd3f686c
VZ
572 // common part of copy ctor and assignment operator
573 void DoCopy(const wxListBase& list);
574 // common part of all Append()s
575 wxNodeBase *AppendCommon(wxNodeBase *node);
576 // free node's data and node itself
577 void DoDeleteNode(wxNodeBase *node);
578
579 size_t m_count; // number of elements in the list
580 bool m_destroy; // destroy user data when deleting list items?
581 wxNodeBase *m_nodeFirst, // pointers to the head and tail of the list
582 *m_nodeLast;
583
584 wxKeyType m_keyType; // type of our keys (may be wxKEY_NONE)
585};
586
587// -----------------------------------------------------------------------------
588// macros for definition of "template" list type
589// -----------------------------------------------------------------------------
590
591// and now some heavy magic...
592
593// declare a list type named 'name' and containing elements of type 'T *'
594// (as a by product of macro expansion you also get wx##name##Node
ce3ed50d 595// wxNode-derived type)
fd3f686c
VZ
596//
597// implementation details:
ce3ed50d 598// 1. We define _WX_LIST_ITEM_TYPE_##name typedef to save in it the item type
fd3f686c
VZ
599// for the list of given type - this allows us to pass only the list name
600// to WX_DEFINE_LIST() even if it needs both the name and the type
601//
ce3ed50d
JS
602// 2. We redefine all non-type-safe wxList functions with type-safe versions
603// which don't take any space (everything is inline), but bring compile
fd3f686c 604// time error checking.
f03fc89f
VZ
605//
606// 3. The macro which is usually used (WX_DECLARE_LIST) is defined in terms of
607// a more generic WX_DECLARE_LIST_2 macro which, in turn, uses the most
608// generic WX_DECLARE_LIST_3 one. The last macro adds a sometimes
609// interesting capability to store polymorphic objects in the list and is
610// particularly useful with, for example, "wxWindow *" list where the
611// wxWindowBase pointers are put into the list, but wxWindow pointers are
612// retrieved from it.
6de44038
VZ
613//
614// 4. final hack is that WX_DECLARE_LIST_3 is defined in terms of
615// WX_DECLARE_LIST_4 to allow defining classes without operator->() as
616// it results in compiler warnings when this operator doesn't make sense
617// (i.e. stored elements are not pointers)
f03fc89f 618
6de44038
VZ
619// common part of WX_DECLARE_LIST_3 and WX_DECLARE_LIST_PTR_3
620#define WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, ptrop) \
ba059d80 621 typedef int (*wxSortFuncFor_##name)(const T **, const T **); \
fd3f686c 622 \
f6bcfd97 623 classexp nodetype : public wxNodeBase \
fd3f686c
VZ
624 { \
625 public: \
626 nodetype(wxListBase *list = (wxListBase *)NULL, \
627 nodetype *previous = (nodetype *)NULL, \
628 nodetype *next = (nodetype *)NULL, \
7f985bd3 629 T *data = (T *)NULL, \
e146b8c8 630 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
631 : wxNodeBase(list, previous, next, data, key) { } \
632 \
633 nodetype *GetNext() const \
634 { return (nodetype *)wxNodeBase::GetNext(); } \
635 nodetype *GetPrevious() const \
636 { return (nodetype *)wxNodeBase::GetPrevious(); } \
637 \
638 T *GetData() const \
639 { return (T *)wxNodeBase::GetData(); } \
640 void SetData(T *data) \
641 { wxNodeBase::SetData(data); } \
642 \
643 virtual void DeleteData(); \
cd989b24
VZ
644 \
645 DECLARE_NO_COPY_CLASS(nodetype) \
fd3f686c
VZ
646 }; \
647 \
f6bcfd97 648 classexp name : public wxListBase \
fd3f686c
VZ
649 { \
650 public: \
e2a3cc0c 651 typedef nodetype Node; \
df5168c4 652 typedef Node* compatibility_iterator; \
e2a3cc0c 653 \
fd3f686c
VZ
654 name(wxKeyType keyType = wxKEY_NONE) : wxListBase(keyType) \
655 { } \
00e09270
VZ
656 name(const name& list) : wxListBase(list.GetKeyType()) \
657 { Assign(list); } \
fd3f686c
VZ
658 name(size_t count, T *elements[]) \
659 : wxListBase(count, (void **)elements) { } \
660 \
f6bcfd97 661 name& operator=(const name& list) \
00e09270 662 { Assign(list); return *this; } \
f6bcfd97 663 \
fd3f686c
VZ
664 nodetype *GetFirst() const \
665 { return (nodetype *)wxListBase::GetFirst(); } \
666 nodetype *GetLast() const \
667 { return (nodetype *)wxListBase::GetLast(); } \
668 \
669 nodetype *Item(size_t index) const \
670 { return (nodetype *)wxListBase::Item(index); } \
671 \
672 T *operator[](size_t index) const \
673 { \
674 nodetype *node = Item(index); \
7f985bd3 675 return node ? (T*)(node->GetData()) : (T*)NULL; \
fd3f686c
VZ
676 } \
677 \
f03fc89f 678 nodetype *Append(Tbase *object) \
fd3f686c 679 { return (nodetype *)wxListBase::Append(object); } \
f03fc89f 680 nodetype *Insert(Tbase *object) \
a802c3a1 681 { return (nodetype *)Insert((nodetype*)NULL, object); } \
d8996187
VZ
682 nodetype *Insert(size_t pos, Tbase *object) \
683 { return (nodetype *)wxListBase::Insert(pos, object); } \
f03fc89f 684 nodetype *Insert(nodetype *prev, Tbase *object) \
fd3f686c
VZ
685 { return (nodetype *)wxListBase::Insert(prev, object); } \
686 \
687 nodetype *Append(long key, void *object) \
688 { return (nodetype *)wxListBase::Append(key, object); } \
9d2f3c71 689 nodetype *Append(const wxChar *key, void *object) \
fd3f686c
VZ
690 { return (nodetype *)wxListBase::Append(key, object); } \
691 \
692 nodetype *DetachNode(nodetype *node) \
693 { return (nodetype *)wxListBase::DetachNode(node); } \
694 bool DeleteNode(nodetype *node) \
695 { return wxListBase::DeleteNode(node); } \
f03fc89f 696 bool DeleteObject(Tbase *object) \
fd3f686c 697 { return wxListBase::DeleteObject(object); } \
df5168c4
MB
698 void Erase(compatibility_iterator it) \
699 { DeleteNode(it); } \
fd3f686c 700 \
22d080f3 701 nodetype *Find(const Tbase *object) const \
fd3f686c
VZ
702 { return (nodetype *)wxListBase::Find(object); } \
703 \
704 virtual nodetype *Find(const wxListKey& key) const \
705 { return (nodetype *)wxListBase::Find(key); } \
706 \
f03fc89f 707 int IndexOf(Tbase *object) const \
77c5eefb
VZ
708 { return wxListBase::IndexOf(object); } \
709 \
ed1288c1
VZ
710 void Sort(wxSortCompareFunction func) \
711 { wxListBase::Sort(func); } \
fd3f686c 712 void Sort(wxSortFuncFor_##name func) \
ed1288c1 713 { Sort((wxSortCompareFunction)func); } \
fd3f686c
VZ
714 \
715 protected: \
ea48aff3 716 virtual wxNodeBase *CreateNode(wxNodeBase *prev, wxNodeBase *next, \
fd3f686c 717 void *data, \
e146b8c8 718 const wxListKey& key = wxDefaultListKey) \
fd3f686c
VZ
719 { \
720 return new nodetype(this, \
721 (nodetype *)prev, (nodetype *)next, \
722 (T *)data, key); \
723 } \
df5168c4
MB
724 /* STL interface */ \
725 public: \
726 typedef size_t size_type; \
727 typedef int difference_type; \
728 typedef T* value_type; \
729 typedef Tbase* base_value_type; \
730 typedef value_type& reference; \
731 typedef const value_type& const_reference; \
732 typedef base_value_type& base_reference; \
733 typedef const base_value_type& const_base_reference; \
734 \
735 class iterator \
736 { \
737 typedef name list; \
738 public: \
37589419 739 typedef nodetype Node; \
df5168c4 740 typedef iterator itor; \
37589419
MB
741 typedef T* value_type; \
742 typedef value_type* ptr_type; \
743 typedef value_type& reference; \
df5168c4
MB
744 \
745 Node* m_node; \
746 Node* m_init; \
747 public: \
37589419 748 typedef reference reference_type; \
df5168c4
MB
749 typedef ptr_type pointer_type; \
750 \
751 iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\
752 iterator() : m_node(NULL), m_init(NULL) { } \
753 reference_type operator*() const \
754 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 755 ptrop \
df5168c4
MB
756 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
757 itor operator++(int) \
758 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
759 itor& operator--() \
760 { \
761 m_node = m_node ? m_node->GetPrevious() : m_init; \
762 return *this; \
763 } \
764 itor operator--(int) \
765 { \
766 itor tmp = *this; \
767 m_node = m_node ? m_node->GetPrevious() : m_init; \
768 return tmp; \
769 } \
770 bool operator!=(const itor& it) const \
771 { return it.m_node != m_node; } \
772 bool operator==(const itor& it) const \
773 { return it.m_node == m_node; } \
774 }; \
775 class const_iterator \
776 { \
777 typedef name list; \
778 public: \
37589419
MB
779 typedef nodetype Node; \
780 typedef T* value_type; \
781 typedef const value_type& const_reference; \
df5168c4 782 typedef const_iterator itor; \
37589419 783 typedef value_type* ptr_type; \
df5168c4
MB
784 \
785 Node* m_node; \
786 Node* m_init; \
787 public: \
37589419 788 typedef const_reference reference_type; \
df5168c4
MB
789 typedef const ptr_type pointer_type; \
790 \
791 const_iterator(Node* node, Node* init) \
792 : m_node(node), m_init(init) { } \
793 const_iterator() : m_node(NULL), m_init(NULL) { } \
794 const_iterator(const iterator& it) \
795 : m_node(it.m_node), m_init(it.m_init) { } \
796 reference_type operator*() const \
797 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 798 ptrop \
df5168c4
MB
799 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
800 itor operator++(int) \
801 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
802 itor& operator--() \
803 { \
804 m_node = m_node ? m_node->GetPrevious() : m_init; \
805 return *this; \
806 } \
807 itor operator--(int) \
808 { \
809 itor tmp = *this; \
810 m_node = m_node ? m_node->GetPrevious() : m_init; \
811 return tmp; \
812 } \
813 bool operator!=(const itor& it) const \
814 { return it.m_node != m_node; } \
815 bool operator==(const itor& it) const \
816 { return it.m_node == m_node; } \
817 }; \
818 class reverse_iterator \
819 { \
820 typedef name list; \
821 public: \
37589419
MB
822 typedef nodetype Node; \
823 typedef T* value_type; \
df5168c4 824 typedef reverse_iterator itor; \
37589419
MB
825 typedef value_type* ptr_type; \
826 typedef value_type& reference; \
df5168c4
MB
827 \
828 Node* m_node; \
829 Node* m_init; \
830 public: \
37589419 831 typedef reference reference_type; \
df5168c4
MB
832 typedef ptr_type pointer_type; \
833 \
834 reverse_iterator(Node* node, Node* init) \
835 : m_node(node), m_init(init) { } \
836 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
837 reference_type operator*() const \
838 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 839 ptrop \
df5168c4
MB
840 itor& operator++() \
841 { m_node = m_node->GetPrevious(); return *this; } \
842 itor operator++(int) \
843 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
844 itor& operator--() \
845 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
846 itor operator--(int) \
847 { \
848 itor tmp = *this; \
849 m_node = m_node ? m_node->GetNext() : m_init; \
850 return tmp; \
851 } \
852 bool operator!=(const itor& it) const \
853 { return it.m_node != m_node; } \
854 bool operator==(const itor& it) const \
855 { return it.m_node == m_node; } \
856 }; \
857 class const_reverse_iterator \
858 { \
859 typedef name list; \
860 public: \
37589419
MB
861 typedef nodetype Node; \
862 typedef T* value_type; \
df5168c4 863 typedef const_reverse_iterator itor; \
37589419
MB
864 typedef value_type* ptr_type; \
865 typedef const value_type& const_reference; \
df5168c4
MB
866 \
867 Node* m_node; \
868 Node* m_init; \
869 public: \
37589419 870 typedef const_reference reference_type; \
df5168c4
MB
871 typedef const ptr_type pointer_type; \
872 \
873 const_reverse_iterator(Node* node, Node* init) \
874 : m_node(node), m_init(init) { } \
875 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
876 const_reverse_iterator(const reverse_iterator& it) \
877 : m_node(it.m_node), m_init(it.m_init) { } \
878 reference_type operator*() const \
879 { return *(pointer_type)m_node->GetDataPtr(); } \
6de44038 880 ptrop \
df5168c4
MB
881 itor& operator++() \
882 { m_node = m_node->GetPrevious(); return *this; } \
883 itor operator++(int) \
884 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
885 itor& operator--() \
886 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
887 itor operator--(int) \
888 { \
889 itor tmp = *this; \
890 m_node = m_node ? m_node->GetNext() : m_init; \
891 return tmp; \
892 } \
893 bool operator!=(const itor& it) const \
894 { return it.m_node != m_node; } \
895 bool operator==(const itor& it) const \
896 { return it.m_node == m_node; } \
897 }; \
898 \
899 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
900 { assign(n, v); } \
901 name(const_iterator first, const_iterator last) \
902 { assign(first, last); } \
903 iterator begin() { return iterator(GetFirst(), GetLast()); } \
904 const_iterator begin() const \
905 { return const_iterator(GetFirst(), GetLast()); } \
906 iterator end() { return iterator(NULL, GetLast()); } \
907 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
908 reverse_iterator rbegin() \
909 { return reverse_iterator(GetLast(), GetFirst()); } \
910 const_reverse_iterator rbegin() const \
911 { return const_reverse_iterator(GetLast(), GetFirst()); } \
912 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
913 const_reverse_iterator rend() const \
914 { return const_reverse_iterator(NULL, GetFirst()); } \
915 void resize(size_type n, value_type v = value_type()) \
916 { \
5751dd32
JS
917 while (n < size()) \
918 pop_back(); \
919 while (n > size()) \
d56cc7b1 920 push_back(v); \
df5168c4
MB
921 } \
922 size_type size() const { return GetCount(); } \
923 size_type max_size() const { return INT_MAX; } \
924 bool empty() const { return IsEmpty(); } \
925 reference front() { return *begin(); } \
926 const_reference front() const { return *begin(); } \
927 reference back() { return *--end(); } \
928 const_reference back() const { return *--end(); } \
929 void push_front(const_reference v = value_type()) \
930 { Insert(GetFirst(), (const_base_reference)v); } \
931 void pop_front() { DeleteNode(GetFirst()); } \
932 void push_back(const_reference v = value_type()) \
933 { Append((const_base_reference)v); } \
934 void pop_back() { DeleteNode(GetLast()); } \
935 void assign(const_iterator first, const_iterator last) \
936 { \
937 clear(); \
938 for(; first != last; ++first) \
939 Append((const_base_reference)*first); \
940 } \
941 void assign(size_type n, const_reference v = value_type()) \
942 { \
943 clear(); \
944 for(size_type i = 0; i < n; ++i) \
945 Append((const_base_reference)v); \
946 } \
947 iterator insert(iterator it, const_reference v = value_type()) \
948 { \
949 Insert(it.m_node, (const_base_reference)v); \
950 return iterator(it.m_node->GetPrevious(), GetLast()); \
951 } \
952 void insert(iterator it, size_type n, const_reference v = value_type())\
953 { \
954 for(size_type i = 0; i < n; ++i) \
955 Insert(it.m_node, (const_base_reference)v); \
956 } \
957 void insert(iterator it, const_iterator first, const_iterator last) \
958 { \
959 for(; first != last; ++first) \
960 Insert(it.m_node, (const_base_reference)*first); \
961 } \
962 iterator erase(iterator it) \
963 { \
964 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
965 DeleteNode(it.m_node); return next; \
966 } \
967 iterator erase(iterator first, iterator last) \
968 { \
969 iterator next = last; ++next; \
970 DeleteNodes(first.m_node, last.m_node); \
971 return next; \
972 } \
973 void clear() { Clear(); } \
974 void splice(iterator it, name& l, iterator first, iterator last) \
975 { insert(it, first, last); l.erase(first, last); } \
976 void splice(iterator it, name& l) \
977 { splice(it, l, l.begin(), l.end() ); } \
978 void splice(iterator it, name& l, iterator first) \
979 { \
980 iterator tmp = first; ++tmp; \
981 if(it == first || it == tmp) return; \
982 insert(it, *first); \
983 l.erase(first); \
984 } \
985 void remove(const_reference v) \
986 { DeleteObject((const_base_reference)v); } \
987 void reverse() \
988 { Reverse(); } \
989 /* void swap(name& l) \
990 { \
991 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
992 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
993 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
994 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
995 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
996 } */ \
385bcb35 997 }
fd3f686c 998
6de44038
VZ
999#define WX_LIST_PTROP \
1000 pointer_type operator->() const \
1001 { return (pointer_type)m_node->GetDataPtr(); }
1002#define WX_LIST_PTROP_NONE
1003
1004#define WX_DECLARE_LIST_3(T, Tbase, name, nodetype, classexp) \
1005 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP_NONE)
1006#define WX_DECLARE_LIST_PTR_3(T, Tbase, name, nodetype, classexp) \
1007 WX_DECLARE_LIST_4(T, Tbase, name, nodetype, classexp, WX_LIST_PTROP)
1008
f6bcfd97
BP
1009#define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
1010 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
6de44038
VZ
1011#define WX_DECLARE_LIST_PTR_2(elementtype, listname, nodename, classexp) \
1012 WX_DECLARE_LIST_PTR_3(elementtype, elementtype, listname, nodename, classexp)
f03fc89f 1013
fd3f686c
VZ
1014#define WX_DECLARE_LIST(elementtype, listname) \
1015 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
f6bcfd97 1016 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
6de44038
VZ
1017#define WX_DECLARE_LIST_PTR(elementtype, listname) \
1018 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1019 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class)
f6bcfd97 1020
45c1de35 1021#define WX_DECLARE_LIST_WITH_DECL(elementtype, listname, decl) \
f6bcfd97 1022 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
45c1de35 1023 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, decl)
f644b28c 1024
45c1de35
VS
1025#define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
1026 WX_DECLARE_LIST_WITH_DECL(elementtype, listname, class WXDLLEXPORT)
1027
6de44038
VZ
1028#define WX_DECLARE_EXPORTED_LIST_PTR(elementtype, listname) \
1029 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1030 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
fd3f686c 1031
0b9ab0bd
RL
1032#define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
1033 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1034 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
6de44038
VZ
1035#define WX_DECLARE_USER_EXPORTED_LIST_PTR(elementtype, listname, usergoo) \
1036 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
1037 WX_DECLARE_LIST_PTR_2(elementtype, listname, wx##listname##Node, class usergoo)
0b9ab0bd 1038
fd3f686c
VZ
1039// this macro must be inserted in your program after
1040// #include <wx/listimpl.cpp>
1041#define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
1042
0b9ab0bd
RL
1043#define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1044#define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
1045
df5168c4 1046#endif // !wxUSE_STL
0b9ab0bd 1047
69b9f4cc 1048// ============================================================================
fd3f686c 1049// now we can define classes 100% compatible with the old ones
69b9f4cc 1050// ============================================================================
fd3f686c 1051
e146b8c8 1052// ----------------------------------------------------------------------------
f03fc89f 1053// commonly used list classes
e146b8c8
VZ
1054// ----------------------------------------------------------------------------
1055
69b9f4cc 1056#if defined(wxLIST_COMPATIBILITY)
fd3f686c 1057
137b7303
VZ
1058// inline compatibility functions
1059
69b9f4cc
MB
1060#if !wxUSE_STL
1061
1062// ----------------------------------------------------------------------------
137b7303 1063// wxNodeBase deprecated methods
69b9f4cc 1064// ----------------------------------------------------------------------------
137b7303
VZ
1065
1066inline wxNode *wxNodeBase::Next() const { return (wxNode *)GetNext(); }
1067inline wxNode *wxNodeBase::Previous() const { return (wxNode *)GetPrevious(); }
1068inline wxObject *wxNodeBase::Data() const { return (wxObject *)GetData(); }
1069
69b9f4cc 1070// ----------------------------------------------------------------------------
137b7303 1071// wxListBase deprecated methods
69b9f4cc 1072// ----------------------------------------------------------------------------
137b7303
VZ
1073
1074inline int wxListBase::Number() const { return (int)GetCount(); }
1075inline wxNode *wxListBase::First() const { return (wxNode *)GetFirst(); }
1076inline wxNode *wxListBase::Last() const { return (wxNode *)GetLast(); }
1077inline wxNode *wxListBase::Nth(size_t n) const { return (wxNode *)Item(n); }
1078inline wxListBase::operator wxList&() const { return *(wxList*)this; }
1079
69b9f4cc 1080#endif
137b7303 1081
b1d4dd7a
RL
1082// define this to make a lot of noise about use of the old wxList classes.
1083//#define wxWARN_COMPAT_LIST_USE
1084
69b9f4cc 1085// ----------------------------------------------------------------------------
fd3f686c 1086// wxList compatibility class: in fact, it's a list of wxObjects
69b9f4cc 1087// ----------------------------------------------------------------------------
6de44038
VZ
1088
1089WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode,
1090 class WXDLLIMPEXP_BASE);
fd3f686c 1091
bddd7a8d 1092class WXDLLIMPEXP_BASE wxList : public wxObjectList
c801d85f 1093{
fd3f686c 1094public:
df5168c4 1095#if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
728c62b6
MB
1096 wxList() { };
1097 wxDEPRECATED( wxList(int key_type) );
df5168c4 1098#elif !wxUSE_STL
b1d4dd7a
RL
1099 wxList(int key_type = wxKEY_NONE);
1100#endif
1101
799ea011 1102 // this destructor is required for Darwin
f11bdd03 1103 ~wxList() { }
fd3f686c 1104
df5168c4 1105#if !wxUSE_STL
f6bcfd97 1106 wxList& operator=(const wxList& list)
f2af4afb 1107 { (void) wxListBase::operator=(list); return *this; }
f6bcfd97 1108
fd3f686c 1109 // compatibility methods
3bef6c4c 1110 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
df5168c4 1111#endif
3bef6c4c 1112
df5168c4
MB
1113#if wxUSE_STL
1114#else
fd3f686c 1115 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
df5168c4 1116#endif
f98bd52a
VZ
1117
1118private:
df5168c4 1119#if !wxUSE_STL
f98bd52a 1120 DECLARE_DYNAMIC_CLASS(wxList)
df5168c4 1121#endif
c801d85f
KB
1122};
1123
df5168c4
MB
1124#if !wxUSE_STL
1125
fd3f686c
VZ
1126// -----------------------------------------------------------------------------
1127// wxStringList class for compatibility with the old code
1128// -----------------------------------------------------------------------------
bddd7a8d 1129WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
fd3f686c 1130
bddd7a8d 1131class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
c801d85f 1132{
fd3f686c
VZ
1133public:
1134 // ctors and such
1135 // default
b1d4dd7a 1136#ifdef wxWARN_COMPAT_LIST_USE
728c62b6 1137 wxStringList();
b1d4dd7a
RL
1138 wxDEPRECATED( wxStringList(const wxChar *first ...) );
1139#else
1140 wxStringList();
9d2f3c71 1141 wxStringList(const wxChar *first ...);
b1d4dd7a 1142#endif
fd3f686c 1143
db9504c5
VZ
1144 // copying the string list: the strings are copied, too (extremely
1145 // inefficient!)
f644b28c 1146 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(true); DoCopy(other); }
db9504c5
VZ
1147 wxStringList& operator=(const wxStringList& other)
1148 { Clear(); DoCopy(other); return *this; }
1149
fd3f686c
VZ
1150 // operations
1151 // makes a copy of the string
f526f752 1152 wxNode *Add(const wxChar *s);
f644b28c 1153
890f8a7c 1154 // Append to beginning of list
f526f752 1155 wxNode *Prepend(const wxChar *s);
fd3f686c 1156
9d2f3c71 1157 bool Delete(const wxChar *s);
fd3f686c 1158
f644b28c 1159 wxChar **ListToArray(bool new_copies = false) const;
9d2f3c71 1160 bool Member(const wxChar *s) const;
fd3f686c
VZ
1161
1162 // alphabetic sort
1163 void Sort();
1164
db9504c5
VZ
1165private:
1166 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
f98bd52a
VZ
1167
1168 DECLARE_DYNAMIC_CLASS(wxStringList)
c801d85f
KB
1169};
1170
df5168c4
MB
1171#else // if wxUSE_STL
1172
f455ffb2 1173WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLIMPEXP_BASE);
df5168c4 1174
f455ffb2 1175class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
df5168c4
MB
1176{
1177public:
fd82f4e6
MB
1178 compatibility_iterator Append(wxChar* s)
1179 { wxString tmp = s; delete[] s; return wxStringListBase::Append(tmp); }
1180 compatibility_iterator Insert(wxChar* s)
1181 { wxString tmp = s; delete[] s; return wxStringListBase::Insert(tmp); }
1182 compatibility_iterator Insert(size_t pos, wxChar* s)
1183 {
1184 wxString tmp = s;
1185 delete[] s;
1186 return wxStringListBase::Insert(pos, tmp);
1187 }
1188 compatibility_iterator Add(const wxChar* s)
1189 { push_back(s); return GetLast(); }
1190 compatibility_iterator Prepend(const wxChar* s)
1191 { push_front(s); return GetFirst(); }
df5168c4
MB
1192};
1193
1194#endif // wxUSE_STL
1195
fd3f686c
VZ
1196#endif // wxLIST_COMPATIBILITY
1197
df5168c4
MB
1198// delete all list elements
1199//
1200// NB: the class declaration of the list elements must be visible from the
1201// place where you use this macro, otherwise the proper destructor may not
1202// be called (a decent compiler should give a warning about it, but don't
1203// count on it)!
1204#define WX_CLEAR_LIST(type, list) \
1205 { \
1206 type::iterator it, en; \
1207 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1208 delete *it; \
1209 (list).clear(); \
1210 }
1211
c801d85f 1212#endif
34138703 1213 // _WX_LISTH__