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