X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d294c9db889143938d8164df03fef56bdc1ab45e..a2c5db764c8450dda6e87fe58917b0a00ec2c74f:/include/wx/list.h diff --git a/include/wx/list.h b/include/wx/list.h index 5714dcd455..0694f7efeb 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -54,28 +54,12 @@ extern "C" typedef int (* LINKAGEMODE wxSortCompareFunction)(const void *elem1, const void *elem2); } -class WXDLLIMPEXP_BASE wxObjectListNode; +class WXDLLIMPEXP_FWD_BASE wxObjectListNode; typedef wxObjectListNode wxNode; // typedef int (* LINKAGEMODE wxListIterateFunction)(void *current); -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - -#if !defined(wxENUM_KEY_TYPE_DEFINED) -#define wxENUM_KEY_TYPE_DEFINED - -enum wxKeyType -{ - wxKEY_NONE, - wxKEY_INTEGER, - wxKEY_STRING -}; - -#endif - #if wxUSE_STL #define wxLIST_COMPATIBILITY @@ -93,7 +77,7 @@ enum wxKeyType #define WX_DECLARE_LIST_WITH_DECL(elT, liT, decl) \ WX_DECLARE_LIST_XO(elT*, liT, decl) -#if !defined( __VISUALC__ ) +#if !defined(__VISUALC__) || __VISUALC__ >= 1300 // == !VC6 template class WXDLLIMPEXP_BASE wxList_SortFunction @@ -109,7 +93,7 @@ private: #define WX_LIST_SORTFUNCTION( elT, f ) wxList_SortFunction(f) #define VC6_WORKAROUND(elT, liT, decl) -#else // if defined( __VISUALC__ ) +#else // if defined( __VISUALC__ ) && __VISUALC__ < 1300 // == VC6 #define WX_LIST_SORTFUNCTION( elT, f ) std::greater( f ) #define VC6_WORKAROUND(elT, liT, decl) \ @@ -128,35 +112,81 @@ private: bool operator()(const elT X, const elT Y) const \ { \ return m_CompFunc ? \ - ( m_CompFunc( X, Y ) < 0 ) : \ + ( m_CompFunc( wxListCastElementToVoidPtr(X), \ + wxListCastElementToVoidPtr(Y) ) < 0 ) : \ ( X > Y ); \ } \ }; -#endif // defined( __VISUALC__ ) +// helper for std::greater above: +template +inline const void *wxListCastElementToVoidPtr(const T* ptr) { return ptr; } +inline const void *wxListCastElementToVoidPtr(const wxString& str) + { return (const char*)str; } + +#endif // VC6/!VC6 +/* + Note 1: the outer helper class _WX_LIST_HELPER_##liT below is a workaround + for mingw 3.2.3 compiler bug that prevents a static function of liT class + from being exported into dll. A minimal code snippet reproducing the bug: + + struct WXDLLEXPORT Foo + { + static void Bar(); + struct SomeInnerClass + { + friend class Foo; // comment this out to make it link + }; + ~Foo() + { + Bar(); + } + }; + + The program does not link under mingw_gcc 3.2.3 producing undefined + reference to Foo::Bar() function + + + Note 2: the EmptyList is needed to allow having a NULL pointer-like + invalid iterator. We used to use just an uninitialized iterator object + instead but this fails with some debug/checked versions of STL, notably the + glibc version activated with _GLIBCXX_DEBUG, so we need to have a separate + invalid iterator. + */ + +// the real wxList-class declaration #define WX_DECLARE_LIST_XO(elT, liT, decl) \ + decl _WX_LIST_HELPER_##liT \ + { \ + typedef elT _WX_LIST_ITEM_TYPE_##liT; \ + public: \ + static void DeleteFunction( _WX_LIST_ITEM_TYPE_##liT X ); \ + }; \ + \ VC6_WORKAROUND(elT, liT, decl) \ decl liT : public std::list \ { \ private: \ + typedef std::list BaseListType; \ + static BaseListType EmptyList; \ + \ bool m_destroy; \ - private: \ - typedef elT _WX_LIST_ITEM_TYPE_##liT; \ - static void DeleteFunction( _WX_LIST_ITEM_TYPE_##liT X ); \ + \ public: \ decl compatibility_iterator \ { \ private: \ - /* Workaround for broken VC6 nested class name resolution */ \ - typedef std::list::iterator iterator; \ - friend class liT; \ - private: \ + /* Workaround for broken VC6 nested class name resolution */ \ + typedef std::list::iterator iterator; \ + friend class liT; \ + \ iterator m_iter; \ liT * m_list; \ + \ public: \ compatibility_iterator() \ - : m_iter(), m_list( NULL ) {} \ + : m_iter(EmptyList.end()), m_list( NULL ) {} \ compatibility_iterator( liT* li, iterator i ) \ : m_iter( i ), m_list( li ) {} \ compatibility_iterator( const liT* li, iterator i ) \ @@ -225,6 +255,11 @@ private: std::advance( i, idx ); \ return compatibility_iterator( this, i ); \ } \ + elT operator[](size_t idx) const \ + { \ + return Item(idx).GetData(); \ + } \ + \ compatibility_iterator GetFirst() const \ { \ return compatibility_iterator( this, \ @@ -269,7 +304,7 @@ private: void Erase( const compatibility_iterator& i ) \ { \ if ( m_destroy ) \ - DeleteFunction( i->GetData() ); \ + _WX_LIST_HELPER_##liT::DeleteFunction( i->GetData() ); \ erase( i.m_iter ); \ } \ bool DeleteNode( const compatibility_iterator& i ) \ @@ -288,13 +323,17 @@ private: void Clear() \ { \ if ( m_destroy ) \ - std::for_each( begin(), end(), DeleteFunction ); \ + std::for_each( begin(), end(), \ + _WX_LIST_HELPER_##liT::DeleteFunction ); \ clear(); \ } \ /* Workaround for broken VC6 std::list::sort() see above */ \ void Sort( wxSortCompareFunction compfunc ) \ { sort( WX_LIST_SORTFUNCTION( elT, compfunc ) ); } \ ~liT() { Clear(); } \ + \ + /* It needs access to our EmptyList */ \ + friend decl compatibility_iterator; \ } #define WX_DECLARE_LIST(elementtype, listname) \ @@ -321,11 +360,6 @@ private: #else // if !wxUSE_STL -// due to circular header dependencies this function has to be declared here -// (normally it's found in utils.h which includes itself list.h...) -#if WXWIN_COMPATIBILITY_2_4 -extern WXDLLIMPEXP_BASE wxChar* copystring(const wxChar *s); -#endif // undef it to get rid of old, deprecated functions #define wxLIST_COMPATIBILITY @@ -337,7 +371,7 @@ extern WXDLLIMPEXP_BASE wxChar* copystring(const wxChar *s); union wxListKeyValue { long integer; - wxChar *string; + wxString *string; }; // a struct which may contain both types of keys @@ -354,15 +388,17 @@ public: { } wxListKey(long i) : m_keyType(wxKEY_INTEGER) { m_key.integer = i; } - wxListKey(const wxChar *s) : m_keyType(wxKEY_STRING) - { m_key.string = wxStrdup(s); } wxListKey(const wxString& s) : m_keyType(wxKEY_STRING) - { m_key.string = wxStrdup(s.c_str()); } + { m_key.string = new wxString(s); } + wxListKey(const char *s) : m_keyType(wxKEY_STRING) + { m_key.string = new wxString(s); } + wxListKey(const wchar_t *s) : m_keyType(wxKEY_STRING) + { m_key.string = new wxString(s); } // accessors wxKeyType GetKeyType() const { return m_keyType; } - const wxChar *GetString() const - { wxASSERT( m_keyType == wxKEY_STRING ); return m_key.string; } + const wxString GetString() const + { wxASSERT( m_keyType == wxKEY_STRING ); return *m_key.string; } long GetNumber() const { wxASSERT( m_keyType == wxKEY_INTEGER ); return m_key.integer; } @@ -375,7 +411,7 @@ public: ~wxListKey() { if ( m_keyType == wxKEY_STRING ) - free(m_key.string); + delete m_key.string; } private: @@ -389,7 +425,7 @@ private: extern WXDLLIMPEXP_DATA_BASE(wxListKey) wxDefaultListKey; -class WXDLLIMPEXP_BASE wxListBase; +class WXDLLIMPEXP_FWD_BASE wxListBase; class WXDLLIMPEXP_BASE wxNodeBase { @@ -405,11 +441,11 @@ public: virtual ~wxNodeBase(); // FIXME no check is done that the list is really keyed on strings - const wxChar *GetKeyString() const { return m_key.string; } + wxString GetKeyString() const { return *m_key.string; } long GetKeyInteger() const { return m_key.integer; } // Necessary for some existing code - void SetKeyString(wxChar* s) { m_key.string = s; } + void SetKeyString(const wxString& s) { m_key.string = new wxString(s); } void SetKeyInteger(long i) { m_key.integer = i; } #ifdef wxLIST_COMPATIBILITY @@ -451,11 +487,11 @@ private: // a double-linked list class // ----------------------------------------------------------------------------- -class WXDLLIMPEXP_BASE wxList; +class WXDLLIMPEXP_FWD_BASE wxList; class WXDLLIMPEXP_BASE wxListBase : public wxObject { -friend class WXDLLIMPEXP_BASE wxNodeBase; // should be able to call DetachNode() +friend class WXDLLIMPEXP_FWD_BASE wxNodeBase; // should be able to call DetachNode() friend class wxHashTableBase; // should be able to call untyped Find() public: @@ -559,7 +595,7 @@ protected: // keyed append wxNodeBase *Append(long key, void *object); - wxNodeBase *Append(const wxChar *key, void *object); + wxNodeBase *Append(const wxString& key, void *object); // removes node from the list but doesn't delete it (returns pointer // to the node or NULL if it wasn't found in the list) @@ -702,12 +738,12 @@ private: name& operator=(const name& list) \ { Assign(list); return *this; } \ \ - compatibility_iterator GetFirst() const \ + nodetype *GetFirst() const \ { return (nodetype *)wxListBase::GetFirst(); } \ - compatibility_iterator GetLast() const \ + nodetype *GetLast() const \ { return (nodetype *)wxListBase::GetLast(); } \ \ - compatibility_iterator Item(size_t index) const \ + nodetype *Item(size_t index) const \ { return (nodetype *)wxListBase::Item(index); } \ \ T *operator[](size_t index) const \ @@ -716,18 +752,18 @@ private: return node ? (T*)(node->GetData()) : (T*)NULL; \ } \ \ - compatibility_iterator Append(Tbase *object) \ + nodetype *Append(Tbase *object) \ { return (nodetype *)wxListBase::Append(object); } \ - compatibility_iterator Insert(Tbase *object) \ + nodetype *Insert(Tbase *object) \ { return (nodetype *)Insert((nodetype*)NULL, object); } \ - compatibility_iterator Insert(size_t pos, Tbase *object) \ + nodetype *Insert(size_t pos, Tbase *object) \ { return (nodetype *)wxListBase::Insert(pos, object); } \ - compatibility_iterator Insert(nodetype *prev, Tbase *object) \ + nodetype *Insert(nodetype *prev, Tbase *object) \ { return (nodetype *)wxListBase::Insert(prev, object); } \ \ - compatibility_iterator Append(long key, void *object) \ + nodetype *Append(long key, void *object) \ { return (nodetype *)wxListBase::Append(key, object); } \ - compatibility_iterator Append(const wxChar *key, void *object) \ + nodetype *Append(const wxChar *key, void *object) \ { return (nodetype *)wxListBase::Append(key, object); } \ \ nodetype *DetachNode(nodetype *node) \ @@ -736,10 +772,10 @@ private: { return wxListBase::DeleteNode(node); } \ bool DeleteObject(Tbase *object) \ { return wxListBase::DeleteObject(object); } \ - void Erase(compatibility_iterator it) \ + void Erase(nodetype *it) \ { DeleteNode(it); } \ \ - compatibility_iterator Find(const Tbase *object) const \ + nodetype *Find(const Tbase *object) const \ { return (nodetype *)wxListBase::Find(object); } \ \ virtual nodetype *Find(const wxListKey& key) const \ @@ -988,7 +1024,8 @@ private: iterator insert(const iterator& it, const_reference v = value_type())\ { \ Insert(it.m_node, (const_base_reference)v); \ - return iterator(it.m_node->GetPrevious(), GetLast()); \ + iterator itprev(it); \ + return itprev--; \ } \ void insert(const iterator& it, size_type n, const_reference v = value_type())\ { \ @@ -1176,10 +1213,10 @@ public: // default #ifdef wxWARN_COMPAT_LIST_USE wxStringList(); - wxDEPRECATED( wxStringList(const wxChar *first ...) ); + wxDEPRECATED( wxStringList(const wxChar *first ...) ); // FIXME-UTF8 #else wxStringList(); - wxStringList(const wxChar *first ...); + wxStringList(const wxChar *first ...); // FIXME-UTF8 #endif // copying the string list: the strings are copied, too (extremely