mirror of
https://github.com/zeromq/cppzmq.git
synced 2025-12-24 14:19:10 +01:00
Problem: No type-safe alternatives when polling or needing a reference to a socket
Solution: Introduce a socket_ref that is a non-owning nullable reference to a socket
This commit is contained in:
@@ -20,6 +20,7 @@ add_executable(
|
||||
message.cpp
|
||||
context.cpp
|
||||
socket.cpp
|
||||
socket_ref.cpp
|
||||
poller.cpp
|
||||
active_poller.cpp
|
||||
multipart.cpp
|
||||
|
||||
@@ -25,9 +25,11 @@ TEST_CASE("socket create assign", "[socket]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket(context, ZMQ_ROUTER);
|
||||
CHECK(static_cast<void*>(socket));
|
||||
CHECK(static_cast<bool>(socket));
|
||||
CHECK(socket.handle() != nullptr);
|
||||
socket = {};
|
||||
CHECK(!static_cast<void*>(socket));
|
||||
CHECK(!static_cast<bool>(socket));
|
||||
CHECK(socket.handle() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("socket create by enum and destroy", "[socket]")
|
||||
@@ -75,7 +77,7 @@ TEST_CASE("socket proxy", "[socket]")
|
||||
auto s3 = std::move(capture);
|
||||
try
|
||||
{
|
||||
zmq::proxy(s1, s2, &s3);
|
||||
zmq::proxy(s1, s2, zmq::socket_ref(s3));
|
||||
}
|
||||
catch (const zmq::error_t& e)
|
||||
{
|
||||
@@ -102,7 +104,7 @@ TEST_CASE("socket proxy steerable", "[socket]")
|
||||
auto s3 = std::move(control);
|
||||
try
|
||||
{
|
||||
zmq::proxy_steerable(s1, s2, ZMQ_NULLPTR, &s3);
|
||||
zmq::proxy_steerable(s1, s2, zmq::socket_ref(), s3);
|
||||
}
|
||||
catch (const zmq::error_t& e)
|
||||
{
|
||||
|
||||
116
tests/socket_ref.cpp
Normal file
116
tests/socket_ref.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <catch.hpp>
|
||||
#include <zmq.hpp>
|
||||
#ifdef ZMQ_CPP11
|
||||
|
||||
#ifdef ZMQ_CPP17
|
||||
static_assert(std::is_nothrow_swappable_v<zmq::socket_ref>);
|
||||
#endif
|
||||
static_assert(sizeof(zmq::socket_ref) == sizeof(void *), "size mismatch");
|
||||
static_assert(alignof(zmq::socket_ref) == alignof(void *), "alignment mismatch");
|
||||
static_assert(std::is_trivially_copyable<zmq::socket_ref>::value,
|
||||
"needs to be trivially copyable");
|
||||
|
||||
TEST_CASE("socket_ref default init", "[socket_ref]")
|
||||
{
|
||||
zmq::socket_ref sr;
|
||||
CHECK(!sr);
|
||||
CHECK(sr == nullptr);
|
||||
CHECK(nullptr == sr);
|
||||
CHECK(sr.handle() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref create from nullptr", "[socket_ref]")
|
||||
{
|
||||
zmq::socket_ref sr = nullptr;
|
||||
CHECK(sr == nullptr);
|
||||
CHECK(sr.handle() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref create from handle", "[socket_ref]")
|
||||
{
|
||||
void *np = nullptr;
|
||||
zmq::socket_ref sr{zmq::from_handle, np};
|
||||
CHECK(sr == nullptr);
|
||||
CHECK(sr.handle() == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref compare", "[socket_ref]")
|
||||
{
|
||||
zmq::socket_ref sr1;
|
||||
zmq::socket_ref sr2;
|
||||
CHECK(sr1 == sr2);
|
||||
CHECK(!(sr1 != sr2));
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref compare from socket_t", "[socket_ref]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t s1(context, zmq::socket_type::router);
|
||||
zmq::socket_t s2(context, zmq::socket_type::dealer);
|
||||
zmq::socket_ref sr1 = s1;
|
||||
zmq::socket_ref sr2 = s2;
|
||||
CHECK(sr1);
|
||||
CHECK(sr2);
|
||||
CHECK(sr1 == s1);
|
||||
CHECK(sr2 == s2);
|
||||
CHECK(sr1.handle() == s1.handle());
|
||||
CHECK(sr1 != sr2);
|
||||
CHECK(sr1.handle() != sr2.handle());
|
||||
CHECK(sr1 != nullptr);
|
||||
CHECK(nullptr != sr1);
|
||||
CHECK(sr2 != nullptr);
|
||||
const bool comp1 = (sr1 < sr2) != (sr1 >= sr2);
|
||||
CHECK(comp1);
|
||||
const bool comp2 = (sr1 > sr2) != (sr1 <= sr2);
|
||||
CHECK(comp2);
|
||||
std::hash<zmq::socket_ref> hash;
|
||||
CHECK(hash(sr1) != hash(sr2));
|
||||
CHECK(hash(sr1) == hash(s1));
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref assignment", "[socket_ref]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t s1(context, zmq::socket_type::router);
|
||||
zmq::socket_t s2(context, zmq::socket_type::dealer);
|
||||
zmq::socket_ref sr1 = s1;
|
||||
zmq::socket_ref sr2 = s2;
|
||||
sr1 = s2;
|
||||
CHECK(sr1 == sr2);
|
||||
CHECK(sr1.handle() == sr2.handle());
|
||||
sr1 = std::move(sr2);
|
||||
CHECK(sr1 == sr2);
|
||||
CHECK(sr1.handle() == sr2.handle());
|
||||
sr2 = nullptr;
|
||||
CHECK(sr1 != sr2);
|
||||
sr1 = nullptr;
|
||||
CHECK(sr1 == sr2);
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref swap", "[socket_ref]")
|
||||
{
|
||||
zmq::socket_ref sr1;
|
||||
zmq::socket_ref sr2;
|
||||
using std::swap;
|
||||
swap(sr1, sr2);
|
||||
}
|
||||
|
||||
TEST_CASE("socket_ref reinterpret as void*", "[socket_ref]")
|
||||
{
|
||||
struct SVP
|
||||
{
|
||||
void *p;
|
||||
};
|
||||
struct SSR
|
||||
{
|
||||
zmq::socket_ref sr;
|
||||
} ssr;
|
||||
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket(context, zmq::socket_type::router);
|
||||
CHECK(socket.handle() != nullptr);
|
||||
reinterpret_cast<SVP *>(&ssr)->p = socket.handle();
|
||||
CHECK(ssr.sr == socket);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user