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