26 #ifndef __ZMQ_HPP_INCLUDED__ 27 #define __ZMQ_HPP_INCLUDED__ 36 #if (defined(__cplusplus) && __cplusplus >= 201103L) \ 37 || (defined(_MSC_VER) && _MSC_VER >= 1900) 40 #if (defined(__cplusplus) && __cplusplus >= 201402L) \ 41 || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) \ 42 || (defined(_HAS_CXX17) \ 44 == 1) // _HAS_CXX14 might not be defined when using C++17 on MSVC 47 #if (defined(__cplusplus) && __cplusplus >= 201703L) \ 48 || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) 52 #if defined(ZMQ_CPP14) 53 #define ZMQ_DEPRECATED(msg) [[deprecated(msg)]] 54 #elif defined(_MSC_VER) 55 #define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg)) 56 #elif defined(__GNUC__) 57 #define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg))) 60 #if defined(ZMQ_CPP17) 61 #define ZMQ_NODISCARD [[nodiscard]] 66 #if defined(ZMQ_CPP11) 67 #define ZMQ_NOTHROW noexcept 68 #define ZMQ_EXPLICIT explicit 69 #define ZMQ_OVERRIDE override 70 #define ZMQ_NULLPTR nullptr 71 #define ZMQ_CONSTEXPR_FN constexpr 72 #define ZMQ_CONSTEXPR_VAR constexpr 73 #define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg) 75 #define ZMQ_NOTHROW throw() 79 #define ZMQ_CONSTEXPR_FN 80 #define ZMQ_CONSTEXPR_VAR const 81 #define ZMQ_CPP11_DEPRECATED(msg) 103 #if __has_include(<optional>) 105 #define ZMQ_HAS_OPTIONAL 1 107 #if __has_include(<string_view>) 108 #include <string_view> 109 #define ZMQ_HAS_STRING_VIEW 1 116 #define CPPZMQ_VERSION_MAJOR 4 117 #define CPPZMQ_VERSION_MINOR 7 118 #define CPPZMQ_VERSION_PATCH 0 120 #define CPPZMQ_VERSION \ 121 ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, \ 122 CPPZMQ_VERSION_PATCH) 125 #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) \ 126 && defined(__GXX_EXPERIMENTAL_CXX0X__)) 127 #define ZMQ_HAS_RVALUE_REFS 128 #define ZMQ_DELETED_FUNCTION = delete 129 #elif defined(__clang__) 130 #if __has_feature(cxx_rvalue_references) 131 #define ZMQ_HAS_RVALUE_REFS 134 #if __has_feature(cxx_deleted_functions) 135 #define ZMQ_DELETED_FUNCTION = delete 137 #define ZMQ_DELETED_FUNCTION 139 #elif defined(_MSC_VER) && (_MSC_VER >= 1900) 140 #define ZMQ_HAS_RVALUE_REFS 141 #define ZMQ_DELETED_FUNCTION = delete 142 #elif defined(_MSC_VER) && (_MSC_VER >= 1600) 143 #define ZMQ_HAS_RVALUE_REFS 144 #define ZMQ_DELETED_FUNCTION 146 #define ZMQ_DELETED_FUNCTION 149 #if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) \ 150 && defined(__GNUC__) && __GNUC__ < 5 151 #define ZMQ_CPP11_PARTIAL 152 #elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805 155 #define ZMQ_CPP11_PARTIAL 159 #ifdef ZMQ_CPP11_PARTIAL 160 #define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) 162 #include <type_traits> 163 #define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value 167 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) 168 #define ZMQ_NEW_MONITOR_EVENT_LAYOUT 171 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) 172 #define ZMQ_HAS_PROXY_STEERABLE 182 #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0) 183 #define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags) 190 #define ZMQ_ASSERT(expression) assert(expression) 192 #define ZMQ_ASSERT(expression) (void) (expression) 204 template<
class T>
auto begin(T &&r) -> decltype(begin(std::forward<T>(r)))
206 return begin(std::forward<T>(r));
208 template<
class T>
auto end(T &&r) -> decltype(end(std::forward<T>(r)))
210 return end(std::forward<T>(r));
214 template<
class T>
using void_t = void;
217 using iter_value_t =
typename std::iterator_traits<Iter>::value_type;
219 template<
class Range>
220 using range_iter_t = decltype(
223 template<
class Range>
using range_value_t = iter_value_t<range_iter_t<Range>>;
225 template<
class T,
class =
void>
struct is_range : std::false_type
233 ranges::begin(std::declval<typename std::remove_reference<T>::type &>())
234 == ranges::end(std::declval<typename std::remove_reference<T>::type &>()))>>
251 return zmq_strerror(errnum);
253 int num()
const {
return errnum; }
259 inline int poll(zmq_pollitem_t *items_,
size_t nitems_,
long timeout_ = -1)
261 int rc = zmq_poll(items_, static_cast<int>(nitems_), timeout_);
267 ZMQ_DEPRECATED(
"from 4.3.1, use poll taking non-const items")
268 inline
int poll(zmq_pollitem_t const *items_,
size_t nitems_,
long timeout_ = -1)
270 return poll(const_cast<zmq_pollitem_t *>(items_), nitems_, timeout_);
274 ZMQ_DEPRECATED(
"from 4.3.1, use poll taking non-const items")
276 poll(zmq_pollitem_t
const *items,
size_t nitems, std::chrono::milliseconds
timeout)
278 return poll(const_cast<zmq_pollitem_t *>(items), nitems,
279 static_cast<long>(timeout.count()));
282 ZMQ_DEPRECATED(
"from 4.3.1, use poll taking non-const items")
283 inline int poll(std::vector<zmq_pollitem_t>
const &items,
284 std::chrono::milliseconds
timeout)
286 return poll(const_cast<zmq_pollitem_t *>(items.data()), items.size(),
287 static_cast<long>(timeout.count()));
290 ZMQ_DEPRECATED(
"from 4.3.1, use poll taking non-const items")
291 inline int poll(std::vector<zmq_pollitem_t>
const &items,
long timeout_ = -1)
293 return poll(const_cast<zmq_pollitem_t *>(items.data()), items.size(), timeout_);
297 poll(zmq_pollitem_t *items,
size_t nitems, std::chrono::milliseconds
timeout)
299 return poll(items, nitems, static_cast<long>(timeout.count()));
302 inline int poll(std::vector<zmq_pollitem_t> &items,
303 std::chrono::milliseconds
timeout)
305 return poll(items.data(), items.size(),
static_cast<long>(timeout.count()));
308 inline int poll(std::vector<zmq_pollitem_t> &items,
long timeout_ = -1)
310 return poll(items.data(), items.size(), timeout_);
315 inline void version(
int *major_,
int *minor_,
int *patch_)
317 zmq_version(major_, minor_, patch_);
321 inline std::tuple<int, int, int>
version()
323 std::tuple<int, int, int> v;
324 zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v));
334 int rc = zmq_msg_init(&msg);
340 int rc = zmq_msg_init_size(&msg, size_);
345 template<
class ForwardIter>
message_t(ForwardIter first, ForwardIter last)
347 typedef typename std::iterator_traits<ForwardIter>::value_type value_t;
349 assert(std::distance(first, last) >= 0);
351 static_cast<size_t>(std::distance(first, last)) *
sizeof(value_t);
352 int const rc = zmq_msg_init_size(&msg, size_);
355 std::copy(first, last, data<value_t>());
360 int rc = zmq_msg_init_size(&msg, size_);
363 memcpy(data(), data_, size_);
368 int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
373 #if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL) 374 template<
class Range,
375 typename =
typename std::enable_if<
376 detail::is_range<Range>::value
377 && ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t<Range>)
378 && !std::is_same<Range, message_t>::value>
::type>
380 message_t(detail::ranges::begin(rng), detail::ranges::end(rng))
385 #ifdef ZMQ_HAS_RVALUE_REFS 386 message_t(message_t &&rhs)
ZMQ_NOTHROW : msg(rhs.msg)
388 int rc = zmq_msg_init(&rhs.msg);
401 int rc = zmq_msg_close(&msg);
407 int rc = zmq_msg_close(&msg);
410 rc = zmq_msg_init(&msg);
416 int rc = zmq_msg_close(&msg);
419 rc = zmq_msg_init_size(&msg, size_);
426 int rc = zmq_msg_close(&msg);
429 rc = zmq_msg_init_size(&msg, size_);
432 memcpy(data(), data_, size_);
437 int rc = zmq_msg_close(&msg);
440 rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
445 ZMQ_DEPRECATED(
"from 4.3.1, use move taking non-const reference instead")
446 void move(message_t const *msg_)
448 int rc = zmq_msg_move(&msg, const_cast<zmq_msg_t *>(msg_->handle()));
455 int rc = zmq_msg_move(&msg, msg_.
handle());
460 ZMQ_DEPRECATED(
"from 4.3.1, use copy taking non-const reference instead")
463 int rc = zmq_msg_copy(&msg, const_cast<zmq_msg_t *>(msg_->handle()));
470 int rc = zmq_msg_copy(&msg, msg_.
handle());
477 int rc = zmq_msg_more(const_cast<zmq_msg_t *>(&msg));
485 return zmq_msg_data(const_cast<zmq_msg_t *>(&msg));
490 return zmq_msg_size(const_cast<zmq_msg_t *>(&msg));
499 return static_cast<T
const *
>(data());
502 ZMQ_DEPRECATED(
"from 4.3.0, use operator== instead")
507 const size_t my_size = size();
508 return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size);
513 return !(*
this == other);
516 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0) 517 int get(
int property_)
519 int value = zmq_msg_get(&msg, property_);
526 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) 527 const char *
gets(
const char *property_)
529 const char *value = zmq_msg_gets(&msg, property_);
536 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) 537 uint32_t routing_id()
const 539 return zmq_msg_routing_id(const_cast<zmq_msg_t *>(&msg));
542 void set_routing_id(uint32_t routing_id)
544 int rc = zmq_msg_set_routing_id(&msg, routing_id);
549 const char *group()
const 551 return zmq_msg_group(const_cast<zmq_msg_t *>(&msg));
554 void set_group(
const char *group)
556 int rc = zmq_msg_set_group(&msg, group);
565 return std::string(static_cast<const char *>(data()), size());
569 std::string_view to_string_view()
const noexcept
571 return std::string_view(static_cast<const char *>(data()), size());
584 std::stringstream os;
586 const unsigned char *msg_data = this->data<unsigned char>();
588 size_t size = this->size();
589 int is_ascii[2] = {0, 0};
591 os <<
"zmq::message_t [size " << std::dec << std::setw(3)
592 << std::setfill(
'0') << size <<
"] (";
595 os <<
"... too big to print)";
600 is_ascii[1] = (byte >= 32 && byte < 127);
601 if (is_ascii[1] != is_ascii[0])
607 os << std::hex << std::uppercase << std::setw(2)
608 << std::setfill(
'0') <<
static_cast<short>(byte);
610 is_ascii[0] = is_ascii[1];
647 #ifdef ZMQ_IO_THREADS 648 io_threads = ZMQ_IO_THREADS,
650 #ifdef ZMQ_THREAD_SCHED_POLICY 651 thread_sched_policy = ZMQ_THREAD_SCHED_POLICY,
653 #ifdef ZMQ_THREAD_PRIORITY 654 thread_priority = ZMQ_THREAD_PRIORITY,
656 #ifdef ZMQ_THREAD_AFFINITY_CPU_ADD 657 thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD,
659 #ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE 660 thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE,
662 #ifdef ZMQ_THREAD_NAME_PREFIX 663 thread_name_prefix = ZMQ_THREAD_NAME_PREFIX,
666 max_msgsz = ZMQ_MAX_MSGSZ,
668 #ifdef ZMQ_ZERO_COPY_RECV 669 zero_copy_recv = ZMQ_ZERO_COPY_RECV,
671 #ifdef ZMQ_MAX_SOCKETS 672 max_sockets = ZMQ_MAX_SOCKETS,
674 #ifdef ZMQ_SOCKET_LIMIT 675 socket_limit = ZMQ_SOCKET_LIMIT,
680 #ifdef ZMQ_MSG_T_SIZE 681 msg_t_size = ZMQ_MSG_T_SIZE
697 explicit context_t(
int io_threads_,
int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT)
703 int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_);
706 rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_);
710 #ifdef ZMQ_HAS_RVALUE_REFS 723 int setctxopt(
int option_,
int optval_)
725 int rc = zmq_ctx_set(ptr, option_, optval_);
731 int getctxopt(
int option_) {
return zmq_ctx_get(ptr, option_); }
734 void set(ctxopt option,
int optval)
736 int rc = zmq_ctx_set(ptr, static_cast<int>(option), optval);
743 int rc = zmq_ctx_get(ptr, static_cast<int>(option));
761 rc = zmq_ctx_destroy(ptr);
762 }
while (rc == -1 && errno == EINTR);
775 int rc = zmq_ctx_shutdown(ptr);
804 struct recv_buffer_size
807 size_t untruncated_size;
811 return size != untruncated_size;
815 #if defined(ZMQ_HAS_OPTIONAL) && (ZMQ_HAS_OPTIONAL > 0) 817 using send_result_t = std::optional<size_t>;
818 using recv_result_t = std::optional<size_t>;
819 using recv_buffer_result_t = std::optional<recv_buffer_size>;
827 template<
class T>
class trivial_optional
830 static_assert(std::is_trivial<T>::value,
"T must be trivial");
831 using value_type = T;
833 trivial_optional() =
default;
834 trivial_optional(T value) noexcept : _value(value), _has_value(
true) {}
836 const T *operator->()
const noexcept
841 T *operator->() noexcept
847 const T &operator*()
const noexcept
852 T &operator*() noexcept
861 throw std::exception();
864 const T &value()
const 867 throw std::exception();
871 explicit operator bool()
const noexcept {
return _has_value; }
872 bool has_value()
const noexcept {
return _has_value; }
876 bool _has_value{
false};
880 using send_result_t = detail::trivial_optional<size_t>;
881 using recv_result_t = detail::trivial_optional<size_t>;
882 using recv_buffer_result_t = detail::trivial_optional<recv_buffer_size>;
888 template<
class T> constexpr T enum_bit_or(T a, T b) noexcept
890 static_assert(std::is_enum<T>::value,
"must be enum");
892 return static_cast<T
>(
static_cast<U
>(a) | static_cast<U>(b));
894 template<
class T> constexpr T enum_bit_and(T a, T b) noexcept
896 static_assert(std::is_enum<T>::value,
"must be enum");
898 return static_cast<T
>(
static_cast<U
>(a) & static_cast<U>(b));
900 template<
class T> constexpr T enum_bit_xor(T a, T b) noexcept
902 static_assert(std::is_enum<T>::value,
"must be enum");
904 return static_cast<T
>(
static_cast<U
>(a) ^ static_cast<U>(b));
906 template<
class T> constexpr T enum_bit_not(T a) noexcept
908 static_assert(std::is_enum<T>::value,
"must be enum");
910 return static_cast<T
>(~static_cast<U>(a));
915 enum class send_flags : int
918 dontwait = ZMQ_DONTWAIT,
919 sndmore = ZMQ_SNDMORE
922 constexpr send_flags operator|(send_flags a, send_flags b) noexcept
924 return detail::enum_bit_or(a, b);
926 constexpr send_flags operator&(send_flags a, send_flags b) noexcept
928 return detail::enum_bit_and(a, b);
930 constexpr send_flags operator^(send_flags a, send_flags b) noexcept
932 return detail::enum_bit_xor(a, b);
934 constexpr send_flags operator~(send_flags a) noexcept
936 return detail::enum_bit_not(a);
940 enum class recv_flags : int
943 dontwait = ZMQ_DONTWAIT
946 constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept
948 return detail::enum_bit_or(a, b);
950 constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept
952 return detail::enum_bit_and(a, b);
954 constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept
956 return detail::enum_bit_xor(a, b);
958 constexpr recv_flags operator~(recv_flags a) noexcept
960 return detail::enum_bit_not(a);
971 constexpr mutable_buffer() noexcept : _data(
nullptr), _size(0) {}
972 constexpr mutable_buffer(
void *p,
size_t n) noexcept : _data(p), _size(n)
975 assert(p !=
nullptr || n == 0);
979 constexpr
void *data()
const noexcept {
return _data; }
980 constexpr
size_t size()
const noexcept {
return _size; }
981 mutable_buffer &operator+=(
size_t n) noexcept
984 const auto shift = (std::min)(n, _size);
985 _data =
static_cast<char *
>(_data) + shift;
995 inline mutable_buffer operator+(
const mutable_buffer &mb,
size_t n) noexcept
997 return mutable_buffer(static_cast<char *>(mb.data()) + (std::min)(n, mb.size()),
998 mb.size() - (std::min)(n, mb.size()));
1000 inline mutable_buffer operator+(
size_t n,
const mutable_buffer &mb) noexcept
1008 constexpr const_buffer() noexcept : _data(
nullptr), _size(0) {}
1009 constexpr const_buffer(
const void *p,
size_t n) noexcept : _data(p), _size(n)
1012 assert(p !=
nullptr || n == 0);
1015 constexpr const_buffer(
const mutable_buffer &mb) noexcept :
1016 _data(mb.data()), _size(mb.size())
1020 constexpr
const void *data()
const noexcept {
return _data; }
1021 constexpr
size_t size()
const noexcept {
return _size; }
1022 const_buffer &operator+=(
size_t n) noexcept
1024 const auto shift = (std::min)(n, _size);
1025 _data =
static_cast<const char *
>(_data) + shift;
1035 inline const_buffer operator+(
const const_buffer &cb,
size_t n) noexcept
1037 return const_buffer(static_cast<const char *>(cb.data())
1038 + (std::min)(n, cb.size()),
1039 cb.size() - (std::min)(n, cb.size()));
1041 inline const_buffer operator+(
size_t n,
const const_buffer &cb) noexcept
1048 constexpr mutable_buffer buffer(
void *p,
size_t n) noexcept
1050 return mutable_buffer(p, n);
1052 constexpr const_buffer buffer(
const void *p,
size_t n) noexcept
1054 return const_buffer(p, n);
1056 constexpr mutable_buffer buffer(
const mutable_buffer &mb) noexcept
1060 inline mutable_buffer buffer(
const mutable_buffer &mb,
size_t n) noexcept
1062 return mutable_buffer(mb.data(), (std::min)(mb.size(), n));
1064 constexpr const_buffer buffer(
const const_buffer &cb) noexcept
1068 inline const_buffer buffer(
const const_buffer &cb,
size_t n) noexcept
1070 return const_buffer(cb.data(), (std::min)(cb.size(), n));
1075 template<
class T>
struct is_buffer
1077 static constexpr
bool value =
1078 std::is_same<T, const_buffer>::value || std::is_same<T, mutable_buffer>::value;
1081 template<
class T>
struct is_pod_like
1087 static constexpr
bool value =
1088 ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout<T>::value;
1091 template<
class C> constexpr
auto seq_size(
const C &c) noexcept -> decltype(c.size())
1095 template<
class T,
size_t N>
1096 constexpr
size_t seq_size(
const T (&)[N]) noexcept
1102 auto buffer_contiguous_sequence(Seq &&seq) noexcept
1103 -> decltype(buffer(std::addressof(*std::begin(seq)),
size_t{}))
1105 using T =
typename std::remove_cv<
1107 static_assert(detail::is_pod_like<T>::value,
"T must be POD");
1109 const auto size = seq_size(seq);
1110 return buffer(size != 0u ? std::addressof(*std::begin(seq)) :
nullptr,
1114 auto buffer_contiguous_sequence(Seq &&seq,
size_t n_bytes) noexcept
1115 -> decltype(buffer_contiguous_sequence(seq))
1117 using T =
typename std::remove_cv<
1119 static_assert(detail::is_pod_like<T>::value,
"T must be POD");
1121 const auto size = seq_size(seq);
1122 return buffer(size != 0u ? std::addressof(*std::begin(seq)) :
nullptr,
1123 (std::min)(size *
sizeof(T), n_bytes));
1129 template<
class T,
size_t N> mutable_buffer buffer(T (&data)[N]) noexcept
1131 return detail::buffer_contiguous_sequence(data);
1133 template<
class T,
size_t N>
1134 mutable_buffer buffer(T (&data)[N],
size_t n_bytes) noexcept
1136 return detail::buffer_contiguous_sequence(data, n_bytes);
1138 template<
class T,
size_t N> const_buffer buffer(
const T (&data)[N]) noexcept
1140 return detail::buffer_contiguous_sequence(data);
1142 template<
class T,
size_t N>
1143 const_buffer buffer(
const T (&data)[N],
size_t n_bytes) noexcept
1145 return detail::buffer_contiguous_sequence(data, n_bytes);
1148 template<
class T,
size_t N> mutable_buffer buffer(std::array<T, N> &data) noexcept
1150 return detail::buffer_contiguous_sequence(data);
1152 template<
class T,
size_t N>
1153 mutable_buffer buffer(std::array<T, N> &data,
size_t n_bytes) noexcept
1155 return detail::buffer_contiguous_sequence(data, n_bytes);
1157 template<
class T,
size_t N>
1158 const_buffer buffer(std::array<const T, N> &data) noexcept
1160 return detail::buffer_contiguous_sequence(data);
1162 template<
class T,
size_t N>
1163 const_buffer buffer(std::array<const T, N> &data,
size_t n_bytes) noexcept
1165 return detail::buffer_contiguous_sequence(data, n_bytes);
1167 template<
class T,
size_t N>
1168 const_buffer buffer(
const std::array<T, N> &data) noexcept
1170 return detail::buffer_contiguous_sequence(data);
1172 template<
class T,
size_t N>
1173 const_buffer buffer(
const std::array<T, N> &data,
size_t n_bytes) noexcept
1175 return detail::buffer_contiguous_sequence(data, n_bytes);
1178 template<
class T,
class Allocator>
1179 mutable_buffer buffer(std::vector<T, Allocator> &data) noexcept
1181 return detail::buffer_contiguous_sequence(data);
1183 template<
class T,
class Allocator>
1184 mutable_buffer buffer(std::vector<T, Allocator> &data,
size_t n_bytes) noexcept
1186 return detail::buffer_contiguous_sequence(data, n_bytes);
1188 template<
class T,
class Allocator>
1189 const_buffer buffer(
const std::vector<T, Allocator> &data) noexcept
1191 return detail::buffer_contiguous_sequence(data);
1193 template<
class T,
class Allocator>
1194 const_buffer buffer(
const std::vector<T, Allocator> &data,
size_t n_bytes) noexcept
1196 return detail::buffer_contiguous_sequence(data, n_bytes);
1199 template<
class T,
class Traits,
class Allocator>
1200 mutable_buffer buffer(std::basic_string<T, Traits, Allocator> &data) noexcept
1202 return detail::buffer_contiguous_sequence(data);
1204 template<
class T,
class Traits,
class Allocator>
1205 mutable_buffer buffer(std::basic_string<T, Traits, Allocator> &data,
1206 size_t n_bytes) noexcept
1208 return detail::buffer_contiguous_sequence(data, n_bytes);
1210 template<
class T,
class Traits,
class Allocator>
1211 const_buffer buffer(
const std::basic_string<T, Traits, Allocator> &data) noexcept
1213 return detail::buffer_contiguous_sequence(data);
1215 template<
class T,
class Traits,
class Allocator>
1216 const_buffer buffer(
const std::basic_string<T, Traits, Allocator> &data,
1217 size_t n_bytes) noexcept
1219 return detail::buffer_contiguous_sequence(data, n_bytes);
1222 #if defined(ZMQ_HAS_STRING_VIEW) && (ZMQ_HAS_STRING_VIEW > 0) 1224 template<
class T,
class Traits>
1225 const_buffer buffer(std::basic_string_view<T, Traits> data) noexcept
1227 return detail::buffer_contiguous_sequence(data);
1229 template<
class T,
class Traits>
1230 const_buffer buffer(std::basic_string_view<T, Traits> data,
size_t n_bytes) noexcept
1232 return detail::buffer_contiguous_sequence(data, n_bytes);
1239 template<
class Char,
size_t N>
1240 constexpr const_buffer str_buffer(
const Char (&data)[N]) noexcept
1242 static_assert(detail::is_pod_like<Char>::value,
"Char must be POD");
1244 assert(data[N - 1] == Char{0});
1246 return const_buffer(static_cast<const Char *>(data), (N - 1) *
sizeof(Char));
1251 constexpr const_buffer
operator"" _zbuf(
const char *str,
size_t len) noexcept
1253 return const_buffer(str, len *
sizeof(
char));
1255 constexpr const_buffer
operator"" _zbuf(
const wchar_t *str,
size_t len) noexcept
1257 return const_buffer(str, len *
sizeof(
wchar_t));
1259 constexpr const_buffer
operator"" _zbuf(
const char16_t *str,
size_t len) noexcept
1261 return const_buffer(str, len *
sizeof(char16_t));
1263 constexpr const_buffer
operator"" _zbuf(
const char32_t *str,
size_t len) noexcept
1265 return const_buffer(str, len *
sizeof(char32_t));
1279 template<
typename T>
void setsockopt(
int option_, T
const &optval)
1281 setsockopt(option_, &optval,
sizeof(T));
1284 void setsockopt(
int option_,
const void *optval_,
size_t optvallen_)
1286 int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_);
1291 void getsockopt(
int option_,
void *optval_,
size_t *optvallen_)
const 1293 int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_);
1301 size_t optlen =
sizeof(T);
1302 getsockopt(option_, &optval, &optlen);
1310 int rc = zmq_bind(_handle, addr_);
1319 int rc = zmq_unbind(_handle, addr_);
1328 int rc = zmq_connect(_handle, addr_);
1337 int rc = zmq_disconnect(_handle, addr_);
1345 size_t send(const
void *buf_,
size_t len_,
int flags_ = 0)
1347 int nbytes = zmq_send(_handle, buf_, len_, flags_);
1349 return static_cast<size_t>(nbytes);
1350 if (zmq_errno() == EAGAIN)
1359 int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_);
1362 if (zmq_errno() == EAGAIN)
1367 template<
typename T>
1369 "from 4.4.1, use send taking message_t or buffer (for contiguous " 1370 "ranges), and send_flags")
1371 bool send(T first, T last,
int flags_ = 0)
1374 int nbytes = zmq_msg_send(msg.
handle(), _handle, flags_);
1377 if (zmq_errno() == EAGAIN)
1382 #ifdef ZMQ_HAS_RVALUE_REFS 1388 return send(msg_, static_cast<send_flags>(flags_)).has_value();
1390 return send(msg_, flags_);
1396 send_result_t send(const_buffer buf, send_flags flags = send_flags::none)
1399 zmq_send(_handle, buf.data(), buf.size(),
static_cast<int>(flags));
1401 return static_cast<size_t>(nbytes);
1402 if (zmq_errno() == EAGAIN)
1407 send_result_t send(
message_t &msg, send_flags flags)
1409 int nbytes = zmq_msg_send(msg.
handle(), _handle,
static_cast<int>(flags));
1411 return static_cast<size_t>(nbytes);
1412 if (zmq_errno() == EAGAIN)
1417 send_result_t send(
message_t &&msg, send_flags flags)
1419 return send(msg, flags);
1424 "from 4.3.1, use recv taking a mutable_buffer and recv_flags")
1425 size_t recv(
void *buf_,
size_t len_,
int flags_ = 0)
1427 int nbytes = zmq_recv(_handle, buf_, len_, flags_);
1429 return static_cast<size_t>(nbytes);
1430 if (zmq_errno() == EAGAIN)
1436 "from 4.3.1, use recv taking a reference to message_t and recv_flags")
1437 bool recv(
message_t *msg_,
int flags_ = 0)
1439 int nbytes = zmq_msg_recv(msg_->
handle(), _handle, flags_);
1442 if (zmq_errno() == EAGAIN)
1449 recv_buffer_result_t recv(mutable_buffer buf,
1450 recv_flags flags = recv_flags::none)
1453 zmq_recv(_handle, buf.data(), buf.size(),
static_cast<int>(flags));
1455 return recv_buffer_size{
1456 (std::min)(static_cast<size_t>(nbytes), buf.size()),
1457 static_cast<size_t>(nbytes)};
1459 if (zmq_errno() == EAGAIN)
1465 recv_result_t recv(
message_t &msg, recv_flags flags = recv_flags::none)
1468 zmq_msg_recv(msg.
handle(), _handle,
static_cast<int>(flags));
1470 assert(msg.
size() ==
static_cast<size_t>(nbytes));
1471 return static_cast<size_t>(nbytes);
1473 if (zmq_errno() == EAGAIN)
1479 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) 1480 void join(
const char *group)
1482 int rc = zmq_join(_handle, group);
1487 void leave(
const char *group)
1489 int rc = zmq_leave(_handle, group);
1509 enum class socket_type : int
1513 dealer = ZMQ_DEALER,
1514 router = ZMQ_ROUTER,
1521 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) 1527 #if ZMQ_VERSION_MAJOR >= 4 1528 stream = ZMQ_STREAM,
1563 return sr.handle() ==
nullptr;
1567 return sr.handle() ==
nullptr;
1571 return !(sr ==
nullptr);
1575 return !(sr ==
nullptr);
1581 return std::equal_to<void *>()(a.handle(), b.handle());
1589 return std::less<void *>()(a.handle(), b.handle());
1613 return hash<void *>()(sr.handle());
1629 detail::socket_base(zmq_socket(static_cast<void *>(context_), type_)),
1630 ctxptr(static_cast<void *>(context_))
1638 socket_t(context_, static_cast<int>(type_))
1643 #ifdef ZMQ_HAS_RVALUE_REFS 1669 int rc = zmq_close(_handle);
1689 socket_t(
void *context_,
int type_) :
1702 ZMQ_DEPRECATED(
"from 4.3.1, use proxy taking socket_t objects")
1703 inline
void proxy(
void *frontend,
void *backend,
void *capture)
1705 int rc = zmq_proxy(frontend, backend, capture);
1713 int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle());
1718 #ifdef ZMQ_HAS_PROXY_STEERABLE 1719 ZMQ_DEPRECATED(
"from 4.3.1, use proxy_steerable taking socket_t objects")
1723 int rc = zmq_proxy_steerable(frontend, backend, capture, control);
1733 int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(),
1734 capture.handle(), control.handle());
1747 #ifdef ZMQ_HAS_RVALUE_REFS 1751 std::swap(_monitor_socket, rhs._monitor_socket);
1759 std::swap(_monitor_socket, rhs._monitor_socket);
1768 monitor(socket, addr.c_str(), events);
1773 init(socket, addr_, events);
1781 init(socket, addr.c_str(), events);
1786 int rc = zmq_socket_monitor(socket.handle(), addr_, events);
1791 _monitor_socket =
socket_t(socket.ctxptr, ZMQ_PAIR);
1792 _monitor_socket.connect(addr_);
1794 on_monitor_started();
1799 assert(_monitor_socket);
1802 zmq_msg_init(&eventMsg);
1805 {_monitor_socket.handle(), 0, ZMQ_POLLIN, 0},
1810 if (items[0].revents & ZMQ_POLLIN) {
1811 int rc = zmq_msg_recv(&eventMsg, _monitor_socket.handle(), 0);
1812 if (rc == -1 && zmq_errno() == ETERM)
1817 zmq_msg_close(&eventMsg);
1821 #if ZMQ_VERSION_MAJOR >= 4 1822 const char *data =
static_cast<const char *
>(zmq_msg_data(&eventMsg));
1824 memcpy(&msgEvent.
event, data,
sizeof(uint16_t));
1825 data +=
sizeof(uint16_t);
1826 memcpy(&msgEvent.
value, data,
sizeof(int32_t));
1832 #ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT 1834 zmq_msg_init(&addrMsg);
1835 int rc = zmq_msg_recv(&addrMsg, _monitor_socket.handle(), 0);
1836 if (rc == -1 && zmq_errno() == ETERM) {
1837 zmq_msg_close(&eventMsg);
1842 const char *str =
static_cast<const char *
>(zmq_msg_data(&addrMsg));
1843 std::string address(str, str + zmq_msg_size(&addrMsg));
1844 zmq_msg_close(&addrMsg);
1847 std::string address =
event->data.connected.addr;
1850 #ifdef ZMQ_EVENT_MONITOR_STOPPED 1851 if (event->event == ZMQ_EVENT_MONITOR_STOPPED) {
1852 zmq_msg_close(&eventMsg);
1858 switch (event->event) {
1859 case ZMQ_EVENT_CONNECTED:
1860 on_event_connected(*event, address.c_str());
1862 case ZMQ_EVENT_CONNECT_DELAYED:
1863 on_event_connect_delayed(*event, address.c_str());
1865 case ZMQ_EVENT_CONNECT_RETRIED:
1866 on_event_connect_retried(*event, address.c_str());
1868 case ZMQ_EVENT_LISTENING:
1869 on_event_listening(*event, address.c_str());
1871 case ZMQ_EVENT_BIND_FAILED:
1872 on_event_bind_failed(*event, address.c_str());
1874 case ZMQ_EVENT_ACCEPTED:
1875 on_event_accepted(*event, address.c_str());
1877 case ZMQ_EVENT_ACCEPT_FAILED:
1878 on_event_accept_failed(*event, address.c_str());
1880 case ZMQ_EVENT_CLOSED:
1881 on_event_closed(*event, address.c_str());
1883 case ZMQ_EVENT_CLOSE_FAILED:
1884 on_event_close_failed(*event, address.c_str());
1886 case ZMQ_EVENT_DISCONNECTED:
1887 on_event_disconnected(*event, address.c_str());
1889 #ifdef ZMQ_BUILD_DRAFT_API 1890 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) 1891 case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL:
1892 on_event_handshake_failed_no_detail(*event, address.c_str());
1894 case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL:
1895 on_event_handshake_failed_protocol(*event, address.c_str());
1897 case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH:
1898 on_event_handshake_failed_auth(*event, address.c_str());
1900 case ZMQ_EVENT_HANDSHAKE_SUCCEEDED:
1901 on_event_handshake_succeeded(*event, address.c_str());
1903 #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) 1904 case ZMQ_EVENT_HANDSHAKE_FAILED:
1905 on_event_handshake_failed(*event, address.c_str());
1907 case ZMQ_EVENT_HANDSHAKE_SUCCEED:
1908 on_event_handshake_succeed(*event, address.c_str());
1913 on_event_unknown(*event, address.c_str());
1916 zmq_msg_close(&eventMsg);
1921 #ifdef ZMQ_EVENT_MONITOR_STOPPED 1925 zmq_socket_monitor(_socket.handle(),
ZMQ_NULLPTR, 0);
1983 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) 2008 #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) 2009 virtual void on_event_handshake_failed(
const zmq_event_t &event_,
2015 virtual void on_event_handshake_succeed(
const zmq_event_t &event_,
2038 zmq_socket_monitor(_socket.handle(),
ZMQ_NULLPTR, 0);
2039 _monitor_socket.
close();
2043 #if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) 2046 enum class event_flags : short
2049 pollin = ZMQ_POLLIN,
2050 pollout = ZMQ_POLLOUT,
2051 pollerr = ZMQ_POLLERR,
2052 pollpri = ZMQ_POLLPRI
2055 constexpr event_flags operator|(event_flags a, event_flags b) noexcept
2057 return detail::enum_bit_or(a, b);
2059 constexpr event_flags operator&(event_flags a, event_flags b) noexcept
2061 return detail::enum_bit_and(a, b);
2063 constexpr event_flags operator^(event_flags a, event_flags b) noexcept
2065 return detail::enum_bit_xor(a, b);
2067 constexpr event_flags operator~(event_flags a) noexcept
2069 return detail::enum_bit_not(a);
2072 struct no_user_data;
2075 template<
class T = no_user_data>
struct poller_event
2087 template<
typename T = no_user_data>
class poller_t
2090 using event_type = poller_event<T>;
2092 poller_t() : poller_ptr(zmq_poller_new())
2099 typename Dummy = void,
2101 typename std::enable_if<!std::is_same<T, no_user_data>::value, Dummy>
::type>
2104 add_impl(socket, events, user_data);
2109 add_impl(socket, events,
nullptr);
2114 if (0 != zmq_poller_remove(poller_ptr.get(), socket.handle())) {
2122 != zmq_poller_modify(poller_ptr.get(), socket.handle(),
2123 static_cast<short>(events))) {
2128 size_t wait_all(std::vector<event_type> &poller_events,
2129 const std::chrono::milliseconds
timeout)
2131 int rc = zmq_poller_wait_all(
2133 reinterpret_cast<zmq_poller_event_t *
>(poller_events.data()),
2134 static_cast<int>(poller_events.size()),
2135 static_cast<long>(timeout.count()));
2137 return static_cast<size_t>(rc);
2139 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) 2140 if (zmq_errno() == EAGAIN)
2142 if (zmq_errno() == ETIMEDOUT)
2150 struct destroy_poller_t
2152 void operator()(
void *ptr) noexcept
2154 int rc = zmq_poller_destroy(&ptr);
2159 std::unique_ptr<void, destroy_poller_t> poller_ptr;
2161 void add_impl(
zmq::socket_ref socket, event_flags events, T *user_data)
2164 != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data,
2165 static_cast<short>(events))) {
2170 #endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) 2174 return os << msg.
str();
2179 #endif // __ZMQ_HPP_INCLUDED__ void monitor(socket_t &socket, const char *addr_, int events=ZMQ_EVENT_ALL)
void swap(context_t &other) ZMQ_NOTHROW
void setsockopt(int option_, const void *optval_, size_t optvallen_)
context_t(int io_threads_, int max_sockets_=ZMQ_MAX_SOCKETS_DFLT)
bool operator>=(socket_ref a, socket_ref b) ZMQ_NOTHROW
ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private) ZMQ_NOTHROW
virtual const char * what() const ZMQ_NOTHROW ZMQ_OVERRIDE
ZMQ_NODISCARD const zmq_msg_t * handle() const ZMQ_NOTHROW
#define ZMQ_DELETED_FUNCTION
bool operator<=(socket_ref a, socket_ref b) ZMQ_NOTHROW
void monitor(socket_t &socket, std::string const &addr, int events=ZMQ_EVENT_ALL)
virtual void on_event_handshake_failed_protocol(const zmq_event_t &event_, const char *addr_)
const char * addr
inproc hangs. no messages ever get received by server. tcp/ipc okay.
zmq_pollitem_t pollitem_t
virtual void on_event_connect_delayed(const zmq_event_t &event_, const char *addr_)
void setsockopt(int option_, T const &optval)
bool connected() const ZMQ_NOTHROW
const char * gets(const char *property_)
void swap(socket_t &other) ZMQ_NOTHROW
void bind(const char *addr_)
virtual void on_event_closed(const zmq_event_t &event_, const char *addr_)
virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_)
virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_)
void rebuild(const void *data_, size_t size_)
message_t(const void *data_, size_t size_)
ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW
void unbind(std::string const &addr)
void disconnect(const char *addr_)
#define ZMQ_CONSTEXPR_VAR
std::string to_string() const
bool operator<(socket_ref a, socket_ref b) ZMQ_NOTHROW
virtual void on_event_handshake_succeeded(const zmq_event_t &event_, const char *addr_)
ZMQ_NODISCARD zmq_msg_t * handle() ZMQ_NOTHROW
T const * data() const ZMQ_NOTHROW
ZMQ_EXPLICIT socket_base(void *handle) ZMQ_NOTHROW
void proxy_steerable(void *frontend, void *backend, void *capture, void *control)
void * data() ZMQ_NOTHROW
int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_=-1)
void proxy(void *frontend, void *backend, void *capture)
virtual void on_event_handshake_failed_auth(const zmq_event_t &event_, const char *addr_)
void move(message_t &msg_)
const void * data() const ZMQ_NOTHROW
void copy(message_t &msg_)
void init(socket_t &socket, const char *addr_, int events=ZMQ_EVENT_ALL)
bool check_event(int timeout=0)
message_t(ForwardIter first, ForwardIter last)
virtual void on_event_close_failed(const zmq_event_t &event_, const char *addr_)
bool operator!=(socket_ref a, socket_ref b) ZMQ_NOTHROW
virtual void on_event_handshake_failed_no_detail(const zmq_event_t &event_, const char *addr_)
std::ostream & operator<<(std::ostream &os, const message_t &msg)
#define ZMQ_ASSERT(expression)
message_t(void *data_, size_t size_, free_fn *ffn_, void *hint_=ZMQ_NULLPTR)
socket_base() ZMQ_NOTHROW
T getsockopt(int option_) const
void getsockopt(int option_, void *optval_, size_t *optvallen_) const
virtual void on_event_unknown(const zmq_event_t &event_, const char *addr_)
socket_t(context_t &context_, int type_)
void rebuild(size_t size_)
bool operator>(socket_ref a, socket_ref b) ZMQ_NOTHROW
bool operator==(const message_t &other) const ZMQ_NOTHROW
virtual void on_event_listening(const zmq_event_t &event_, const char *addr_)
void client(std::string str)
void version(int *major_, int *minor_, int *patch_)
virtual void on_event_connected(const zmq_event_t &event_, const char *addr_)
void connect(std::string const &addr)
socket_ref(from_handle_t, void *handle) ZMQ_NOTHROW
bool operator!=(const message_t &other) const ZMQ_NOTHROW
void connect(const char *addr_)
void swap(message_t &a, message_t &b) ZMQ_NOTHROW
void shutdown() ZMQ_NOTHROW
size_t size() const ZMQ_NOTHROW
void bind(std::string const &addr)
void rebuild(void *data_, size_t size_, free_fn *ffn_, void *hint_=ZMQ_NULLPTR)
virtual void on_monitor_started()
virtual void on_event_bind_failed(const zmq_event_t &event_, const char *addr_)
void init(socket_t &socket, std::string const &addr, int events=ZMQ_EVENT_ALL)
virtual void on_event_accept_failed(const zmq_event_t &event_, const char *addr_)
void disconnect(std::string const &addr)
bool operator==(socket_ref a, socket_ref b) ZMQ_NOTHROW
void swap(socket_t &a, socket_t &b) ZMQ_NOTHROW
void swap(message_t &other) ZMQ_NOTHROW
#define ZMQ_CPP11_DEPRECATED(msg)
void unbind(const char *addr_)
virtual void on_event_connect_retried(const zmq_event_t &event_, const char *addr_)
ZMQ_CONSTEXPR_VAR from_handle_t from_handle
bool more() const ZMQ_NOTHROW