From: Vadim Zeitlin Date: Mon, 6 Aug 2012 11:06:45 +0000 (+0000) Subject: A better fix for wxHash{Map,Set} with g++ 4.7. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/7a7fa93b0dd56b06325740cebc91f1156c18e30c A better fix for wxHash{Map,Set} with g++ 4.7. This reverts r70556, i.e. removes the scope operators added by it to all WX_DECLARE_HASH_{MAP,SET} macros, and implements a workaround for the problem due to the use of empty base class optimization in g++ 4.7 standard library implementations inside the macros themselves by prepending the hasher and comparator classes with explicit "struct". git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72297 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 2c53338ad0..c653e9444c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -530,6 +530,7 @@ Major new features in this release All: - Add wxDir::Close() method (Silverstorm82). +- Fix compilation of wxHash{Map,Set} with g++ 4.7 (Nathan Ridge). All (GUI): diff --git a/include/wx/hashset.h b/include/wx/hashset.h index 1f3368c5bf..ae133d0618 100644 --- a/include/wx/hashset.h +++ b/include/wx/hashset.h @@ -46,7 +46,7 @@ // we need to define the class declared by _WX_DECLARE_HASH_SET as a class and // not a typedef to allow forward declaring it -#define _WX_DECLARE_HASH_SET( KEY_T, HASH_T, KEY_EQ_T, PTROP, CLASSNAME, CLASSEXP ) \ +#define _WX_DECLARE_HASH_SET_IMPL( KEY_T, HASH_T, KEY_EQ_T, PTROP, CLASSNAME, CLASSEXP ) \ CLASSEXP CLASSNAME \ : public WX_HASH_SET_BASE_TEMPLATE< KEY_T, HASH_T, KEY_EQ_T > \ { \ @@ -69,6 +69,31 @@ public: \ {} \ } +// In some standard library implementations (in particular, the libstdc++ that +// ships with g++ 4.7), std::unordered_set inherits privately from its hasher +// and comparator template arguments for purposes of empty base optimization. +// As a result, in the declaration of a class deriving from std::unordered_set +// the names of the hasher and comparator classes are interpreted as naming +// the base class which is inaccessible. +// The workaround is to prefix the class names with 'struct'; however, don't +// do this on MSVC because it causes a warning there if the class was +// declared as a 'class' rather than a 'struct' (and MSVC's std::unordered_set +// implementation does not suffer from the access problem). +#ifdef _MSC_VER +#define WX_MAYBE_PREFIX_WITH_STRUCT(STRUCTNAME) STRUCTNAME +#else +#define WX_MAYBE_PREFIX_WITH_STRUCT(STRUCTNAME) struct STRUCTNAME +#endif + +#define _WX_DECLARE_HASH_SET( KEY_T, HASH_T, KEY_EQ_T, PTROP, CLASSNAME, CLASSEXP ) \ + _WX_DECLARE_HASH_SET_IMPL( \ + KEY_T, \ + WX_MAYBE_PREFIX_WITH_STRUCT(HASH_T), \ + WX_MAYBE_PREFIX_WITH_STRUCT(KEY_EQ_T), \ + PTROP, \ + CLASSNAME, \ + CLASSEXP) + #else // no appropriate STL class, use our own implementation // this is a complex way of defining an easily inlineable identity function... diff --git a/include/wx/html/htmlpars.h b/include/wx/html/htmlpars.h index cecb016c3f..045060a4ea 100644 --- a/include/wx/html/htmlpars.h +++ b/include/wx/html/htmlpars.h @@ -29,7 +29,7 @@ class wxHtmlTextPieces; class wxHtmlParserState; WX_DECLARE_HASH_SET_WITH_DECL_PTR(wxHtmlTagHandler*, - ::wxPointerHash, ::wxPointerEqual, + wxPointerHash, wxPointerEqual, wxHtmlTagHandlersSet, class WXDLLIMPEXP_HTML); WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxHtmlTagHandler*, diff --git a/interface/wx/hashmap.h b/interface/wx/hashmap.h index b7554e815b..b816f836fc 100644 --- a/interface/wx/hashmap.h +++ b/interface/wx/hashmap.h @@ -83,8 +83,8 @@ @code WX_DECLARE_HASH_MAP( int, wxString, - ::wxIntegerHash, - ::wxIntegerEqual, + wxIntegerHash, + wxIntegerEqual, MyHash ); // using an user-defined class for keys @@ -119,8 +119,8 @@ WX_DECLARE_HASH_MAP( MyKey, // type of the keys SOME_TYPE, // any type you like - ::MyKeyHash, // hasher - ::MyKeyEqual, // key equality predicate + MyKeyHash, // hasher + MyKeyEqual, // key equality predicate CLASSNAME); // name of the class @endcode diff --git a/interface/wx/hashset.h b/interface/wx/hashset.h index a3406431c7..36469e47e5 100644 --- a/interface/wx/hashset.h +++ b/interface/wx/hashset.h @@ -20,11 +20,11 @@ class MyClass { ... }; // same, with MyClass* keys (only uses pointer equality!) - WX_DECLARE_HASH_SET( MyClass*, ::wxPointerHash, ::wxPointerEqual, MySet1 ); + WX_DECLARE_HASH_SET( MyClass*, wxPointerHash, wxPointerEqual, MySet1 ); // same, with int keys - WX_DECLARE_HASH_SET( int, ::wxIntegerHash, ::wxIntegerEqual, MySet2 ); + WX_DECLARE_HASH_SET( int, wxIntegerHash, wxIntegerEqual, MySet2 ); // declare a hash set with string keys - WX_DECLARE_HASH_SET( wxString, ::wxStringHash, ::wxStringEqual, MySet3 ); + WX_DECLARE_HASH_SET( wxString, wxStringHash, wxStringEqual, MySet3 ); MySet1 h1; MySet2 h1; @@ -70,8 +70,8 @@ @code WX_DECLARE_HASH_SET( int, - ::wxIntegerHash, - ::wxIntegerEqual, + wxIntegerHash, + wxIntegerEqual, MySet ); // using an user-defined class for keys @@ -105,8 +105,8 @@ }; WX_DECLARE_HASH_SET( MyKey, // type of the keys - ::MyKeyHash, // hasher - ::MyKeyEqual, // key equality predicate + MyKeyHash, // hasher + MyKeyEqual, // key equality predicate CLASSNAME); // name of the class @endcode diff --git a/src/common/translation.cpp b/src/common/translation.cpp index 379eccc45c..c3ee0d73f2 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -1440,7 +1440,7 @@ wxString wxTranslations::ChooseLanguageForDomain(const wxString& WXUNUSED(domain namespace { -WX_DECLARE_HASH_SET(wxString, ::wxStringHash, ::wxStringEqual, +WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, wxLocaleUntranslatedStrings); } diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index a4e705841f..d4d7a12b40 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -72,7 +72,7 @@ const char wxGridNameStr[] = "grid"; // Required for wxIs... functions #include -WX_DECLARE_HASH_SET_WITH_DECL_PTR(int, ::wxIntegerHash, ::wxIntegerEqual, +WX_DECLARE_HASH_SET_WITH_DECL_PTR(int, wxIntegerHash, wxIntegerEqual, wxGridFixedIndicesSet, class WXDLLIMPEXP_ADV); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index bd2482b47d..f39611943b 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -107,7 +107,7 @@ class wxXmlResourceDataRecords : public wxVector // this is a class so that it can be forward-declared }; -WX_DECLARE_HASH_SET_PTR(int, ::wxIntegerHash, ::wxIntegerEqual, wxHashSetInt); +WX_DECLARE_HASH_SET_PTR(int, wxIntegerHash, wxIntegerEqual, wxHashSetInt); class wxIdRange // Holds data for a particular rangename { diff --git a/utils/wxrc/wxrc.cpp b/utils/wxrc/wxrc.cpp index d6b9799e92..1998c76687 100644 --- a/utils/wxrc/wxrc.cpp +++ b/utils/wxrc/wxrc.cpp @@ -32,7 +32,7 @@ #include "wx/mimetype.h" #include "wx/vector.h" -WX_DECLARE_HASH_SET(wxString, ::wxStringHash, ::wxStringEqual, StringSet); +WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, StringSet); class XRCWidgetData {