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