Merge branch 'noexcept-event-tables'

Allow using noexcept handlers in event tables.

See https://github.com/wxWidgets/wxWidgets/pull/1788
This commit is contained in:
Vadim Zeitlin
2020-04-12 16:41:55 +02:00
4 changed files with 51 additions and 2 deletions

View File

@@ -191,6 +191,7 @@ Currently the following symbols exist:
@itemdef{wxHAS_NATIVE_ANIMATIONCTRL, Defined if native wxAnimationCtrl class is being used (this symbol only exists in wxWidgets 3.1.4 and later).} @itemdef{wxHAS_NATIVE_ANIMATIONCTRL, Defined if native wxAnimationCtrl class is being used (this symbol only exists in wxWidgets 3.1.4 and later).}
@itemdef{wxHAS_NATIVE_DATAVIEWCTRL, Defined if native wxDataViewCtrl class is being used (this symbol only exists in wxWidgets 3.1.4 and later).} @itemdef{wxHAS_NATIVE_DATAVIEWCTRL, Defined if native wxDataViewCtrl class is being used (this symbol only exists in wxWidgets 3.1.4 and later).}
@itemdef{wxHAS_NATIVE_WINDOW, Defined if wxNativeWindow class is available.} @itemdef{wxHAS_NATIVE_WINDOW, Defined if wxNativeWindow class is available.}
@itemdef{wxHAS_NOEXCEPT, Defined if the currently used compiler supports C++11 @c noexcept. @c wxNOEXCEPT is defined as this keyword in this case, and as nothing otherwise.}
@itemdef{wxHAS_NULLPTR_T, Defined if the currently used compiler supports C++11 @c nullptr.} @itemdef{wxHAS_NULLPTR_T, Defined if the currently used compiler supports C++11 @c nullptr.}
@itemdef{wxHAS_IMAGES_IN_RESOURCES, Defined if <a href="http://en.wikipedia.org/wiki/Resource_(Windows)"> @itemdef{wxHAS_IMAGES_IN_RESOURCES, Defined if <a href="http://en.wikipedia.org/wiki/Resource_(Windows)">
Windows resource files</a> or OS/2 resource files are available on the current platform.} Windows resource files</a> or OS/2 resource files are available on the current platform.}

View File

@@ -285,12 +285,19 @@ typedef short int WXTYPE;
#define wxOVERRIDE #define wxOVERRIDE
#endif /* HAVE_OVERRIDE */ #endif /* HAVE_OVERRIDE */
/* same for defaulted member function keyword */ /* same for more C++11 keywords which don't have such historic baggage as
override and so can be detected by just testing for C++11 support (which
still requires handling MSVS specially, unfortunately) */
#if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14) #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14)
#define wxHAS_MEMBER_DEFAULT #define wxHAS_MEMBER_DEFAULT
#define wxMEMBER_DEFAULT = default #define wxMEMBER_DEFAULT = default
#define wxHAS_NOEXCEPT
#define wxNOEXCEPT noexcept
#else #else
#define wxMEMBER_DEFAULT #define wxMEMBER_DEFAULT
#define wxNOEXCEPT
#endif #endif
/* /*

View File

@@ -144,9 +144,43 @@ inline wxEventFunction wxEventFunctionCast(void (wxEvtHandler::*func)(T&))
wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE() wxGCC_WARNING_RESTORE_CAST_FUNCTION_TYPE()
} }
// Special hack to remove "noexcept" from the function type when using C++17 or
// later: static_cast<> below would fail to cast a member function pointer to a
// member of a derived class to the base class if noexcept is specified for the
// former, so remove it first if necessary.
#if __cplusplus >= 201703L
namespace wxPrivate
{
// Generic template version, doing nothing.
template <typename T>
struct RemoveNoexceptEventHandler
{
using type = T;
};
// Specialization removing noexcept when it's specified.
//
// Note that this doesn't pretend to be generally suitable, this is just enough
// to work in our particular case.
template <typename R, typename C, typename E>
struct RemoveNoexceptEventHandler<R (C::*)(E&) noexcept>
{
using type = R (C::*)(E&);
};
} // namespace wxPrivate
#define wxREMOVE_NOEXCEPT_EVENT_HANDLER(pmf) \
static_cast<wxPrivate::RemoveNoexceptEventHandler<decltype(pmf)>::type>(pmf)
#else
#define wxREMOVE_NOEXCEPT_EVENT_HANDLER(pmf) pmf
#endif
// Try to cast the given event handler to the correct handler type: // Try to cast the given event handler to the correct handler type:
#define wxEVENT_HANDLER_CAST( functype, func ) \ #define wxEVENT_HANDLER_CAST( functype, func ) \
wxEventFunctionCast(static_cast<functype>(&func)) wxEventFunctionCast(static_cast<functype>(wxREMOVE_NOEXCEPT_EVENT_HANDLER(&func)))
// The tag is a type associated to the event type (which is an integer itself, // The tag is a type associated to the event type (which is an integer itself,

View File

@@ -122,6 +122,9 @@ public:
void OnEvent(wxEvent&) { g_called.method = true; } void OnEvent(wxEvent&) { g_called.method = true; }
void OnAnotherEvent(AnotherEvent&); void OnAnotherEvent(AnotherEvent&);
void OnIdle(wxIdleEvent&) { g_called.method = true; } void OnIdle(wxIdleEvent&) { g_called.method = true; }
#ifdef wxHAS_NOEXCEPT
void OnIdleNoExcept(wxIdleEvent&) noexcept { }
#endif
private: private:
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
@@ -138,6 +141,10 @@ wxBEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
EVT_MYEVENT(MyClassWithEventTable::OnMyEvent) EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
EVT_MYEVENT(MyClassWithEventTable::OnEvent) EVT_MYEVENT(MyClassWithEventTable::OnEvent)
#ifdef wxHAS_NOEXCEPT
EVT_IDLE(MyClassWithEventTable::OnIdleNoExcept)
#endif
// this shouldn't compile: // this shouldn't compile:
//EVT_MYEVENT(MyClassWithEventTable::OnIdle) //EVT_MYEVENT(MyClassWithEventTable::OnIdle)
//EVT_IDLE(MyClassWithEventTable::OnAnotherEvent) //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)