list.h 74 KB

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