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