From e5c41c4eb58fe6195209ea2e74c257c2340d8acb Mon Sep 17 00:00:00 2001 From: Chris Thrasher Date: Mon, 21 Aug 2023 21:29:39 -0600 Subject: [PATCH] Enable move semantics for socket types --- include/SFML/Network/Socket.hpp | 12 ++++++++++++ src/SFML/Network/Socket.cpp | 23 +++++++++++++++++++++++ test/Network/Socket.test.cpp | 28 ++++++++++++++++++++++++++-- test/Network/TcpListener.test.cpp | 4 ++-- test/Network/TcpSocket.test.cpp | 4 ++-- test/Network/UdpSocket.test.cpp | 4 ++-- 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/include/SFML/Network/Socket.hpp b/include/SFML/Network/Socket.hpp index aa53f0e6..34e2f225 100644 --- a/include/SFML/Network/Socket.hpp +++ b/include/SFML/Network/Socket.hpp @@ -83,6 +83,18 @@ public: //////////////////////////////////////////////////////////// Socket& operator=(const Socket&) = delete; + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + Socket(Socket&& socket) noexcept; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment + /// + //////////////////////////////////////////////////////////// + Socket& operator=(Socket&& socket) noexcept; + //////////////////////////////////////////////////////////// /// \brief Set the blocking state of the socket /// diff --git a/src/SFML/Network/Socket.cpp b/src/SFML/Network/Socket.cpp index db73b8cc..1e85202a 100644 --- a/src/SFML/Network/Socket.cpp +++ b/src/SFML/Network/Socket.cpp @@ -31,6 +31,7 @@ #include #include +#include namespace sf @@ -49,6 +50,28 @@ Socket::~Socket() } +//////////////////////////////////////////////////////////// +Socket::Socket(Socket&& socket) noexcept : +m_type(socket.m_type), +m_socket(std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket())), +m_isBlocking(socket.m_isBlocking) +{ +} + + +//////////////////////////////////////////////////////////// +Socket& Socket::operator=(Socket&& socket) noexcept +{ + if (&socket == this) + return *this; + + m_type = socket.m_type; + m_socket = std::exchange(socket.m_socket, priv::SocketImpl::invalidSocket()); + m_isBlocking = socket.m_isBlocking; + return *this; +} + + //////////////////////////////////////////////////////////// void Socket::setBlocking(bool blocking) { diff --git a/test/Network/Socket.test.cpp b/test/Network/Socket.test.cpp index ec819eb4..4cd3d788 100644 --- a/test/Network/Socket.test.cpp +++ b/test/Network/Socket.test.cpp @@ -23,8 +23,8 @@ TEST_CASE("[Network] sf::Socket") STATIC_CHECK(!std::is_constructible_v); STATIC_CHECK(!std::is_copy_constructible_v); STATIC_CHECK(!std::is_copy_assignable_v); - STATIC_CHECK(!std::is_nothrow_move_constructible_v); - STATIC_CHECK(!std::is_nothrow_move_assignable_v); + STATIC_CHECK(std::is_nothrow_move_constructible_v); + STATIC_CHECK(std::is_nothrow_move_assignable_v); } SECTION("Constants") @@ -41,6 +41,30 @@ TEST_CASE("[Network] sf::Socket") CHECK(testSocket.getHandle() == invalidHandle); } + SECTION("Move semantics") + { + SECTION("Construction") + { + TestSocket movedTestSocket; + movedTestSocket.setBlocking(false); + movedTestSocket.create(); + const TestSocket testSocket(std::move(movedTestSocket)); + CHECK(!testSocket.isBlocking()); + CHECK(testSocket.getHandle() != invalidHandle); + } + + SECTION("Assignment") + { + TestSocket movedTestSocket; + movedTestSocket.setBlocking(false); + movedTestSocket.create(); + TestSocket testSocket; + testSocket = std::move(movedTestSocket); + CHECK(!testSocket.isBlocking()); + CHECK(testSocket.getHandle() != invalidHandle); + } + } + SECTION("Set/get blocking") { TestSocket testSocket; diff --git a/test/Network/TcpListener.test.cpp b/test/Network/TcpListener.test.cpp index bcb242d3..d08faa1c 100644 --- a/test/Network/TcpListener.test.cpp +++ b/test/Network/TcpListener.test.cpp @@ -4,5 +4,5 @@ static_assert(!std::is_copy_constructible_v); static_assert(!std::is_copy_assignable_v); -static_assert(!std::is_nothrow_move_constructible_v); -static_assert(!std::is_nothrow_move_assignable_v); +static_assert(std::is_nothrow_move_constructible_v); +static_assert(std::is_nothrow_move_assignable_v); diff --git a/test/Network/TcpSocket.test.cpp b/test/Network/TcpSocket.test.cpp index aeee20ba..4d9079bf 100644 --- a/test/Network/TcpSocket.test.cpp +++ b/test/Network/TcpSocket.test.cpp @@ -4,5 +4,5 @@ static_assert(!std::is_copy_constructible_v); static_assert(!std::is_copy_assignable_v); -static_assert(!std::is_nothrow_move_constructible_v); -static_assert(!std::is_nothrow_move_assignable_v); +static_assert(std::is_nothrow_move_constructible_v); +static_assert(std::is_nothrow_move_assignable_v); diff --git a/test/Network/UdpSocket.test.cpp b/test/Network/UdpSocket.test.cpp index f1016ec3..43e03b30 100644 --- a/test/Network/UdpSocket.test.cpp +++ b/test/Network/UdpSocket.test.cpp @@ -4,5 +4,5 @@ static_assert(!std::is_copy_constructible_v); static_assert(!std::is_copy_assignable_v); -static_assert(!std::is_nothrow_move_constructible_v); -static_assert(!std::is_nothrow_move_assignable_v); +static_assert(std::is_nothrow_move_constructible_v); +static_assert(std::is_nothrow_move_assignable_v);