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