From cbe449908efe4cd08a2a58571364f3a7da321fce Mon Sep 17 00:00:00 2001 From: Jaakko Moisio Date: Thu, 21 Oct 2021 20:51:33 +0300 Subject: [PATCH] Problem: `sock.get(zmq::sockopt::type)` is not typesafe Solution: Add `zmq::sockopt::socket_type` that is used to `get()` an enumerator from `zmq::socket_type` instead of plain `int`. It makes code like this compile: #include #include int main() { zmq::context_t ctx; zmq::socket_t sock(ctx, zmq::socket_type::push); assert(sock.get(zmq::sockopt::socket_type) == zmq::socket_type::push); return 0; } --- tests/socket.cpp | 5 +++- zmq.hpp | 73 +++++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/tests/socket.cpp b/tests/socket.cpp index 87c2af1..cebee4b 100644 --- a/tests/socket.cpp +++ b/tests/socket.cpp @@ -406,7 +406,10 @@ TEST_CASE("socket check integral options", "[socket]") #endif #ifdef ZMQ_TYPE check_integral_opt_get(zmq::sockopt::type, router, "type"); -#endif +#ifdef ZMQ_CPP11 + check_integral_opt_get(zmq::sockopt::socket_type, router, "socket_type"); +#endif // ZMQ_CPP11 +#endif // ZMQ_TYPE #ifdef ZMQ_HAVE_VMCI #ifdef ZMQ_VMCI_BUFFER_SIZE diff --git a/zmq.hpp b/zmq.hpp index 300dda5..b4629b0 100644 --- a/zmq.hpp +++ b/zmq.hpp @@ -1376,6 +1376,39 @@ constexpr const_buffer operator"" _zbuf(const char32_t *str, size_t len) noexcep } } +#ifdef ZMQ_CPP11 +enum class socket_type : int +{ + req = ZMQ_REQ, + rep = ZMQ_REP, + dealer = ZMQ_DEALER, + router = ZMQ_ROUTER, + pub = ZMQ_PUB, + sub = ZMQ_SUB, + xpub = ZMQ_XPUB, + xsub = ZMQ_XSUB, + push = ZMQ_PUSH, + pull = ZMQ_PULL, +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) + server = ZMQ_SERVER, + client = ZMQ_CLIENT, + radio = ZMQ_RADIO, + dish = ZMQ_DISH, + gather = ZMQ_GATHER, + scatter = ZMQ_SCATTER, + dgram = ZMQ_DGRAM, +#endif +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) + peer = ZMQ_PEER, + channel = ZMQ_CHANNEL, +#endif +#if ZMQ_VERSION_MAJOR >= 4 + stream = ZMQ_STREAM, +#endif + pair = ZMQ_PAIR +}; +#endif + namespace sockopt { // There are two types of options, @@ -1615,7 +1648,10 @@ ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int); #endif #ifdef ZMQ_TYPE ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int); -#endif +#ifdef ZMQ_CPP11 +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, socket_type, socket_type); +#endif // ZMQ_CPP11 +#endif // ZMQ_TYPE #ifdef ZMQ_UNSUBSCRIBE ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe); #endif @@ -1757,7 +1793,7 @@ class socket_base template ZMQ_NODISCARD T get(sockopt::integral_option) const { - static_assert(std::is_integral::value, "T must be integral"); + static_assert(std::is_scalar::value, "T must be scalar"); T val; size_t size = sizeof val; get_option(Opt, &val, &size); @@ -2026,39 +2062,6 @@ class socket_base }; } // namespace detail -#ifdef ZMQ_CPP11 -enum class socket_type : int -{ - req = ZMQ_REQ, - rep = ZMQ_REP, - dealer = ZMQ_DEALER, - router = ZMQ_ROUTER, - pub = ZMQ_PUB, - sub = ZMQ_SUB, - xpub = ZMQ_XPUB, - xsub = ZMQ_XSUB, - push = ZMQ_PUSH, - pull = ZMQ_PULL, -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - server = ZMQ_SERVER, - client = ZMQ_CLIENT, - radio = ZMQ_RADIO, - dish = ZMQ_DISH, - gather = ZMQ_GATHER, - scatter = ZMQ_SCATTER, - dgram = ZMQ_DGRAM, -#endif -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) - peer = ZMQ_PEER, - channel = ZMQ_CHANNEL, -#endif -#if ZMQ_VERSION_MAJOR >= 4 - stream = ZMQ_STREAM, -#endif - pair = ZMQ_PAIR -}; -#endif - struct from_handle_t { struct _private