]> git.saurik.com Git - wxWidgets.git/blob - include/wx/list.h
compilation fix
[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 list::Node Node; \
665 typedef iterator itor; \
666 typedef list::value_type* ptr_type; \
667 \
668 Node* m_node; \
669 Node* m_init; \
670 public: \
671 typedef list::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 list::Node Node; \
704 typedef const_iterator itor; \
705 typedef list::value_type* ptr_type; \
706 \
707 Node* m_node; \
708 Node* m_init; \
709 public: \
710 typedef list::const_reference reference_type; \
711 typedef const ptr_type pointer_type; \
712 \
713 const_iterator(Node* node, Node* init) \
714 : m_node(node), m_init(init) { } \
715 const_iterator() : m_node(NULL), m_init(NULL) { } \
716 const_iterator(const iterator& it) \
717 : m_node(it.m_node), m_init(it.m_init) { } \
718 reference_type operator*() const \
719 { return *(pointer_type)m_node->GetDataPtr(); } \
720 pointer_type operator->() const \
721 { return (pointer_type)m_node->GetDataPtr(); } \
722 itor& operator++() { m_node = m_node->GetNext(); return *this; }\
723 itor operator++(int) \
724 { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }\
725 itor& operator--() \
726 { \
727 m_node = m_node ? m_node->GetPrevious() : m_init; \
728 return *this; \
729 } \
730 itor operator--(int) \
731 { \
732 itor tmp = *this; \
733 m_node = m_node ? m_node->GetPrevious() : m_init; \
734 return tmp; \
735 } \
736 bool operator!=(const itor& it) const \
737 { return it.m_node != m_node; } \
738 bool operator==(const itor& it) const \
739 { return it.m_node == m_node; } \
740 }; \
741 class reverse_iterator \
742 { \
743 typedef name list; \
744 public: \
745 typedef list::Node Node; \
746 typedef reverse_iterator itor; \
747 typedef list::value_type* ptr_type; \
748 \
749 Node* m_node; \
750 Node* m_init; \
751 public: \
752 typedef list::reference reference_type; \
753 typedef ptr_type pointer_type; \
754 \
755 reverse_iterator(Node* node, Node* init) \
756 : m_node(node), m_init(init) { } \
757 reverse_iterator() : m_node(NULL), m_init(NULL) { } \
758 reference_type operator*() const \
759 { return *(pointer_type)m_node->GetDataPtr(); } \
760 pointer_type operator->() const \
761 { return (pointer_type)m_node->GetDataPtr(); } \
762 itor& operator++() \
763 { m_node = m_node->GetPrevious(); return *this; } \
764 itor operator++(int) \
765 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
766 itor& operator--() \
767 { m_node = m_node ? m_node->GetNext() : m_init; return *this; } \
768 itor operator--(int) \
769 { \
770 itor tmp = *this; \
771 m_node = m_node ? m_node->GetNext() : m_init; \
772 return tmp; \
773 } \
774 bool operator!=(const itor& it) const \
775 { return it.m_node != m_node; } \
776 bool operator==(const itor& it) const \
777 { return it.m_node == m_node; } \
778 }; \
779 class const_reverse_iterator \
780 { \
781 typedef name list; \
782 public: \
783 typedef list::Node Node; \
784 typedef const_reverse_iterator itor; \
785 typedef list::value_type* ptr_type; \
786 \
787 Node* m_node; \
788 Node* m_init; \
789 public: \
790 typedef list::const_reference reference_type; \
791 typedef const ptr_type pointer_type; \
792 \
793 const_reverse_iterator(Node* node, Node* init) \
794 : m_node(node), m_init(init) { } \
795 const_reverse_iterator() : m_node(NULL), m_init(NULL) { } \
796 const_reverse_iterator(const reverse_iterator& it) \
797 : m_node(it.m_node), m_init(it.m_init) { } \
798 reference_type operator*() const \
799 { return *(pointer_type)m_node->GetDataPtr(); } \
800 pointer_type operator->() const \
801 { return (pointer_type)m_node->GetDataPtr(); } \
802 itor& operator++() \
803 { m_node = m_node->GetPrevious(); return *this; } \
804 itor operator++(int) \
805 { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }\
806 itor& operator--() \
807 { m_node = m_node ? m_node->GetNext() : m_init; return *this;}\
808 itor operator--(int) \
809 { \
810 itor tmp = *this; \
811 m_node = m_node ? m_node->GetNext() : m_init; \
812 return tmp; \
813 } \
814 bool operator!=(const itor& it) const \
815 { return it.m_node != m_node; } \
816 bool operator==(const itor& it) const \
817 { return it.m_node == m_node; } \
818 }; \
819 \
820 wxEXPLICIT name(size_type n, const_reference v = value_type()) \
821 { assign(n, v); } \
822 name(const_iterator first, const_iterator last) \
823 { assign(first, last); } \
824 iterator begin() { return iterator(GetFirst(), GetLast()); } \
825 const_iterator begin() const \
826 { return const_iterator(GetFirst(), GetLast()); } \
827 iterator end() { return iterator(NULL, GetLast()); } \
828 const_iterator end() const { return const_iterator(NULL, GetLast()); }\
829 reverse_iterator rbegin() \
830 { return reverse_iterator(GetLast(), GetFirst()); } \
831 const_reverse_iterator rbegin() const \
832 { return const_reverse_iterator(GetLast(), GetFirst()); } \
833 reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }\
834 const_reverse_iterator rend() const \
835 { return const_reverse_iterator(NULL, GetFirst()); } \
836 void resize(size_type n, value_type v = value_type()) \
837 { \
838 if(n < size()) \
839 for(; n < size(); pop_back()); \
840 else if(n > size()) \
841 for(; n > size(); push_back(v)); \
842 } \
843 size_type size() const { return GetCount(); } \
844 size_type max_size() const { return INT_MAX; } \
845 bool empty() const { return IsEmpty(); } \
846 reference front() { return *begin(); } \
847 const_reference front() const { return *begin(); } \
848 reference back() { return *--end(); } \
849 const_reference back() const { return *--end(); } \
850 void push_front(const_reference v = value_type()) \
851 { Insert(GetFirst(), (const_base_reference)v); } \
852 void pop_front() { DeleteNode(GetFirst()); } \
853 void push_back(const_reference v = value_type()) \
854 { Append((const_base_reference)v); } \
855 void pop_back() { DeleteNode(GetLast()); } \
856 void assign(const_iterator first, const_iterator last) \
857 { \
858 clear(); \
859 for(; first != last; ++first) \
860 Append((const_base_reference)*first); \
861 } \
862 void assign(size_type n, const_reference v = value_type()) \
863 { \
864 clear(); \
865 for(size_type i = 0; i < n; ++i) \
866 Append((const_base_reference)v); \
867 } \
868 iterator insert(iterator it, const_reference v = value_type()) \
869 { \
870 Insert(it.m_node, (const_base_reference)v); \
871 return iterator(it.m_node->GetPrevious(), GetLast()); \
872 } \
873 void insert(iterator it, size_type n, const_reference v = value_type())\
874 { \
875 for(size_type i = 0; i < n; ++i) \
876 Insert(it.m_node, (const_base_reference)v); \
877 } \
878 void insert(iterator it, const_iterator first, const_iterator last) \
879 { \
880 for(; first != last; ++first) \
881 Insert(it.m_node, (const_base_reference)*first); \
882 } \
883 iterator erase(iterator it) \
884 { \
885 iterator next = iterator(it.m_node->GetNext(), GetLast()); \
886 DeleteNode(it.m_node); return next; \
887 } \
888 iterator erase(iterator first, iterator last) \
889 { \
890 iterator next = last; ++next; \
891 DeleteNodes(first.m_node, last.m_node); \
892 return next; \
893 } \
894 void clear() { Clear(); } \
895 void splice(iterator it, name& l, iterator first, iterator last) \
896 { insert(it, first, last); l.erase(first, last); } \
897 void splice(iterator it, name& l) \
898 { splice(it, l, l.begin(), l.end() ); } \
899 void splice(iterator it, name& l, iterator first) \
900 { \
901 iterator tmp = first; ++tmp; \
902 if(it == first || it == tmp) return; \
903 insert(it, *first); \
904 l.erase(first); \
905 } \
906 void remove(const_reference v) \
907 { DeleteObject((const_base_reference)v); } \
908 void reverse() \
909 { Reverse(); } \
910 /* void swap(name& l) \
911 { \
912 { size_t t = m_count; m_count = l.m_count; l.m_count = t; } \
913 { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }\
914 { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }\
915 { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }\
916 { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }\
917 } */ \
918 }
919
920 #define WX_DECLARE_LIST_2(elementtype, listname, nodename, classexp) \
921 WX_DECLARE_LIST_3(elementtype, elementtype, listname, nodename, classexp)
922
923 #define WX_DECLARE_LIST(elementtype, listname) \
924 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
925 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class)
926
927 #define WX_DECLARE_EXPORTED_LIST(elementtype, listname) \
928 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
929 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class WXDLLEXPORT)
930
931 #define WX_DECLARE_USER_EXPORTED_LIST(elementtype, listname, usergoo) \
932 typedef elementtype _WX_LIST_ITEM_TYPE_##listname; \
933 WX_DECLARE_LIST_2(elementtype, listname, wx##listname##Node, class usergoo)
934
935 // this macro must be inserted in your program after
936 // #include <wx/listimpl.cpp>
937 #define WX_DEFINE_LIST(name) "don't forget to include listimpl.cpp!"
938
939 #define WX_DEFINE_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
940 #define WX_DEFINE_USER_EXPORTED_LIST(name) WX_DEFINE_LIST(name)
941
942 #endif // !wxUSE_STL
943
944 // =============================================================================
945 // now we can define classes 100% compatible with the old ones
946 // =============================================================================
947
948 // ----------------------------------------------------------------------------
949 // commonly used list classes
950 // ----------------------------------------------------------------------------
951
952 #ifdef wxLIST_COMPATIBILITY
953
954 // define this to make a lot of noise about use of the old wxList classes.
955 //#define wxWARN_COMPAT_LIST_USE
956
957 // -----------------------------------------------------------------------------
958 // wxList compatibility class: in fact, it's a list of wxObjects
959 // -----------------------------------------------------------------------------
960 WX_DECLARE_LIST_2(wxObject, wxObjectList, wxObjectListNode, class WXDLLIMPEXP_BASE);
961
962 class WXDLLIMPEXP_BASE wxList : public wxObjectList
963 {
964 public:
965 #if defined(wxWARN_COMPAT_LIST_USE) && !wxUSE_STL
966 wxDEPRECATED( wxList(int key_type = wxKEY_NONE) );
967 #elif !wxUSE_STL
968 wxList(int key_type = wxKEY_NONE);
969 #endif
970
971 // this destructor is required for Darwin
972 ~wxList() { }
973
974 #if !wxUSE_STL
975 wxList& operator=(const wxList& list)
976 { (void) wxListBase::operator=(list); return *this; }
977
978 // compatibility methods
979 void Sort(wxSortCompareFunction compfunc) { wxListBase::Sort(compfunc); }
980 #endif
981
982 #if wxUSE_STL
983 #else
984 wxNode *Member(wxObject *object) const { return (wxNode *)Find(object); }
985 #endif
986
987 private:
988 #if !wxUSE_STL
989 DECLARE_DYNAMIC_CLASS(wxList)
990 #endif
991 };
992
993 #if !wxUSE_STL
994
995 // -----------------------------------------------------------------------------
996 // wxStringList class for compatibility with the old code
997 // -----------------------------------------------------------------------------
998 WX_DECLARE_LIST_2(wxChar, wxStringListBase, wxStringListNode, class WXDLLIMPEXP_BASE);
999
1000 class WXDLLIMPEXP_BASE wxStringList : public wxStringListBase
1001 {
1002 public:
1003 // ctors and such
1004 // default
1005 #ifdef wxWARN_COMPAT_LIST_USE
1006 wxDEPRECATED( wxStringList() );
1007 wxDEPRECATED( wxStringList(const wxChar *first ...) );
1008 #else
1009 wxStringList();
1010 wxStringList(const wxChar *first ...);
1011 #endif
1012
1013 // copying the string list: the strings are copied, too (extremely
1014 // inefficient!)
1015 wxStringList(const wxStringList& other) : wxStringListBase() { DeleteContents(TRUE); DoCopy(other); }
1016 wxStringList& operator=(const wxStringList& other)
1017 { Clear(); DoCopy(other); return *this; }
1018
1019 // operations
1020 // makes a copy of the string
1021 wxNode *Add(const wxChar *s);
1022
1023 // Append to beginning of list
1024 wxNode *Prepend(const wxChar *s);
1025
1026 bool Delete(const wxChar *s);
1027
1028 wxChar **ListToArray(bool new_copies = FALSE) const;
1029 bool Member(const wxChar *s) const;
1030
1031 // alphabetic sort
1032 void Sort();
1033
1034 private:
1035 void DoCopy(const wxStringList&); // common part of copy ctor and operator=
1036
1037 DECLARE_DYNAMIC_CLASS(wxStringList)
1038 };
1039
1040 #else // if wxUSE_STL
1041
1042 WX_DECLARE_LIST_XO(wxString, wxStringListBase, class WXDLLEXPORT);
1043
1044 class WXDLLEXPORT wxStringList : public wxStringListBase
1045 {
1046 public:
1047 };
1048
1049 #endif // wxUSE_STL
1050
1051 #endif // wxLIST_COMPATIBILITY
1052
1053 // delete all list elements
1054 //
1055 // NB: the class declaration of the list elements must be visible from the
1056 // place where you use this macro, otherwise the proper destructor may not
1057 // be called (a decent compiler should give a warning about it, but don't
1058 // count on it)!
1059 #define WX_CLEAR_LIST(type, list) \
1060 { \
1061 type::iterator it, en; \
1062 for( it = (list).begin(), en = (list).end(); it != en; ++it ) \
1063 delete *it; \
1064 (list).clear(); \
1065 }
1066
1067 #endif
1068 // _WX_LISTH__