Skip to content

Commit 35ba5be

Browse files
authored
Merge pull request #312 from gummif/gfa/socket-ref
Problem: No type-safe alternatives when polling or needing a reference to a socket
2 parents 9eef00e + c6a3529 commit 35ba5be

File tree

5 files changed

+391
-157
lines changed

5 files changed

+391
-157
lines changed

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ add_executable(
2020
message.cpp
2121
context.cpp
2222
socket.cpp
23+
socket_ref.cpp
2324
poller.cpp
2425
active_poller.cpp
2526
multipart.cpp

tests/socket.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ TEST_CASE("socket create assign", "[socket]")
2525
{
2626
zmq::context_t context;
2727
zmq::socket_t socket(context, ZMQ_ROUTER);
28-
CHECK(static_cast<void*>(socket));
28+
CHECK(static_cast<bool>(socket));
29+
CHECK(socket.handle() != nullptr);
2930
socket = {};
30-
CHECK(!static_cast<void*>(socket));
31+
CHECK(!static_cast<bool>(socket));
32+
CHECK(socket.handle() == nullptr);
3133
}
3234

3335
TEST_CASE("socket create by enum and destroy", "[socket]")
@@ -75,7 +77,7 @@ TEST_CASE("socket proxy", "[socket]")
7577
auto s3 = std::move(capture);
7678
try
7779
{
78-
zmq::proxy(s1, s2, &s3);
80+
zmq::proxy(s1, s2, zmq::socket_ref(s3));
7981
}
8082
catch (const zmq::error_t& e)
8183
{
@@ -102,7 +104,7 @@ TEST_CASE("socket proxy steerable", "[socket]")
102104
auto s3 = std::move(control);
103105
try
104106
{
105-
zmq::proxy_steerable(s1, s2, ZMQ_NULLPTR, &s3);
107+
zmq::proxy_steerable(s1, s2, zmq::socket_ref(), s3);
106108
}
107109
catch (const zmq::error_t& e)
108110
{

tests/socket_ref.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#include <catch.hpp>
2+
#include <zmq.hpp>
3+
#ifdef ZMQ_CPP11
4+
5+
#ifdef ZMQ_CPP17
6+
static_assert(std::is_nothrow_swappable_v<zmq::socket_ref>);
7+
#endif
8+
static_assert(sizeof(zmq::socket_ref) == sizeof(void *), "size mismatch");
9+
static_assert(alignof(zmq::socket_ref) == alignof(void *), "alignment mismatch");
10+
static_assert(std::is_trivially_copyable<zmq::socket_ref>::value,
11+
"needs to be trivially copyable");
12+
13+
TEST_CASE("socket_ref default init", "[socket_ref]")
14+
{
15+
zmq::socket_ref sr;
16+
CHECK(!sr);
17+
CHECK(sr == nullptr);
18+
CHECK(nullptr == sr);
19+
CHECK(sr.handle() == nullptr);
20+
}
21+
22+
TEST_CASE("socket_ref create from nullptr", "[socket_ref]")
23+
{
24+
zmq::socket_ref sr = nullptr;
25+
CHECK(sr == nullptr);
26+
CHECK(sr.handle() == nullptr);
27+
}
28+
29+
TEST_CASE("socket_ref create from handle", "[socket_ref]")
30+
{
31+
void *np = nullptr;
32+
zmq::socket_ref sr{zmq::from_handle, np};
33+
CHECK(sr == nullptr);
34+
CHECK(sr.handle() == nullptr);
35+
}
36+
37+
TEST_CASE("socket_ref compare", "[socket_ref]")
38+
{
39+
zmq::socket_ref sr1;
40+
zmq::socket_ref sr2;
41+
CHECK(sr1 == sr2);
42+
CHECK(!(sr1 != sr2));
43+
}
44+
45+
TEST_CASE("socket_ref compare from socket_t", "[socket_ref]")
46+
{
47+
zmq::context_t context;
48+
zmq::socket_t s1(context, zmq::socket_type::router);
49+
zmq::socket_t s2(context, zmq::socket_type::dealer);
50+
zmq::socket_ref sr1 = s1;
51+
zmq::socket_ref sr2 = s2;
52+
CHECK(sr1);
53+
CHECK(sr2);
54+
CHECK(sr1 == s1);
55+
CHECK(sr2 == s2);
56+
CHECK(sr1.handle() == s1.handle());
57+
CHECK(sr1 != sr2);
58+
CHECK(sr1.handle() != sr2.handle());
59+
CHECK(sr1 != nullptr);
60+
CHECK(nullptr != sr1);
61+
CHECK(sr2 != nullptr);
62+
const bool comp1 = (sr1 < sr2) != (sr1 >= sr2);
63+
CHECK(comp1);
64+
const bool comp2 = (sr1 > sr2) != (sr1 <= sr2);
65+
CHECK(comp2);
66+
std::hash<zmq::socket_ref> hash;
67+
CHECK(hash(sr1) != hash(sr2));
68+
CHECK(hash(sr1) == hash(s1));
69+
}
70+
71+
TEST_CASE("socket_ref assignment", "[socket_ref]")
72+
{
73+
zmq::context_t context;
74+
zmq::socket_t s1(context, zmq::socket_type::router);
75+
zmq::socket_t s2(context, zmq::socket_type::dealer);
76+
zmq::socket_ref sr1 = s1;
77+
zmq::socket_ref sr2 = s2;
78+
sr1 = s2;
79+
CHECK(sr1 == sr2);
80+
CHECK(sr1.handle() == sr2.handle());
81+
sr1 = std::move(sr2);
82+
CHECK(sr1 == sr2);
83+
CHECK(sr1.handle() == sr2.handle());
84+
sr2 = nullptr;
85+
CHECK(sr1 != sr2);
86+
sr1 = nullptr;
87+
CHECK(sr1 == sr2);
88+
}
89+
90+
TEST_CASE("socket_ref swap", "[socket_ref]")
91+
{
92+
zmq::socket_ref sr1;
93+
zmq::socket_ref sr2;
94+
using std::swap;
95+
swap(sr1, sr2);
96+
}
97+
98+
TEST_CASE("socket_ref reinterpret as void*", "[socket_ref]")
99+
{
100+
struct SVP
101+
{
102+
void *p;
103+
};
104+
struct SSR
105+
{
106+
zmq::socket_ref sr;
107+
} ssr;
108+
109+
zmq::context_t context;
110+
zmq::socket_t socket(context, zmq::socket_type::router);
111+
CHECK(socket.handle() != nullptr);
112+
reinterpret_cast<SVP *>(&ssr)->p = socket.handle();
113+
CHECK(ssr.sr == socket);
114+
}
115+
116+
#endif

0 commit comments

Comments
 (0)