Skip to content

Commit d1e7c53

Browse files
authored
Merge pull request #303 from gummif/gfa/swap
Problem: Missing swap functions
2 parents 5c69a36 + 83b91c8 commit d1e7c53

File tree

7 files changed

+108
-9
lines changed

7 files changed

+108
-9
lines changed

tests/context.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include <catch.hpp>
22
#include <zmq.hpp>
33

4+
#if (__cplusplus >= 201703L)
5+
static_assert(std::is_nothrow_swappable<zmq::context_t>::value,
6+
"context_t should be nothrow swappable");
7+
#endif
8+
49
TEST_CASE("context construct default and destroy", "[context]")
510
{
611
zmq::context_t context;
@@ -12,3 +17,13 @@ TEST_CASE("context create, close and destroy", "[context]")
1217
context.close();
1318
CHECK(NULL == (void *) context);
1419
}
20+
21+
#ifdef ZMQ_CPP11
22+
TEST_CASE("context swap", "[context]")
23+
{
24+
zmq::context_t context1;
25+
zmq::context_t context2;
26+
using std::swap;
27+
swap(context1, context2);
28+
}
29+
#endif

tests/message.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,33 @@ static_assert(!std::is_copy_constructible<zmq::message_t>::value,
88
static_assert(!std::is_copy_assignable<zmq::message_t>::value,
99
"message_t should not be copy-assignable");
1010
#endif
11+
#if (__cplusplus >= 201703L)
12+
static_assert(std::is_nothrow_swappable<zmq::message_t>::value,
13+
"message_t should be nothrow swappable");
14+
#endif
1115

1216
TEST_CASE("message default constructed", "[message]")
1317
{
1418
const zmq::message_t message;
1519
CHECK(0u == message.size());
1620
}
1721

22+
#ifdef ZMQ_CPP11
23+
TEST_CASE("message swap", "[message]")
24+
{
25+
const std::string data = "foo";
26+
zmq::message_t message1;
27+
zmq::message_t message2(data.data(), data.size());
28+
using std::swap;
29+
swap(message1, message2);
30+
CHECK(message1.size() == data.size());
31+
CHECK(message2.size() == 0);
32+
swap(message1, message2);
33+
CHECK(message1.size() == 0);
34+
CHECK(message2.size() == data.size());
35+
}
36+
#endif
37+
1838
namespace {
1939
const char *const data = "Hi";
2040
}

tests/monitor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <thread>
55
#include <mutex>
66
#include <condition_variable>
7+
#include <functional>
78

89
class mock_monitor_t : public zmq::monitor_t
910
{

tests/poller.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
#include <array>
66
#include <memory>
77

8+
#if (__cplusplus >= 201703L)
9+
static_assert(std::is_nothrow_swappable<zmq::poller_t<>>::value,
10+
"poller_t should be nothrow swappable");
11+
#endif
12+
813
TEST_CASE("poller create destroy", "[poller]")
914
{
1015
zmq::poller_t<> poller;
@@ -28,6 +33,14 @@ TEST_CASE("poller move assign empty", "[poller]")
2833
b = std::move(a);
2934
}
3035

36+
TEST_CASE("poller swap", "[poller]")
37+
{
38+
zmq::poller_t<> a;
39+
zmq::poller_t<> b;
40+
using std::swap;
41+
swap(a, b);
42+
}
43+
3144
TEST_CASE("poller move construct non empty", "[poller]")
3245
{
3346
zmq::context_t context;

tests/socket.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
#include <future>
55
#endif
66

7+
#if (__cplusplus >= 201703L)
8+
static_assert(std::is_nothrow_swappable<zmq::socket_t>::value,
9+
"socket_t should be nothrow swappable");
10+
#endif
11+
712
TEST_CASE("socket create destroy", "[socket]")
813
{
914
zmq::context_t context;
@@ -16,6 +21,15 @@ TEST_CASE("socket create by enum and destroy", "[socket]")
1621
zmq::context_t context;
1722
zmq::socket_t socket(context, zmq::socket_type::router);
1823
}
24+
25+
TEST_CASE("socket swap", "[socket]")
26+
{
27+
zmq::context_t context;
28+
zmq::socket_t socket1(context, zmq::socket_type::router);
29+
zmq::socket_t socket2(context, zmq::socket_type::dealer);
30+
using std::swap;
31+
swap(socket1, socket2);
32+
}
1933
#endif
2034

2135
TEST_CASE("socket sends and receives const buffer", "[socket]")

zmq.hpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@
7373
#ifdef ZMQ_CPP11
7474
#include <chrono>
7575
#include <tuple>
76-
#include <functional>
77-
#include <unordered_map>
7876
#include <memory>
7977
#endif
8078

@@ -492,6 +490,12 @@ class message_t
492490
return os.str();
493491
}
494492

493+
void swap(message_t &other) ZMQ_NOTHROW
494+
{
495+
// this assumes zmq::msg_t from libzmq is trivially relocatable
496+
std::swap(msg, other.msg);
497+
}
498+
495499
private:
496500
// The underlying message
497501
zmq_msg_t msg;
@@ -502,6 +506,11 @@ class message_t
502506
void operator=(const message_t &) ZMQ_DELETED_FUNCTION;
503507
};
504508

509+
inline void swap(message_t &a, message_t &b) ZMQ_NOTHROW
510+
{
511+
a.swap(b);
512+
}
513+
505514
class context_t
506515
{
507516
public:
@@ -570,13 +579,22 @@ class context_t
570579

571580
operator bool() const ZMQ_NOTHROW { return ptr != ZMQ_NULLPTR; }
572581

582+
void swap(context_t &other) ZMQ_NOTHROW
583+
{
584+
std::swap(ptr, other.ptr);
585+
}
586+
573587
private:
574588
void *ptr;
575589

576590
context_t(const context_t &) ZMQ_DELETED_FUNCTION;
577591
void operator=(const context_t &) ZMQ_DELETED_FUNCTION;
578592
};
579593

594+
inline void swap(context_t &a, context_t &b) ZMQ_NOTHROW {
595+
a.swap(b);
596+
}
597+
580598
#ifdef ZMQ_CPP11
581599
enum class socket_type : int
582600
{
@@ -783,6 +801,12 @@ class socket_t
783801
}
784802
#endif
785803

804+
void swap(socket_t &other) ZMQ_NOTHROW
805+
{
806+
std::swap(ptr, other.ptr);
807+
std::swap(ctxptr, other.ctxptr);
808+
}
809+
786810
private:
787811
void *ptr;
788812
void *ctxptr;
@@ -791,6 +815,10 @@ class socket_t
791815
void operator=(const socket_t &) ZMQ_DELETED_FUNCTION;
792816
};
793817

