X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d4d8988c72e26ea5ef68b87a53691da7c3751a95..7e2baeb41321aedca928608f816f03c13afdeff9:/include/wx/list.h diff --git a/include/wx/list.h b/include/wx/list.h index 5f0790af7b..8c19a070ec 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -135,17 +135,54 @@ private: #endif // defined( __VISUALC__ ) +/* + 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: \ - class compatibility_iterator \ + decl compatibility_iterator \ { \ private: \ /* Workaround for broken VC6 nested class name resolution */ \ @@ -156,7 +193,7 @@ private: 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 +262,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 +311,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,7 +330,8 @@ 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 */ \ @@ -680,7 +723,7 @@ private: { \ public: \ typedef nodetype Node; \ - class compatibility_iterator \ + classexp compatibility_iterator \ { \ public: \ compatibility_iterator(Node *ptr = NULL) : m_ptr(ptr) { } \ @@ -702,12 +745,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 +759,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 +779,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 \ @@ -773,7 +816,7 @@ private: typedef base_value_type& base_reference; \ typedef const base_value_type& const_base_reference; \ \ - class iterator \ + classexp iterator \ { \ typedef name list; \ public: \ @@ -813,7 +856,7 @@ private: bool operator==(const itor& it) const \ { return it.m_node == m_node; } \ }; \ - class const_iterator \ + classexp const_iterator \ { \ typedef name list; \ public: \ @@ -856,7 +899,7 @@ private: bool operator==(const itor& it) const \ { return it.m_node == m_node; } \ }; \ - class reverse_iterator \ + classexp reverse_iterator \ { \ typedef name list; \ public: \ @@ -895,7 +938,7 @@ private: bool operator==(const itor& it) const \ { return it.m_node == m_node; } \ }; \ - class const_reverse_iterator \ + classexp const_reverse_iterator \ { \ typedef name list; \ public: \