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