818+
inline void swap(socket_t &a, socket_t &b) ZMQ_NOTHROW {
819+
a.swap(b);
820+
}
821+
794822
ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects")
795823
inline void proxy(void *frontend, void *backend, void *capture)
796824
{
@@ -1147,6 +1175,8 @@ class monitor_t
11471175
template<typename T = void> class poller_t
11481176
{
11491177
public:
1178+
poller_t() = default;
1179+
11501180
void add(zmq::socket_t &socket, short events, T *user_data)
11511181
{
11521182
if (0
@@ -1192,17 +1222,19 @@ template<typename T = void> class poller_t
11921222
}
11931223

11941224
private:
1195-
std::unique_ptr<void, std::function<void(void *)>> poller_ptr{
1225+
std::unique_ptr<void, void(*)(void *)> poller_ptr{
11961226
[]() {
11971227
auto poller_new = zmq_poller_new();
11981228
if (poller_new)
11991229
return poller_new;
12001230
throw error_t();
1201-
}(),
1202-
[](void *ptr) {
1203-
int rc = zmq_poller_destroy(&ptr);
1204-
ZMQ_ASSERT(rc == 0);
1205-
}};
1231+
}(), &destroy_poller};
1232+
1233+
static void destroy_poller(void *ptr)
1234+
{
1235+
int rc = zmq_poller_destroy(&ptr);
1236+
ZMQ_ASSERT(rc == 0);
1237+
}
12061238
};
12071239
#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
12081240

zmq_addon.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <iomanip>
3131
#include <sstream>
3232
#include <stdexcept>
33+
#ifdef ZMQ_CPP11
34+
#include <functional>
35+
#include <unordered_map>
36+
#endif
3337

3438
namespace zmq
3539
{
@@ -245,7 +249,7 @@ class multipart_t
245249
m_parts.pop_back();
246250
return message;
247251
}
248-
252+
249253
// get message part from front
250254
const message_t &front()
251255
{

0 commit comments

Comments
 (0)