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