From 18393ea5cbdb164103d048198ad146b685214fa2 Mon Sep 17 00:00:00 2001 From: vittorioromeo Date: Mon, 20 Jan 2025 16:24:04 +0100 Subject: [PATCH] Add non-`const` overload of `Event::visit` --- include/SFML/Window/Event.hpp | 11 +++++++ include/SFML/Window/Event.inl | 8 +++++ include/SFML/Window/WindowBase.inl | 2 +- test/Window/Event.test.cpp | 47 ++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index 28bd4cf12..df2972b6a 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -338,6 +338,17 @@ public: template [[nodiscard]] const TEventSubtype* getIf() const; + //////////////////////////////////////////////////////////// + /// \brief Apply a visitor to the event + /// + /// \param visitor The visitor to apply + /// + /// \return The result of applying the visitor to the event + /// + //////////////////////////////////////////////////////////// + template + decltype(auto) visit(T&& visitor); + //////////////////////////////////////////////////////////// /// \brief Apply a visitor to the event /// diff --git a/include/SFML/Window/Event.inl b/include/SFML/Window/Event.inl index 8046a4bb3..daabd2fd3 100644 --- a/include/SFML/Window/Event.inl +++ b/include/SFML/Window/Event.inl @@ -78,6 +78,14 @@ const TEventSubtype* Event::getIf() const } +//////////////////////////////////////////////////////////// +template +decltype(auto) Event::visit(T&& visitor) +{ + return std::visit(std::forward(visitor), m_data); +} + + //////////////////////////////////////////////////////////// template decltype(auto) Event::visit(T&& visitor) const diff --git a/include/SFML/Window/WindowBase.inl b/include/SFML/Window/WindowBase.inl index 19a939564..2c5c89c7b 100644 --- a/include/SFML/Window/WindowBase.inl +++ b/include/SFML/Window/WindowBase.inl @@ -68,7 +68,7 @@ void WindowBase::handleEvents(Ts&&... handlers) // NOLINT(cppcoreguidelines-miss // NOLINTNEXTLINE(misc-const-correctness) priv::OverloadSet overloadSet{std::forward(handlers)..., [](const priv::DelayOverloadResolution&) { /* ignore */ }}; - while (const std::optional event = pollEvent()) + while (std::optional event = pollEvent()) event->visit(overloadSet); } diff --git a/test/Window/Event.test.cpp b/test/Window/Event.test.cpp index 11d9ee3e4..9977f3618 100644 --- a/test/Window/Event.test.cpp +++ b/test/Window/Event.test.cpp @@ -9,17 +9,22 @@ namespace { struct { - std::string_view operator()(const sf::Event::Closed&) const + std::string_view operator()(sf::Event::Closed&) const { - return "Closed"; + return "Closed (non-const)"; } - std::string_view operator()(const sf::Event::Resized&) const + std::string_view operator()(const sf::Event::Closed&) const + { + return "Closed (const)"; + } + + std::string_view operator()(sf::Event::Resized&) const { return "Resized"; } - std::string_view operator()(const sf::Event::KeyPressed&) const + std::string_view operator()(sf::Event::KeyPressed) const { return "KeyPressed"; } @@ -306,10 +311,34 @@ TEST_CASE("[Window] sf::Event") SECTION("visit()") { - CHECK(sf::Event(sf::Event::Closed{}).visit(visitor) == "Closed"); - CHECK(sf::Event(sf::Event::Resized{}).visit(visitor) == "Resized"); - CHECK(sf::Event(sf::Event::FocusLost{}).visit(visitor) == "Other"); - CHECK(sf::Event(sf::Event::FocusGained{}).visit(visitor) == "Other"); - CHECK(sf::Event(sf::Event::KeyPressed{}).visit(visitor) == "KeyPressed"); + SECTION("Non-const") + { + sf::Event closed = sf::Event::Closed{}; + CHECK(closed.visit(visitor) == "Closed (non-const)"); + + sf::Event resized = sf::Event::Resized{}; + CHECK(resized.visit(visitor) == "Resized"); + + sf::Event keyPressed = sf::Event::KeyPressed{}; + CHECK(keyPressed.visit(visitor) == "KeyPressed"); + + sf::Event focusLost = sf::Event::FocusLost{}; + CHECK(focusLost.visit(visitor) == "Other"); + } + + SECTION("Const") + { + const sf::Event closed = sf::Event::Closed{}; + CHECK(closed.visit(visitor) == "Closed (const)"); + + const sf::Event resized = sf::Event::Resized{}; + CHECK(resized.visit(visitor) == "Other"); // Cannot use non-const reference callback + + const sf::Event keyPressed = sf::Event::KeyPressed{}; + CHECK(keyPressed.visit(visitor) == "KeyPressed"); + + const sf::Event focusLost = sf::Event::FocusLost{}; + CHECK(focusLost.visit(visitor) == "Other"); + } } }