From b9771fa3af8570f2ba1d2d4b7742de84d37cc71e Mon Sep 17 00:00:00 2001 From: Pixel-Tony Date: Thu, 9 Jan 2025 23:21:25 +0100 Subject: [PATCH] move event handler verification to the Event class --- include/SFML/Window/Event.hpp | 16 +++++------- include/SFML/Window/Event.inl | 39 +++++++++++++++++++++++++++--- include/SFML/Window/WindowBase.inl | 37 +--------------------------- 3 files changed, 43 insertions(+), 49 deletions(-) diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index 8ef7d2cce..94d68ce47 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -339,15 +339,15 @@ public: [[nodiscard]] const TEventSubtype* getIf() const; //////////////////////////////////////////////////////////// - /// \brief Apply a visitor to the event + /// \brief Apply visitors to the event /// - /// \param visitor The visitor to apply + /// \param visitors Visitors to apply /// - /// \return The result of applying the visitor to the event + /// \return The result of applying visitors to the event /// //////////////////////////////////////////////////////////// - template - decltype(auto) visit(T&& visitor) const; + template + decltype(auto) visit(Ts&&... visitors) const; private: //////////////////////////////////////////////////////////// @@ -396,12 +396,8 @@ private: return (std::is_invocable_v || ...); } -public: template - static constexpr bool isValidHandler() - { - return isInvokableWithAnyOf(static_cast(nullptr)); - } + static constexpr bool isValidHandler = isInvokableWithAnyOf(static_cast(nullptr)); }; } // namespace sf diff --git a/include/SFML/Window/Event.inl b/include/SFML/Window/Event.inl index 4dc18a9ca..bde2cd47e 100644 --- a/include/SFML/Window/Event.inl +++ b/include/SFML/Window/Event.inl @@ -38,6 +38,28 @@ namespace sf { +namespace priv +{ +template +struct OverloadSet : Ts... +{ + using Ts::operator()...; +#if defined(_MSC_VER) && !defined(__clang__) + unsigned char dummy; // Dummy variable to ensure that this struct is not empty thus avoiding a crash due to an MSVC bug +#endif +}; +template +OverloadSet(Ts...) -> OverloadSet; + +struct DelayOverloadResolution +{ + template + DelayOverloadResolution(const T&) + { + } +}; +} // namespace priv + //////////////////////////////////////////////////////////// template Event::Event(const TEventSubtype& eventSubtype) @@ -79,10 +101,21 @@ const TEventSubtype* Event::getIf() const //////////////////////////////////////////////////////////// -template -decltype(auto) Event::visit(T&& visitor) const +template +decltype(auto) Event::visit(Ts&&... visitors) const { - return std::visit(std::forward(visitor), m_data); + static_assert(sizeof...(Ts) > 0, "Must provide at least one handler"); + static_assert((isValidHandler && ...), + "All event handlers must accept a single parameter, either a const reference or a value"); + + // Disable misc-const-correctness for this line since clang-tidy + // complains about it even though the code would become uncompilable + + // NOLINTNEXTLINE(misc-const-correctness) + return std::visit(priv::OverloadSet{std::forward(visitors)..., + [](const priv::DelayOverloadResolution&) { /* ignore */ }}, + m_data); } + } // namespace sf diff --git a/include/SFML/Window/WindowBase.inl b/include/SFML/Window/WindowBase.inl index 772b487c4..e7a67d70a 100644 --- a/include/SFML/Window/WindowBase.inl +++ b/include/SFML/Window/WindowBase.inl @@ -28,50 +28,15 @@ #include #include // NOLINT(misc-header-include-cycle) -#include - namespace sf { -namespace priv -{ -template -struct OverloadSet : Ts... -{ - using Ts::operator()...; -#if defined(_MSC_VER) && !defined(__clang__) - unsigned char dummy; // Dummy variable to ensure that this struct is not empty thus avoiding a crash due to an MSVC bug -#endif -}; -template -OverloadSet(Ts...) -> OverloadSet; - -struct DelayOverloadResolution -{ - template - DelayOverloadResolution(const T&) - { - } -}; -} // namespace priv - - //////////////////////////////////////////////////////////// template void WindowBase::handleEvents(Ts&&... handlers) // NOLINT(cppcoreguidelines-missing-std-forward) { - static_assert(sizeof...(Ts) > 0, "Must provide at least one handler"); - static_assert((Event::isValidHandler() && ...), - "All event handlers must accept a single parameter, either a const reference or a value"); - - // Disable misc-const-correctness for this line since clang-tidy - // complains about it even though the code would become uncompilable - - // NOLINTNEXTLINE(misc-const-correctness) - priv::OverloadSet overloadSet{std::forward(handlers)..., [](const priv::DelayOverloadResolution&) { /* ignore */ }}; - while (const std::optional event = pollEvent()) - event->visit(overloadSet); + event->visit(handlers...); } } // namespace sf