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