zmq.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2016-2017 ZeroMQ community
3  Copyright (c) 2009-2011 250bpm s.r.o.
4  Copyright (c) 2011 Botond Ballo
5  Copyright (c) 2007-2009 iMatix Corporation
6 
7  Permission is hereby granted, free of charge, to any person obtaining a copy
8  of this software and associated documentation files (the "Software"), to
9  deal in the Software without restriction, including without limitation the
10  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11  sell copies of the Software, and to permit persons to whom the Software is
12  furnished to do so, subject to the following conditions:
13 
14  The above copyright notice and this permission notice shall be included in
15  all copies or substantial portions of the Software.
16 
17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23  IN THE SOFTWARE.
24 */
25 
26 #ifndef __ZMQ_HPP_INCLUDED__
27 #define __ZMQ_HPP_INCLUDED__
28 
29 #ifdef _WIN32
30 #ifndef NOMINMAX
31 #define NOMINMAX
32 #endif
33 #endif
34 
35 // included here for _HAS_CXX* macros
36 #include <zmq.h>
37 
38 #if defined(_MSVC_LANG)
39 #define CPPZMQ_LANG _MSVC_LANG
40 #else
41 #define CPPZMQ_LANG __cplusplus
42 #endif
43 // overwrite if specific language macros indicate higher version
44 #if defined(_HAS_CXX14) && _HAS_CXX14 && CPPZMQ_LANG < 201402L
45 #undef CPPZMQ_LANG
46 #define CPPZMQ_LANG 201402L
47 #endif
48 #if defined(_HAS_CXX17) && _HAS_CXX17 && CPPZMQ_LANG < 201703L
49 #undef CPPZMQ_LANG
50 #define CPPZMQ_LANG 201703L
51 #endif
52 
53 // macros defined if has a specific standard or greater
54 #if CPPZMQ_LANG >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
55 #define ZMQ_CPP11
56 #endif
57 #if CPPZMQ_LANG >= 201402L
58 #define ZMQ_CPP14
59 #endif
60 #if CPPZMQ_LANG >= 201703L
61 #define ZMQ_CPP17
62 #endif
63 
64 #if defined(ZMQ_CPP14) && !defined(_MSC_VER)
65 #define ZMQ_DEPRECATED(msg) [[deprecated(msg)]]
66 #elif defined(_MSC_VER)
67 #define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg))
68 #elif defined(__GNUC__)
69 #define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg)))
70 #endif
71 
72 #if defined(ZMQ_CPP17)
73 #define ZMQ_NODISCARD [[nodiscard]]
74 #else
75 #define ZMQ_NODISCARD
76 #endif
77 
78 #if defined(ZMQ_CPP11)
79 #define ZMQ_NOTHROW noexcept
80 #define ZMQ_EXPLICIT explicit
81 #define ZMQ_OVERRIDE override
82 #define ZMQ_NULLPTR nullptr
83 #define ZMQ_CONSTEXPR_FN constexpr
84 #define ZMQ_CONSTEXPR_VAR constexpr
85 #define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg)
86 #else
87 #define ZMQ_NOTHROW throw()
88 #define ZMQ_EXPLICIT
89 #define ZMQ_OVERRIDE
90 #define ZMQ_NULLPTR 0
91 #define ZMQ_CONSTEXPR_FN
92 #define ZMQ_CONSTEXPR_VAR const
93 #define ZMQ_CPP11_DEPRECATED(msg)
94 #endif
95 #if defined(ZMQ_CPP14) && (!defined(_MSC_VER) || _MSC_VER > 1900)
96 #define ZMQ_EXTENDED_CONSTEXPR
97 #endif
98 #if defined(ZMQ_CPP17)
99 #define ZMQ_INLINE_VAR inline
100 #else
101 #define ZMQ_INLINE_VAR
102 #endif
103 
104 #include <cassert>
105 #include <cstring>
106 
107 #include <algorithm>
108 #include <exception>
109 #include <iomanip>
110 #include <sstream>
111 #include <string>
112 #include <vector>
113 #ifdef ZMQ_CPP11
114 #include <array>
115 #include <chrono>
116 #include <tuple>
117 #include <memory>
118 #endif
119 
120 #if defined(__has_include) && defined(ZMQ_CPP17)
121 #define CPPZMQ_HAS_INCLUDE_CPP17(X) __has_include(X)
122 #else
123 #define CPPZMQ_HAS_INCLUDE_CPP17(X) 0
124 #endif
125 
126 #if CPPZMQ_HAS_INCLUDE_CPP17(<optional>) && !defined(CPPZMQ_HAS_OPTIONAL)
127 #define CPPZMQ_HAS_OPTIONAL 1
128 #endif
129 #ifndef CPPZMQ_HAS_OPTIONAL
130 #define CPPZMQ_HAS_OPTIONAL 0
131 #elif CPPZMQ_HAS_OPTIONAL
132 #include <optional>
133 #endif
134 
135 #if CPPZMQ_HAS_INCLUDE_CPP17(<string_view>) && !defined(CPPZMQ_HAS_STRING_VIEW)
136 #define CPPZMQ_HAS_STRING_VIEW 1
137 #endif
138 #ifndef CPPZMQ_HAS_STRING_VIEW
139 #define CPPZMQ_HAS_STRING_VIEW 0
140 #elif CPPZMQ_HAS_STRING_VIEW
141 #include <string_view>
142 #endif
143 
144 /* Version macros for compile-time API version detection */
145 #define CPPZMQ_VERSION_MAJOR 4
146 #define CPPZMQ_VERSION_MINOR 8
147 #define CPPZMQ_VERSION_PATCH 0
148 
149 #define CPPZMQ_VERSION \
150  ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, CPPZMQ_VERSION_PATCH)
151 
152 // Detect whether the compiler supports C++11 rvalue references.
153 #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \
154  defined(__GXX_EXPERIMENTAL_CXX0X__))
155 #define ZMQ_HAS_RVALUE_REFS
156 #define ZMQ_DELETED_FUNCTION = delete
157 #elif defined(__clang__)
158 #if __has_feature(cxx_rvalue_references)
159 #define ZMQ_HAS_RVALUE_REFS
160 #endif
161 
162 #if __has_feature(cxx_deleted_functions)
163 #define ZMQ_DELETED_FUNCTION = delete
164 #else
165 #define ZMQ_DELETED_FUNCTION
166 #endif
167 #elif defined(_MSC_VER) && (_MSC_VER >= 1900)
168 #define ZMQ_HAS_RVALUE_REFS
169 #define ZMQ_DELETED_FUNCTION = delete
170 #elif defined(_MSC_VER) && (_MSC_VER >= 1600)
171 #define ZMQ_HAS_RVALUE_REFS
172 #define ZMQ_DELETED_FUNCTION
173 #else
174 #define ZMQ_DELETED_FUNCTION
175 #endif
176 
177 #if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) && \
178  defined(__GNUC__) && __GNUC__ < 5
179 #define ZMQ_CPP11_PARTIAL
180 #elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805
181 // the date here is the last date of gcc 4.9.4, which
182 // effectively means libstdc++ from gcc 5.5 and higher won't trigger this branch
183 #define ZMQ_CPP11_PARTIAL
184 #endif
185 
186 #ifdef ZMQ_CPP11
187 #ifdef ZMQ_CPP11_PARTIAL
188 #define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
189 #else
190 #include <type_traits>
191 #define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value
192 #endif
193 #endif
194 
195 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0)
196 #define ZMQ_NEW_MONITOR_EVENT_LAYOUT
197 #endif
198 
199 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0)
200 #define ZMQ_HAS_PROXY_STEERABLE
201 /* Socket event data */
202 typedef struct
203 {
204  uint16_t event; // id of the event as bitfield
205  int32_t value; // value is either error code, fd or reconnect interval
206 } zmq_event_t;
207 #endif
208 
209 // Avoid using deprecated message receive function when possible
210 #if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0)
211 #define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags)
212 #endif
213 
214 // In order to prevent unused variable warnings when building in non-debug
215 // mode use this macro to make assertions.
216 #ifndef NDEBUG
217 #define ZMQ_ASSERT(expression) assert(expression)
218 #else
219 #define ZMQ_ASSERT(expression) (void)(expression)
220 #endif
221 
222 namespace zmq
223 {
224 #ifdef ZMQ_CPP11
225 namespace detail
226 {
227 namespace ranges
228 {
229 using std::begin;
230 using std::end;
231 template <class T>
232 auto begin(T&& r) -> decltype(begin(std::forward<T>(r)))
233 {
234  return begin(std::forward<T>(r));
235 }
236 template <class T>
237 auto end(T&& r) -> decltype(end(std::forward<T>(r)))
238 {
239  return end(std::forward<T>(r));
240 }
241 } // namespace ranges
242 
243 template <class T>
244 using void_t = void;
245 
246 template <class Iter>
247 using iter_value_t = typename std::iterator_traits<Iter>::value_type;
248 
249 template <class Range>
250 using range_iter_t =
251  decltype(ranges::begin(std::declval<typename std::remove_reference<Range>::type&>()));
252 
253 template <class Range>
254 using range_value_t = iter_value_t<range_iter_t<Range>>;
255 
256 template <class T, class = void>
257 struct is_range : std::false_type
258 {
259 };
260 
261 template <class T>
262 struct is_range<
263  T, void_t<decltype(ranges::begin(
264  std::declval<typename std::remove_reference<T>::type&>()) ==
265  ranges::end(
266  std::declval<typename std::remove_reference<T>::type&>()))>>
268 {
269 };
270 
271 } // namespace detail
272 #endif
273 
274 typedef zmq_free_fn free_fn;
275 typedef zmq_pollitem_t pollitem_t;
276 
277 class error_t : public std::exception
278 {
279 public:
280  error_t() ZMQ_NOTHROW : errnum(zmq_errno())
281  {
282  }
283  explicit error_t(int err) ZMQ_NOTHROW : errnum(err)
284  {
285  }
286  virtual const char* what() const ZMQ_NOTHROW ZMQ_OVERRIDE
287  {
288  return zmq_strerror(errnum);
289  }
290  int num() const ZMQ_NOTHROW
291  {
292  return errnum;
293  }
294 
295 private:
296  int errnum;
297 };
298 
299 inline int poll(zmq_pollitem_t* items_, size_t nitems_, long timeout_ = -1)
300 {
301  int rc = zmq_poll(items_, static_cast<int>(nitems_), timeout_);
302  if (rc < 0)
303  throw error_t();
304  return rc;
305 }
306 
307 ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
308 inline int poll(zmq_pollitem_t const* items_, size_t nitems_, long timeout_ = -1)
309 {
310  return poll(const_cast<zmq_pollitem_t*>(items_), nitems_, timeout_);
311 }
312 
313 #ifdef ZMQ_CPP11
314 ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
315 inline int poll(zmq_pollitem_t const* items, size_t nitems,
316  std::chrono::milliseconds timeout)
317 {
318  return poll(const_cast<zmq_pollitem_t*>(items), nitems,
319  static_cast<long>(timeout.count()));
320 }
321 
322 ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
323 inline int poll(std::vector<zmq_pollitem_t> const& items,
324  std::chrono::milliseconds timeout)
325 {
326  return poll(const_cast<zmq_pollitem_t*>(items.data()), items.size(),
327  static_cast<long>(timeout.count()));
328 }
329 
330 ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items")
331 inline int poll(std::vector<zmq_pollitem_t> const& items, long timeout_ = -1)
332 {
333  return poll(const_cast<zmq_pollitem_t*>(items.data()), items.size(), timeout_);
334 }
335 
336 inline int poll(zmq_pollitem_t* items, size_t nitems, std::chrono::milliseconds timeout)
337 {
338  return poll(items, nitems, static_cast<long>(timeout.count()));
339 }
340 
341 inline int poll(std::vector<zmq_pollitem_t>& items, std::chrono::milliseconds timeout)
342 {
343  return poll(items.data(), items.size(), static_cast<long>(timeout.count()));
344 }
345 
346 ZMQ_DEPRECATED("from 4.3.1, use poll taking std::chrono instead of long")
347 inline int poll(std::vector<zmq_pollitem_t>& items, long timeout_ = -1)
348 {
349  return poll(items.data(), items.size(), timeout_);
350 }
351 
352 template <std::size_t SIZE>
353 inline int poll(std::array<zmq_pollitem_t, SIZE>& items,
354  std::chrono::milliseconds timeout)
355 {
356  return poll(items.data(), items.size(), static_cast<long>(timeout.count()));
357 }
358 #endif
359 
360 inline void version(int* major_, int* minor_, int* patch_)
361 {
362  zmq_version(major_, minor_, patch_);
363 }
364 
365 #ifdef ZMQ_CPP11
366 inline std::tuple<int, int, int> version()
367 {
368  std::tuple<int, int, int> v;
369  zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v));
370  return v;
371 }
372 
373 #if !defined(ZMQ_CPP11_PARTIAL)
374 namespace detail
375 {
376 template <class T>
377 struct is_char_type
378 {
379  // true if character type for string literals in C++11
380  static constexpr bool value =
381  std::is_same<T, char>::value || std::is_same<T, wchar_t>::value ||
382  std::is_same<T, char16_t>::value || std::is_same<T, char32_t>::value;
383 };
384 } // namespace detail
385 #endif
386 
387 #endif
388 
390 {
391 public:
393  {
394  int rc = zmq_msg_init(&msg);
395  ZMQ_ASSERT(rc == 0);
396  }
397 
398  explicit message_t(size_t size_)
399  {
400  int rc = zmq_msg_init_size(&msg, size_);
401  if (rc != 0)
402  throw error_t();
403  }
404 
405  template <class ForwardIter>
406  message_t(ForwardIter first, ForwardIter last)
407  {
408  typedef typename std::iterator_traits<ForwardIter>::value_type value_t;
409 
410  assert(std::distance(first, last) >= 0);
411  size_t const size_ =
412  static_cast<size_t>(std::distance(first, last)) * sizeof(value_t);
413  int const rc = zmq_msg_init_size(&msg, size_);
414  if (rc != 0)
415  throw error_t();
416  std::copy(first, last, data<value_t>());
417  }
418 
419  message_t(const void* data_, size_t size_)
420  {
421  int rc = zmq_msg_init_size(&msg, size_);
422  if (rc != 0)
423  throw error_t();
424  if (size_)
425  {
426  // this constructor allows (nullptr, 0),
427  // memcpy with a null pointer is UB
428  memcpy(data(), data_, size_);
429  }
430  }
431 
432  message_t(void* data_, size_t size_, free_fn* ffn_, void* hint_ = ZMQ_NULLPTR)
433  {
434  int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
435  if (rc != 0)
436  throw error_t();
437  }
438 
439  // overload set of string-like types and generic containers
440 #if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL)
441  // NOTE this constructor will include the null terminator
442  // when called with a string literal.
443  // An overload taking const char* can not be added because
444  // it would be preferred over this function and break compatiblity.
445  template <class Char, size_t N,
446  typename = typename std::enable_if<detail::is_char_type<Char>::value>::type>
447  ZMQ_DEPRECATED("from 4.7.0, use constructors taking iterators, (pointer, size) "
448  "or strings instead")
449  explicit message_t(const Char (&data)[N])
450  : message_t(detail::ranges::begin(data), detail::ranges::end(data))
451  {
452  }
453 
454  template <class Range, typename = typename std::enable_if<
455  detail::is_range<Range>::value &&
456  ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t<Range>) &&
457  !detail::is_char_type<detail::range_value_t<Range>>::value &&
458  !std::is_same<Range, message_t>::value>::type>
459  explicit message_t(const Range& rng)
460  : message_t(detail::ranges::begin(rng), detail::ranges::end(rng))
461  {
462  }
463 
464  explicit message_t(const std::string& str) : message_t(str.data(), str.size())
465  {
466  }
467 
468 #if CPPZMQ_HAS_STRING_VIEW
470  {
471  }
472 #endif
473 
474 #endif
475 
476 #ifdef ZMQ_HAS_RVALUE_REFS
477  message_t(message_t&& rhs) ZMQ_NOTHROW : msg(rhs.msg)
478  {
479  int rc = zmq_msg_init(&rhs.msg);
480  ZMQ_ASSERT(rc == 0);
481  }
482 
484  {
485  std::swap(msg, rhs.msg);
486  return *this;
487  }
488 #endif
489 
491  {
492  int rc = zmq_msg_close(&msg);
493  ZMQ_ASSERT(rc == 0);
494  }
495 
496  void rebuild()
497  {
498  int rc = zmq_msg_close(&msg);
499  if (rc != 0)
500  throw error_t();
501  rc = zmq_msg_init(&msg);
502  ZMQ_ASSERT(rc == 0);
503  }
504 
505  void rebuild(size_t size_)
506  {
507  int rc = zmq_msg_close(&msg);
508  if (rc != 0)
509  throw error_t();
510  rc = zmq_msg_init_size(&msg, size_);
511  if (rc != 0)
512  throw error_t();
513  }
514 
515  void rebuild(const void* data_, size_t size_)
516  {
517  int rc = zmq_msg_close(&msg);
518  if (rc != 0)
519  throw error_t();
520  rc = zmq_msg_init_size(&msg, size_);
521  if (rc != 0)
522  throw error_t();
523  memcpy(data(), data_, size_);
524  }
525 
526  void rebuild(void* data_, size_t size_, free_fn* ffn_, void* hint_ = ZMQ_NULLPTR)
527  {
528  int rc = zmq_msg_close(&msg);
529  if (rc != 0)
530  throw error_t();
531  rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_);
532  if (rc != 0)
533  throw error_t();
534  }
535 
536  ZMQ_DEPRECATED("from 4.3.1, use move taking non-const reference instead")
537  void move(message_t const* msg_)
538  {
539  int rc = zmq_msg_move(&msg, const_cast<zmq_msg_t*>(msg_->handle()));
540  if (rc != 0)
541  throw error_t();
542  }
543 
544  void move(message_t& msg_)
545  {
546  int rc = zmq_msg_move(&msg, msg_.handle());
547  if (rc != 0)
548  throw error_t();
549  }
550 
551  ZMQ_DEPRECATED("from 4.3.1, use copy taking non-const reference instead")
552  void copy(message_t const* msg_)
553  {
554  int rc = zmq_msg_copy(&msg, const_cast<zmq_msg_t*>(msg_->handle()));
555  if (rc != 0)
556  throw error_t();
557  }
558 
559  void copy(message_t& msg_)
560  {
561  int rc = zmq_msg_copy(&msg, msg_.handle());
562  if (rc != 0)
563  throw error_t();
564  }
565 
566  bool more() const ZMQ_NOTHROW
567  {
568  int rc = zmq_msg_more(const_cast<zmq_msg_t*>(&msg));
569  return rc != 0;
570  }
571 
573  {
574  return zmq_msg_data(&msg);
575  }
576 
577  const void* data() const ZMQ_NOTHROW
578  {
579  return zmq_msg_data(const_cast<zmq_msg_t*>(&msg));
580  }
581 
582  size_t size() const ZMQ_NOTHROW
583  {
584  return zmq_msg_size(const_cast<zmq_msg_t*>(&msg));
585  }
586 
588  {
589  return size() == 0u;
590  }
591 
592  template <typename T>
594  {
595  return static_cast<T*>(data());
596  }
597 
598  template <typename T>
599  T const* data() const ZMQ_NOTHROW
600  {
601  return static_cast<T const*>(data());
602  }
603 
604  ZMQ_DEPRECATED("from 4.3.0, use operator== instead")
605  bool equal(const message_t* other) const ZMQ_NOTHROW
606  {
607  return *this == *other;
608  }
609 
610  bool operator==(const message_t& other) const ZMQ_NOTHROW
611  {
612  const size_t my_size = size();
613  return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size);
614  }
615 
616  bool operator!=(const message_t& other) const ZMQ_NOTHROW
617  {
618  return !(*this == other);
619  }
620 
621 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0)
622  int get(int property_)
623  {
624  int value = zmq_msg_get(&msg, property_);
625  if (value == -1)
626  throw error_t();
627  return value;
628  }
629 #endif
630 
631 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0)
632  const char* gets(const char* property_)
633  {
634  const char* value = zmq_msg_gets(&msg, property_);
635  if (value == ZMQ_NULLPTR)
636  throw error_t();
637  return value;
638  }
639 #endif
640 
641 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
642  uint32_t routing_id() const
643  {
644  return zmq_msg_routing_id(const_cast<zmq_msg_t*>(&msg));
645  }
646 
647  void set_routing_id(uint32_t routing_id)
648  {
649  int rc = zmq_msg_set_routing_id(&msg, routing_id);
650  if (rc != 0)
651  throw error_t();
652  }
653 
654  const char* group() const
655  {
656  return zmq_msg_group(const_cast<zmq_msg_t*>(&msg));
657  }
658 
659  void set_group(const char* group)
660  {
661  int rc = zmq_msg_set_group(&msg, group);
662  if (rc != 0)
663  throw error_t();
664  }
665 #endif
666 
667  // interpret message content as a string
668  std::string to_string() const
669  {
670  return std::string(static_cast<const char*>(data()), size());
671  }
672 #if CPPZMQ_HAS_STRING_VIEW
673  // interpret message content as a string
674  std::string_view to_string_view() const noexcept
675  {
676  return std::string_view(static_cast<const char*>(data()), size());
677  }
678 #endif
679 
686  std::string str() const
687  {
688  // Partly mutuated from the same method in zmq::multipart_t
689  std::stringstream os;
690 
691  const unsigned char* msg_data = this->data<unsigned char>();
692  unsigned char byte;
693  size_t size = this->size();
694  int is_ascii[2] = { 0, 0 };
695 
696  os << "zmq::message_t [size " << std::dec << std::setw(3) << std::setfill('0') << size
697  << "] (";
698  // Totally arbitrary
699  if (size >= 1000)
700  {
701  os << "... too big to print)";
702  }
703  else
704  {
705  while (size--)
706  {
707  byte = *msg_data++;
708 
709  is_ascii[1] = (byte >= 32 && byte < 127);
710  if (is_ascii[1] != is_ascii[0])
711  os << " "; // Separate text/non text
712 
713  if (is_ascii[1])
714  {
715  os << byte;
716  }
717  else
718  {
719  os << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
720  << static_cast<short>(byte);
721  }
722  is_ascii[0] = is_ascii[1];
723  }
724  os << ")";
725  }
726  return os.str();
727  }
728 
730  {
731  // this assumes zmq::msg_t from libzmq is trivially relocatable
732  std::swap(msg, other.msg);
733  }
734 
736  {
737  return &msg;
738  }
739  ZMQ_NODISCARD const zmq_msg_t* handle() const ZMQ_NOTHROW
740  {
741  return &msg;
742  }
743 
744 private:
745  // The underlying message
746  zmq_msg_t msg;
747 
748  // Disable implicit message copying, so that users won't use shared
749  // messages (less efficient) without being aware of the fact.
752 };
753 
754 inline void swap(message_t& a, message_t& b) ZMQ_NOTHROW
755 {
756  a.swap(b);
757 }
758 
759 #ifdef ZMQ_CPP11
760 enum class ctxopt
761 {
762 #ifdef ZMQ_BLOCKY
763  blocky = ZMQ_BLOCKY,
764 #endif
765 #ifdef ZMQ_IO_THREADS
766  io_threads = ZMQ_IO_THREADS,
767 #endif
768 #ifdef ZMQ_THREAD_SCHED_POLICY
769  thread_sched_policy = ZMQ_THREAD_SCHED_POLICY,
770 #endif
771 #ifdef ZMQ_THREAD_PRIORITY
772  thread_priority = ZMQ_THREAD_PRIORITY,
773 #endif
774 #ifdef ZMQ_THREAD_AFFINITY_CPU_ADD
775  thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD,
776 #endif
777 #ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE
778  thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE,
779 #endif
780 #ifdef ZMQ_THREAD_NAME_PREFIX
781  thread_name_prefix = ZMQ_THREAD_NAME_PREFIX,
782 #endif
783 #ifdef ZMQ_MAX_MSGSZ
784  max_msgsz = ZMQ_MAX_MSGSZ,
785 #endif
786 #ifdef ZMQ_ZERO_COPY_RECV
787  zero_copy_recv = ZMQ_ZERO_COPY_RECV,
788 #endif
789 #ifdef ZMQ_MAX_SOCKETS
790  max_sockets = ZMQ_MAX_SOCKETS,
791 #endif
792 #ifdef ZMQ_SOCKET_LIMIT
793  socket_limit = ZMQ_SOCKET_LIMIT,
794 #endif
795 #ifdef ZMQ_IPV6
796  ipv6 = ZMQ_IPV6,
797 #endif
798 #ifdef ZMQ_MSG_T_SIZE
799  msg_t_size = ZMQ_MSG_T_SIZE
800 #endif
801 };
802 #endif
803 
805 {
806 public:
808  {
809  ptr = zmq_ctx_new();
810  if (ptr == ZMQ_NULLPTR)
811  throw error_t();
812  }
813 
814  explicit context_t(int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT)
815  {
816  ptr = zmq_ctx_new();
817  if (ptr == ZMQ_NULLPTR)
818  throw error_t();
819 
820  int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_);
821  ZMQ_ASSERT(rc == 0);
822 
823  rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_);
824  ZMQ_ASSERT(rc == 0);
825  }
826 
827 #ifdef ZMQ_HAS_RVALUE_REFS
828  context_t(context_t&& rhs) ZMQ_NOTHROW : ptr(rhs.ptr)
829  {
830  rhs.ptr = ZMQ_NULLPTR;
831  }
833  {
834  close();
835  std::swap(ptr, rhs.ptr);
836  return *this;
837  }
838 #endif
839 
841  {
842  close();
843  }
844 
845  ZMQ_CPP11_DEPRECATED("from 4.7.0, use set taking zmq::ctxopt instead")
846  int setctxopt(int option_, int optval_)
847  {
848  int rc = zmq_ctx_set(ptr, option_, optval_);
849  ZMQ_ASSERT(rc == 0);
850  return rc;
851  }
852 
853  ZMQ_CPP11_DEPRECATED("from 4.7.0, use get taking zmq::ctxopt instead")
854  int getctxopt(int option_)
855  {
856  return zmq_ctx_get(ptr, option_);
857  }
858 
859 #ifdef ZMQ_CPP11
860  void set(ctxopt option, int optval)
861  {
862  int rc = zmq_ctx_set(ptr, static_cast<int>(option), optval);
863  if (rc == -1)
864  throw error_t();
865  }
866 
867  ZMQ_NODISCARD int get(ctxopt option)
868  {
869  int rc = zmq_ctx_get(ptr, static_cast<int>(option));
870  // some options have a default value of -1
871  // which is unfortunate, and may result in errors
872  // that don't make sense
873  if (rc == -1)
874  throw error_t();
875  return rc;
876  }
877 #endif
878 
879  // Terminates context (see also shutdown()).
881  {
882  if (ptr == ZMQ_NULLPTR)
883  return;
884 
885  int rc;
886  do
887  {
888  rc = zmq_ctx_destroy(ptr);
889  } while (rc == -1 && errno == EINTR);
890 
891  ZMQ_ASSERT(rc == 0);
892  ptr = ZMQ_NULLPTR;
893  }
894 
895  // Shutdown context in preparation for termination (close()).
896  // Causes all blocking socket operations and any further
897  // socket operations to return with ETERM.
899  {
900  if (ptr == ZMQ_NULLPTR)
901  return;
902  int rc = zmq_ctx_shutdown(ptr);
903  ZMQ_ASSERT(rc == 0);
904  }
905 
906  // Be careful with this, it's probably only useful for
907  // using the C api together with an existing C++ api.
908  // Normally you should never need to use this.
909  ZMQ_EXPLICIT operator void*() ZMQ_NOTHROW
910  {
911  return ptr;
912  }
913 
914  ZMQ_EXPLICIT operator void const*() const ZMQ_NOTHROW
915  {
916  return ptr;
917  }
918 
920  {
921  return ptr;
922  }
923 
924  ZMQ_DEPRECATED("from 4.7.0, use handle() != nullptr instead")
925  operator bool() const ZMQ_NOTHROW
926  {
927  return ptr != ZMQ_NULLPTR;
928  }
929 
931  {
932  std::swap(ptr, other.ptr);
933  }
934 
935 private:
936  void* ptr;
937 
940 };
941 
942 inline void swap(context_t& a, context_t& b) ZMQ_NOTHROW
943 {
944  a.swap(b);
945 }
946 
947 #ifdef ZMQ_CPP11
948 
949 struct recv_buffer_size
950 {
951  size_t size; // number of bytes written to buffer
952  size_t untruncated_size; // untruncated message size in bytes
953 
954  ZMQ_NODISCARD bool truncated() const noexcept
955  {
956  return size != untruncated_size;
957  }
958 };
959 
960 #if CPPZMQ_HAS_OPTIONAL
961 
962 using send_result_t = std::optional<size_t>;
963 using recv_result_t = std::optional<size_t>;
964 using recv_buffer_result_t = std::optional<recv_buffer_size>;
965 
966 #else
967 
968 namespace detail
969 {
970 // A C++11 type emulating the most basic
971 // operations of std::optional for trivial types
972 template <class T>
973 class trivial_optional
974 {
975 public:
976  static_assert(std::is_trivial<T>::value, "T must be trivial");
977  using value_type = T;
978 
979  trivial_optional() = default;
980  trivial_optional(T value) noexcept : _value(value), _has_value(true)
981  {
982  }
983 
984  const T* operator->() const noexcept
985  {
986  assert(_has_value);
987  return &_value;
988  }
989  T* operator->() noexcept
990  {
991  assert(_has_value);
992  return &_value;
993  }
994 
995  const T& operator*() const noexcept
996  {
997  assert(_has_value);
998  return _value;
999  }
1000  T& operator*() noexcept
1001  {
1002  assert(_has_value);
1003  return _value;
1004  }
1005 
1006  T& value()
1007  {
1008  if (!_has_value)
1009  throw std::exception();
1010  return _value;
1011  }
1012  const T& value() const
1013  {
1014  if (!_has_value)
1015  throw std::exception();
1016  return _value;
1017  }
1018 
1019  explicit operator bool() const noexcept
1020  {
1021  return _has_value;
1022  }
1023  bool has_value() const noexcept
1024  {
1025  return _has_value;
1026  }
1027 
1028 private:
1029  T _value{};
1030  bool _has_value{ false };
1031 };
1032 } // namespace detail
1033 
1034 using send_result_t = detail::trivial_optional<size_t>;
1035 using recv_result_t = detail::trivial_optional<size_t>;
1036 using recv_buffer_result_t = detail::trivial_optional<recv_buffer_size>;
1037 
1038 #endif
1039 
1040 namespace detail
1041 {
1042 template <class T>
1043 constexpr T enum_bit_or(T a, T b) noexcept
1044 {
1045  static_assert(std::is_enum<T>::value, "must be enum");
1046  using U = typename std::underlying_type<T>::type;
1047  return static_cast<T>(static_cast<U>(a) | static_cast<U>(b));
1048 }
1049 template <class T>
1050 constexpr T enum_bit_and(T a, T b) noexcept
1051 {
1052  static_assert(std::is_enum<T>::value, "must be enum");
1053  using U = typename std::underlying_type<T>::type;
1054  return static_cast<T>(static_cast<U>(a) & static_cast<U>(b));
1055 }
1056 template <class T>
1057 constexpr T enum_bit_xor(T a, T b) noexcept
1058 {
1059  static_assert(std::is_enum<T>::value, "must be enum");
1060  using U = typename std::underlying_type<T>::type;
1061  return static_cast<T>(static_cast<U>(a) ^ static_cast<U>(b));
1062 }
1063 template <class T>
1064 constexpr T enum_bit_not(T a) noexcept
1065 {
1066  static_assert(std::is_enum<T>::value, "must be enum");
1067  using U = typename std::underlying_type<T>::type;
1068  return static_cast<T>(~static_cast<U>(a));
1069 }
1070 } // namespace detail
1071 
1072 // partially satisfies named requirement BitmaskType
1073 enum class send_flags : int
1074 {
1075  none = 0,
1076  dontwait = ZMQ_DONTWAIT,
1077  sndmore = ZMQ_SNDMORE
1078 };
1079 
1080 constexpr send_flags operator|(send_flags a, send_flags b) noexcept
1081 {
1082  return detail::enum_bit_or(a, b);
1083 }
1084 constexpr send_flags operator&(send_flags a, send_flags b) noexcept
1085 {
1086  return detail::enum_bit_and(a, b);
1087 }
1088 constexpr send_flags operator^(send_flags a, send_flags b) noexcept
1089 {
1090  return detail::enum_bit_xor(a, b);
1091 }
1092 constexpr send_flags operator~(send_flags a) noexcept
1093 {
1094  return detail::enum_bit_not(a);
1095 }
1096 
1097 // partially satisfies named requirement BitmaskType
1098 enum class recv_flags : int
1099 {
1100  none = 0,
1101  dontwait = ZMQ_DONTWAIT
1102 };
1103 
1104 constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept
1105 {
1106  return detail::enum_bit_or(a, b);
1107 }
1108 constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept
1109 {
1110  return detail::enum_bit_and(a, b);
1111 }
1112 constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept
1113 {
1114  return detail::enum_bit_xor(a, b);
1115 }
1116 constexpr recv_flags operator~(recv_flags a) noexcept
1117 {
1118  return detail::enum_bit_not(a);
1119 }
1120 
1121 // mutable_buffer, const_buffer and buffer are based on
1122 // the Networking TS specification, draft:
1123 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf
1124 
1125 class mutable_buffer
1126 {
1127 public:
1128  constexpr mutable_buffer() noexcept : _data(nullptr), _size(0)
1129  {
1130  }
1131  constexpr mutable_buffer(void* p, size_t n) noexcept : _data(p), _size(n)
1132  {
1133 #ifdef ZMQ_EXTENDED_CONSTEXPR
1134  assert(p != nullptr || n == 0);
1135 #endif
1136  }
1137 
1138  constexpr void* data() const noexcept
1139  {
1140  return _data;
1141  }
1142  constexpr size_t size() const noexcept
1143  {
1144  return _size;
1145  }
1146  mutable_buffer& operator+=(size_t n) noexcept
1147  {
1148  // (std::min) is a workaround for when a min macro is defined
1149  const auto shift = (std::min)(n, _size);
1150  _data = static_cast<char*>(_data) + shift;
1151  _size -= shift;
1152  return *this;
1153  }
1154 
1155 private:
1156  void* _data;
1157  size_t _size;
1158 };
1159 
1160 inline mutable_buffer operator+(const mutable_buffer& mb, size_t n) noexcept
1161 {
1162  return mutable_buffer(static_cast<char*>(mb.data()) + (std::min)(n, mb.size()),
1163  mb.size() - (std::min)(n, mb.size()));
1164 }
1165 inline mutable_buffer operator+(size_t n, const mutable_buffer& mb) noexcept
1166 {
1167  return mb + n;
1168 }
1169 
1170 class const_buffer
1171 {
1172 public:
1173  constexpr const_buffer() noexcept : _data(nullptr), _size(0)
1174  {
1175  }
1176  constexpr const_buffer(const void* p, size_t n) noexcept : _data(p), _size(n)
1177  {
1178 #ifdef ZMQ_EXTENDED_CONSTEXPR
1179  assert(p != nullptr || n == 0);
1180 #endif
1181  }
1182  constexpr const_buffer(const mutable_buffer& mb) noexcept
1183  : _data(mb.data()), _size(mb.size())
1184  {
1185  }
1186 
1187  constexpr const void* data() const noexcept
1188  {
1189  return _data;
1190  }
1191  constexpr size_t size() const noexcept
1192  {
1193  return _size;
1194  }
1195  const_buffer& operator+=(size_t n) noexcept
1196  {
1197  const auto shift = (std::min)(n, _size);
1198  _data = static_cast<const char*>(_data) + shift;
1199  _size -= shift;
1200  return *this;
1201  }
1202 
1203 private:
1204  const void* _data;
1205  size_t _size;
1206 };
1207 
1208 inline const_buffer operator+(const const_buffer& cb, size_t n) noexcept
1209 {
1210  return const_buffer(static_cast<const char*>(cb.data()) + (std::min)(n, cb.size()),
1211  cb.size() - (std::min)(n, cb.size()));
1212 }
1213 inline const_buffer operator+(size_t n, const const_buffer& cb) noexcept
1214 {
1215  return cb + n;
1216 }
1217 
1218 // buffer creation
1219 
1220 constexpr mutable_buffer buffer(void* p, size_t n) noexcept
1221 {
1222  return mutable_buffer(p, n);
1223 }
1224 constexpr const_buffer buffer(const void* p, size_t n) noexcept
1225 {
1226  return const_buffer(p, n);
1227 }
1228 constexpr mutable_buffer buffer(const mutable_buffer& mb) noexcept
1229 {
1230  return mb;
1231 }
1232 inline mutable_buffer buffer(const mutable_buffer& mb, size_t n) noexcept
1233 {
1234  return mutable_buffer(mb.data(), (std::min)(mb.size(), n));
1235 }
1236 constexpr const_buffer buffer(const const_buffer& cb) noexcept
1237 {
1238  return cb;
1239 }
1240 inline const_buffer buffer(const const_buffer& cb, size_t n) noexcept
1241 {
1242  return const_buffer(cb.data(), (std::min)(cb.size(), n));
1243 }
1244 
1245 namespace detail
1246 {
1247 template <class T>
1248 struct is_buffer
1249 {
1250  static constexpr bool value =
1251  std::is_same<T, const_buffer>::value || std::is_same<T, mutable_buffer>::value;
1252 };
1253 
1254 template <class T>
1255 struct is_pod_like
1256 {
1257  // NOTE: The networking draft N4771 section 16.11 requires
1258  // T in the buffer functions below to be
1259  // trivially copyable OR standard layout.
1260  // Here we decide to be conservative and require both.
1261  static constexpr bool value =
1262  ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout<T>::value;
1263 };
1264 
1265 template <class C>
1266 constexpr auto seq_size(const C& c) noexcept -> decltype(c.size())
1267 {
1268  return c.size();
1269 }
1270 template <class T, size_t N>
1271 constexpr size_t seq_size(const T (& /*array*/)[N]) noexcept
1272 {
1273  return N;
1274 }
1275 
1276 template <class Seq>
1277 auto buffer_contiguous_sequence(Seq&& seq) noexcept
1278  -> decltype(buffer(std::addressof(*std::begin(seq)), size_t{}))
1279 {
1280  using T = typename std::remove_cv<
1281  typename std::remove_reference<decltype(*std::begin(seq))>::type>::type;
1282  static_assert(detail::is_pod_like<T>::value, "T must be POD");
1283 
1284  const auto size = seq_size(seq);
1285  return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr,
1286  size * sizeof(T));
1287 }
1288 template <class Seq>
1289 auto buffer_contiguous_sequence(Seq&& seq, size_t n_bytes) noexcept
1290  -> decltype(buffer_contiguous_sequence(seq))
1291 {
1292  using T = typename std::remove_cv<
1293  typename std::remove_reference<decltype(*std::begin(seq))>::type>::type;
1294  static_assert(detail::is_pod_like<T>::value, "T must be POD");
1295 
1296  const auto size = seq_size(seq);
1297  return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr,
1298  (std::min)(size * sizeof(T), n_bytes));
1299 }
1300 
1301 } // namespace detail
1302 
1303 // C array
1304 template <class T, size_t N>
1305 mutable_buffer buffer(T (&data)[N]) noexcept
1306 {
1307  return detail::buffer_contiguous_sequence(data);
1308 }
1309 template <class T, size_t N>
1310 mutable_buffer buffer(T (&data)[N], size_t n_bytes) noexcept
1311 {
1312  return detail::buffer_contiguous_sequence(data, n_bytes);
1313 }
1314 template <class T, size_t N>
1315 const_buffer buffer(const T (&data)[N]) noexcept
1316 {
1317  return detail::buffer_contiguous_sequence(data);
1318 }
1319 template <class T, size_t N>
1320 const_buffer buffer(const T (&data)[N], size_t n_bytes) noexcept
1321 {
1322  return detail::buffer_contiguous_sequence(data, n_bytes);
1323 }
1324 // std::array
1325 template <class T, size_t N>
1326 mutable_buffer buffer(std::array<T, N>& data) noexcept
1327 {
1328  return detail::buffer_contiguous_sequence(data);
1329 }
1330 template <class T, size_t N>
1331 mutable_buffer buffer(std::array<T, N>& data, size_t n_bytes) noexcept
1332 {
1333  return detail::buffer_contiguous_sequence(data, n_bytes);
1334 }
1335 template <class T, size_t N>
1336 const_buffer buffer(std::array<const T, N>& data) noexcept
1337 {
1338  return detail::buffer_contiguous_sequence(data);
1339 }
1340 template <class T, size_t N>
1341 const_buffer buffer(std::array<const T, N>& data, size_t n_bytes) noexcept
1342 {
1343  return detail::buffer_contiguous_sequence(data, n_bytes);
1344 }
1345 template <class T, size_t N>
1346 const_buffer buffer(const std::array<T, N>& data) noexcept
1347 {
1348  return detail::buffer_contiguous_sequence(data);
1349 }
1350 template <class T, size_t N>
1351 const_buffer buffer(const std::array<T, N>& data, size_t n_bytes) noexcept
1352 {
1353  return detail::buffer_contiguous_sequence(data, n_bytes);
1354 }
1355 // std::vector
1356 template <class T, class Allocator>
1357 mutable_buffer buffer(std::vector<T, Allocator>& data) noexcept
1358 {
1359  return detail::buffer_contiguous_sequence(data);
1360 }
1361 template <class T, class Allocator>
1362 mutable_buffer buffer(std::vector<T, Allocator>& data, size_t n_bytes) noexcept
1363 {
1364  return detail::buffer_contiguous_sequence(data, n_bytes);
1365 }
1366 template <class T, class Allocator>
1367 const_buffer buffer(const std::vector<T, Allocator>& data) noexcept
1368 {
1369  return detail::buffer_contiguous_sequence(data);
1370 }
1371 template <class T, class Allocator>
1372 const_buffer buffer(const std::vector<T, Allocator>& data, size_t n_bytes) noexcept
1373 {
1374  return detail::buffer_contiguous_sequence(data, n_bytes);
1375 }
1376 // std::basic_string
1377 template <class T, class Traits, class Allocator>
1378 mutable_buffer buffer(std::basic_string<T, Traits, Allocator>& data) noexcept
1379 {
1380  return detail::buffer_contiguous_sequence(data);
1381 }
1382 template <class T, class Traits, class Allocator>
1383 mutable_buffer buffer(std::basic_string<T, Traits, Allocator>& data,
1384  size_t n_bytes) noexcept
1385 {
1386  return detail::buffer_contiguous_sequence(data, n_bytes);
1387 }
1388 template <class T, class Traits, class Allocator>
1389 const_buffer buffer(const std::basic_string<T, Traits, Allocator>& data) noexcept
1390 {
1391  return detail::buffer_contiguous_sequence(data);
1392 }
1393 template <class T, class Traits, class Allocator>
1394 const_buffer buffer(const std::basic_string<T, Traits, Allocator>& data,
1395  size_t n_bytes) noexcept
1396 {
1397  return detail::buffer_contiguous_sequence(data, n_bytes);
1398 }
1399 
1400 #if CPPZMQ_HAS_STRING_VIEW
1401 // std::basic_string_view
1402 template <class T, class Traits>
1403 const_buffer buffer(std::basic_string_view<T, Traits> data) noexcept
1404 {
1405  return detail::buffer_contiguous_sequence(data);
1406 }
1407 template <class T, class Traits>
1408 const_buffer buffer(std::basic_string_view<T, Traits> data, size_t n_bytes) noexcept
1409 {
1410  return detail::buffer_contiguous_sequence(data, n_bytes);
1411 }
1412 #endif
1413 
1414 // Buffer for a string literal (null terminated)
1415 // where the buffer size excludes the terminating character.
1416 // Equivalent to zmq::buffer(std::string_view("...")).
1417 template <class Char, size_t N>
1418 constexpr const_buffer str_buffer(const Char (&data)[N]) noexcept
1419 {
1420  static_assert(detail::is_pod_like<Char>::value, "Char must be POD");
1421 #ifdef ZMQ_EXTENDED_CONSTEXPR
1422  assert(data[N - 1] == Char{ 0 });
1423 #endif
1424  return const_buffer(static_cast<const Char*>(data), (N - 1) * sizeof(Char));
1425 }
1426 
1427 namespace literals
1428 {
1429 constexpr const_buffer operator"" _zbuf(const char* str, size_t len) noexcept
1430 {
1431  return const_buffer(str, len * sizeof(char));
1432 }
1433 constexpr const_buffer operator"" _zbuf(const wchar_t* str, size_t len) noexcept
1434 {
1435  return const_buffer(str, len * sizeof(wchar_t));
1436 }
1437 constexpr const_buffer operator"" _zbuf(const char16_t* str, size_t len) noexcept
1438 {
1439  return const_buffer(str, len * sizeof(char16_t));
1440 }
1441 constexpr const_buffer operator"" _zbuf(const char32_t* str, size_t len) noexcept
1442 {
1443  return const_buffer(str, len * sizeof(char32_t));
1444 }
1445 } // namespace literals
1446 
1447 #endif // ZMQ_CPP11
1448 
1449 #ifdef ZMQ_CPP11
1450 namespace sockopt
1451 {
1452 // There are two types of options,
1453 // integral type with known compiler time size (int, bool, int64_t, uint64_t)
1454 // and arrays with dynamic size (strings, binary data).
1455 
1456 // BoolUnit: if true accepts values of type bool (but passed as T into libzmq)
1457 template <int Opt, class T, bool BoolUnit = false>
1458 struct integral_option
1459 {
1460 };
1461 
1462 // NullTerm:
1463 // 0: binary data
1464 // 1: null-terminated string (`getsockopt` size includes null)
1465 // 2: binary (size 32) or Z85 encoder string of size 41 (null included)
1466 template <int Opt, int NullTerm = 1>
1467 struct array_option
1468 {
1469 };
1470 
1471 #define ZMQ_DEFINE_INTEGRAL_OPT(OPT, NAME, TYPE) \
1472  using NAME##_t = integral_option<OPT, TYPE, false>; \
1473  ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \
1474  { \
1475  }
1476 #define ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(OPT, NAME, TYPE) \
1477  using NAME##_t = integral_option<OPT, TYPE, true>; \
1478  ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \
1479  { \
1480  }
1481 #define ZMQ_DEFINE_ARRAY_OPT(OPT, NAME) \
1482  using NAME##_t = array_option<OPT>; \
1483  ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \
1484  { \
1485  }
1486 #define ZMQ_DEFINE_ARRAY_OPT_BINARY(OPT, NAME) \
1487  using NAME##_t = array_option<OPT, 0>; \
1488  ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \
1489  { \
1490  }
1491 #define ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(OPT, NAME) \
1492  using NAME##_t = array_option<OPT, 2>; \
1493  ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \
1494  { \
1495  }
1496 
1497 // duplicate definition from libzmq 4.3.3
1498 #if defined _WIN32
1499 #if defined _WIN64
1500 typedef unsigned __int64 cppzmq_fd_t;
1501 #else
1502 typedef unsigned int cppzmq_fd_t;
1503 #endif
1504 #else
1505 typedef int cppzmq_fd_t;
1506 #endif
1507 
1508 #ifdef ZMQ_AFFINITY
1509 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_AFFINITY, affinity, uint64_t);
1510 #endif
1511 #ifdef ZMQ_BACKLOG
1512 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_BACKLOG, backlog, int);
1513 #endif
1514 #ifdef ZMQ_BINDTODEVICE
1515 ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_BINDTODEVICE, bindtodevice);
1516 #endif
1517 #ifdef ZMQ_CONFLATE
1518 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CONFLATE, conflate, int);
1519 #endif
1520 #ifdef ZMQ_CONNECT_ROUTING_ID
1521 ZMQ_DEFINE_ARRAY_OPT(ZMQ_CONNECT_ROUTING_ID, connect_routing_id);
1522 #endif
1523 #ifdef ZMQ_CONNECT_TIMEOUT
1524 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_CONNECT_TIMEOUT, connect_timeout, int);
1525 #endif
1526 #ifdef ZMQ_CURVE_PUBLICKEY
1527 ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_PUBLICKEY, curve_publickey);
1528 #endif
1529 #ifdef ZMQ_CURVE_SECRETKEY
1530 ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SECRETKEY, curve_secretkey);
1531 #endif
1532 #ifdef ZMQ_CURVE_SERVER
1533 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CURVE_SERVER, curve_server, int);
1534 #endif
1535 #ifdef ZMQ_CURVE_SERVERKEY
1536 ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SERVERKEY, curve_serverkey);
1537 #endif
1538 #ifdef ZMQ_EVENTS
1539 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_EVENTS, events, int);
1540 #endif
1541 #ifdef ZMQ_FD
1542 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_FD, fd, cppzmq_fd_t);
1543 #endif
1544 #ifdef ZMQ_GSSAPI_PLAINTEXT
1545 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_PLAINTEXT, gssapi_plaintext, int);
1546 #endif
1547 #ifdef ZMQ_GSSAPI_SERVER
1548 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_SERVER, gssapi_server, int);
1549 #endif
1550 #ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL
1551 ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL, gssapi_service_principal);
1552 #endif
1553 #ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE
1554 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE,
1555  gssapi_service_principal_nametype, int);
1556 #endif
1557 #ifdef ZMQ_GSSAPI_PRINCIPAL
1558 ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_PRINCIPAL, gssapi_principal);
1559 #endif
1560 #ifdef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE
1561 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, gssapi_principal_nametype, int);
1562 #endif
1563 #ifdef ZMQ_HANDSHAKE_IVL
1564 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HANDSHAKE_IVL, handshake_ivl, int);
1565 #endif
1566 #ifdef ZMQ_HEARTBEAT_IVL
1567 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_IVL, heartbeat_ivl, int);
1568 #endif
1569 #ifdef ZMQ_HEARTBEAT_TIMEOUT
1570 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TIMEOUT, heartbeat_timeout, int);
1571 #endif
1572 #ifdef ZMQ_HEARTBEAT_TTL
1573 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TTL, heartbeat_ttl, int);
1574 #endif
1575 #ifdef ZMQ_IMMEDIATE
1576 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IMMEDIATE, immediate, int);
1577 #endif
1578 #ifdef ZMQ_INVERT_MATCHING
1579 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_INVERT_MATCHING, invert_matching, int);
1580 #endif
1581 #ifdef ZMQ_IPV6
1582 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IPV6, ipv6, int);
1583 #endif
1584 #ifdef ZMQ_LAST_ENDPOINT
1585 ZMQ_DEFINE_ARRAY_OPT(ZMQ_LAST_ENDPOINT, last_endpoint);
1586 #endif
1587 #ifdef ZMQ_LINGER
1588 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_LINGER, linger, int);
1589 #endif
1590 #ifdef ZMQ_MAXMSGSIZE
1591 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MAXMSGSIZE, maxmsgsize, int64_t);
1592 #endif
1593 #ifdef ZMQ_MECHANISM
1594 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MECHANISM, mechanism, int);
1595 #endif
1596 #ifdef ZMQ_METADATA
1597 ZMQ_DEFINE_ARRAY_OPT(ZMQ_METADATA, metadata);
1598 #endif
1599 #ifdef ZMQ_MULTICAST_HOPS
1600 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_HOPS, multicast_hops, int);
1601 #endif
1602 #ifdef ZMQ_MULTICAST_LOOP
1603 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_MULTICAST_LOOP, multicast_loop, int);
1604 #endif
1605 #ifdef ZMQ_MULTICAST_MAXTPDU
1606 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_MAXTPDU, multicast_maxtpdu, int);
1607 #endif
1608 #ifdef ZMQ_PLAIN_SERVER
1609 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PLAIN_SERVER, plain_server, int);
1610 #endif
1611 #ifdef ZMQ_PLAIN_PASSWORD
1612 ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_PASSWORD, plain_password);
1613 #endif
1614 #ifdef ZMQ_PLAIN_USERNAME
1615 ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_USERNAME, plain_username);
1616 #endif
1617 #ifdef ZMQ_USE_FD
1618 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_USE_FD, use_fd, int);
1619 #endif
1620 #ifdef ZMQ_PROBE_ROUTER
1621 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PROBE_ROUTER, probe_router, int);
1622 #endif
1623 #ifdef ZMQ_RATE
1624 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RATE, rate, int);
1625 #endif
1626 #ifdef ZMQ_RCVBUF
1627 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVBUF, rcvbuf, int);
1628 #endif
1629 #ifdef ZMQ_RCVHWM
1630 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVHWM, rcvhwm, int);
1631 #endif
1632 #ifdef ZMQ_RCVMORE
1633 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_RCVMORE, rcvmore, int);
1634 #endif
1635 #ifdef ZMQ_RCVTIMEO
1636 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVTIMEO, rcvtimeo, int);
1637 #endif
1638 #ifdef ZMQ_RECONNECT_IVL
1639 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL, reconnect_ivl, int);
1640 #endif
1641 #ifdef ZMQ_RECONNECT_IVL_MAX
1642 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL_MAX, reconnect_ivl_max, int);
1643 #endif
1644 #ifdef ZMQ_RECOVERY_IVL
1645 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECOVERY_IVL, recovery_ivl, int);
1646 #endif
1647 #ifdef ZMQ_REQ_CORRELATE
1648 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_CORRELATE, req_correlate, int);
1649 #endif
1650 #ifdef ZMQ_REQ_RELAXED
1651 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_RELAXED, req_relaxed, int);
1652 #endif
1653 #ifdef ZMQ_ROUTER_HANDOVER
1654 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_HANDOVER, router_handover, int);
1655 #endif
1656 #ifdef ZMQ_ROUTER_MANDATORY
1657 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_MANDATORY, router_mandatory, int);
1658 #endif
1659 #ifdef ZMQ_ROUTER_NOTIFY
1660 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_NOTIFY, router_notify, int);
1661 #endif
1662 #ifdef ZMQ_ROUTING_ID
1663 ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_ROUTING_ID, routing_id);
1664 #endif
1665 #ifdef ZMQ_SNDBUF
1666 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDBUF, sndbuf, int);
1667 #endif
1668 #ifdef ZMQ_SNDHWM
1669 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDHWM, sndhwm, int);
1670 #endif
1671 #ifdef ZMQ_SNDTIMEO
1672 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDTIMEO, sndtimeo, int);
1673 #endif
1674 #ifdef ZMQ_SOCKS_PROXY
1675 ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PROXY, socks_proxy);
1676 #endif
1677 #ifdef ZMQ_STREAM_NOTIFY
1678 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_STREAM_NOTIFY, stream_notify, int);
1679 #endif
1680 #ifdef ZMQ_SUBSCRIBE
1681 ZMQ_DEFINE_ARRAY_OPT(ZMQ_SUBSCRIBE, subscribe);
1682 #endif
1683 #ifdef ZMQ_TCP_KEEPALIVE
1684 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE, tcp_keepalive, int);
1685 #endif
1686 #ifdef ZMQ_TCP_KEEPALIVE_CNT
1687 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_CNT, tcp_keepalive_cnt, int);
1688 #endif
1689 #ifdef ZMQ_TCP_KEEPALIVE_IDLE
1690 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_IDLE, tcp_keepalive_idle, int);
1691 #endif
1692 #ifdef ZMQ_TCP_KEEPALIVE_INTVL
1693 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_INTVL, tcp_keepalive_intvl, int);
1694 #endif
1695 #ifdef ZMQ_TCP_MAXRT
1696 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_MAXRT, tcp_maxrt, int);
1697 #endif
1698 #ifdef ZMQ_THREAD_SAFE
1699 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_THREAD_SAFE, thread_safe, int);
1700 #endif
1701 #ifdef ZMQ_TOS
1702 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int);
1703 #endif
1704 #ifdef ZMQ_TYPE
1705 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int);
1706 #endif
1707 #ifdef ZMQ_UNSUBSCRIBE
1708 ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe);
1709 #endif
1710 #ifdef ZMQ_VMCI_BUFFER_SIZE
1711 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_SIZE, vmci_buffer_size, uint64_t);
1712 #endif
1713 #ifdef ZMQ_VMCI_BUFFER_MIN_SIZE
1714 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MIN_SIZE, vmci_buffer_min_size, uint64_t);
1715 #endif
1716 #ifdef ZMQ_VMCI_BUFFER_MAX_SIZE
1717 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MAX_SIZE, vmci_buffer_max_size, uint64_t);
1718 #endif
1719 #ifdef ZMQ_VMCI_CONNECT_TIMEOUT
1720 ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_CONNECT_TIMEOUT, vmci_connect_timeout, int);
1721 #endif
1722 #ifdef ZMQ_XPUB_VERBOSE
1723 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSE, xpub_verbose, int);
1724 #endif
1725 #ifdef ZMQ_XPUB_VERBOSER
1726 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSER, xpub_verboser, int);
1727 #endif
1728 #ifdef ZMQ_XPUB_MANUAL
1729 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL, xpub_manual, int);
1730 #endif
1731 #ifdef ZMQ_XPUB_NODROP
1732 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_NODROP, xpub_nodrop, int);
1733 #endif
1734 #ifdef ZMQ_XPUB_WELCOME_MSG
1735 ZMQ_DEFINE_ARRAY_OPT(ZMQ_XPUB_WELCOME_MSG, xpub_welcome_msg);
1736 #endif
1737 #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
1738 ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ZAP_ENFORCE_DOMAIN, zap_enforce_domain, int);
1739 #endif
1740 #ifdef ZMQ_ZAP_DOMAIN
1741 ZMQ_DEFINE_ARRAY_OPT(ZMQ_ZAP_DOMAIN, zap_domain);
1742 #endif
1743 
1744 } // namespace sockopt
1745 #endif // ZMQ_CPP11
1746 
1747 namespace detail
1748 {
1750 {
1751 public:
1753  {
1754  }
1755  ZMQ_EXPLICIT socket_base(void* handle) ZMQ_NOTHROW : _handle(handle)
1756  {
1757  }
1758 
1759  template <typename T>
1760  ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt")
1761  void setsockopt(int option_, T const& optval)
1762  {
1763  setsockopt(option_, &optval, sizeof(T));
1764  }
1765 
1766  ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt")
1767  void setsockopt(int option_, const void* optval_, size_t optvallen_)
1768  {
1769  int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_);
1770  if (rc != 0)
1771  throw error_t();
1772  }
1773 
1774  ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt")
1775  void getsockopt(int option_, void* optval_, size_t* optvallen_) const
1776  {
1777  int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_);
1778  if (rc != 0)
1779  throw error_t();
1780  }
1781 
1782  template <typename T>
1783  ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt")
1784  T getsockopt(int option_) const
1785  {
1786  T optval;
1787  size_t optlen = sizeof(T);
1788  getsockopt(option_, &optval, &optlen);
1789  return optval;
1790  }
1791 
1792 #ifdef ZMQ_CPP11
1793  // Set integral socket option, e.g.
1794  // `socket.set(zmq::sockopt::linger, 0)`
1795  template <int Opt, class T, bool BoolUnit>
1796  void set(sockopt::integral_option<Opt, T, BoolUnit>, const T& val)
1797  {
1798  static_assert(std::is_integral<T>::value, "T must be integral");
1799  set_option(Opt, &val, sizeof val);
1800  }
1801 
1802  // Set integral socket option from boolean, e.g.
1803  // `socket.set(zmq::sockopt::immediate, false)`
1804  template <int Opt, class T>
1805  void set(sockopt::integral_option<Opt, T, true>, bool val)
1806  {
1807  static_assert(std::is_integral<T>::value, "T must be integral");
1808  T rep_val = val;
1809  set_option(Opt, &rep_val, sizeof rep_val);
1810  }
1811 
1812  // Set array socket option, e.g.
1813  // `socket.set(zmq::sockopt::plain_username, "foo123")`
1814  template <int Opt, int NullTerm>
1815  void set(sockopt::array_option<Opt, NullTerm>, const char* buf)
1816  {
1817  set_option(Opt, buf, std::strlen(buf));
1818  }
1819 
1820  // Set array socket option, e.g.
1821  // `socket.set(zmq::sockopt::routing_id, zmq::buffer(id))`
1822  template <int Opt, int NullTerm>
1823  void set(sockopt::array_option<Opt, NullTerm>, const_buffer buf)
1824  {
1825  set_option(Opt, buf.data(), buf.size());
1826  }
1827 
1828  // Set array socket option, e.g.
1829  // `socket.set(zmq::sockopt::routing_id, id_str)`
1830  template <int Opt, int NullTerm>
1831  void set(sockopt::array_option<Opt, NullTerm>, const std::string& buf)
1832  {
1833  set_option(Opt, buf.data(), buf.size());
1834  }
1835 
1836 #if CPPZMQ_HAS_STRING_VIEW
1837  // Set array socket option, e.g.
1838  // `socket.set(zmq::sockopt::routing_id, id_str)`
1839  template <int Opt, int NullTerm>
1840  void set(sockopt::array_option<Opt, NullTerm>, std::string_view buf)
1841  {
1842  set_option(Opt, buf.data(), buf.size());
1843  }
1844 #endif
1845 
1846  // Get scalar socket option, e.g.
1847  // `auto opt = socket.get(zmq::sockopt::linger)`
1848  template <int Opt, class T, bool BoolUnit>
1849  ZMQ_NODISCARD T get(sockopt::integral_option<Opt, T, BoolUnit>) const
1850  {
1851  static_assert(std::is_integral<T>::value, "T must be integral");
1852  T val;
1853  size_t size = sizeof val;
1854  get_option(Opt, &val, &size);
1855  assert(size == sizeof val);
1856  return val;
1857  }
1858 
1859  // Get array socket option, writes to buf, returns option size in bytes, e.g.
1860  // `size_t optsize = socket.get(zmq::sockopt::routing_id, zmq::buffer(id))`
1861  template <int Opt, int NullTerm>
1862  ZMQ_NODISCARD size_t get(sockopt::array_option<Opt, NullTerm>, mutable_buffer buf) const
1863  {
1864  size_t size = buf.size();
1865  get_option(Opt, buf.data(), &size);
1866  return size;
1867  }
1868 
1869  // Get array socket option as string (initializes the string buffer size to init_size)
1870  // e.g. `auto s = socket.get(zmq::sockopt::routing_id)` Note: removes the null character
1871  // from null-terminated string options, i.e. the string size excludes the null
1872  // character.
1873  template <int Opt, int NullTerm>
1874  ZMQ_NODISCARD std::string get(sockopt::array_option<Opt, NullTerm>,
1875  size_t init_size = 1024) const
1876  {
1877  if (NullTerm == 2 && init_size == 1024)
1878  {
1879  init_size = 41; // get as Z85 string
1880  }
1881  std::string str(init_size, '\0');
1882  size_t size = get(sockopt::array_option<Opt>{}, buffer(str));
1883  if (NullTerm == 1)
1884  {
1885  if (size > 0)
1886  {
1887  assert(str[size - 1] == '\0');
1888  --size;
1889  }
1890  }
1891  else if (NullTerm == 2)
1892  {
1893  assert(size == 32 || size == 41);
1894  if (size == 41)
1895  {
1896  assert(str[size - 1] == '\0');
1897  --size;
1898  }
1899  }
1900  str.resize(size);
1901  return str;
1902  }
1903 #endif
1904 
1905  void bind(std::string const& addr)
1906  {
1907  bind(addr.c_str());
1908  }
1909 
1910  void bind(const char* addr_)
1911  {
1912  int rc = zmq_bind(_handle, addr_);
1913  if (rc != 0)
1914  throw error_t();
1915  }
1916 
1917  void unbind(std::string const& addr)
1918  {
1919  unbind(addr.c_str());
1920  }
1921 
1922  void unbind(const char* addr_)
1923  {
1924  int rc = zmq_unbind(_handle, addr_);
1925  if (rc != 0)
1926  throw error_t();
1927  }
1928 
1929  void connect(std::string const& addr)
1930  {
1931  connect(addr.c_str());
1932  }
1933 
1934  void connect(const char* addr_)
1935  {
1936  int rc = zmq_connect(_handle, addr_);
1937  if (rc != 0)
1938  throw error_t();
1939  }
1940 
1941  void disconnect(std::string const& addr)
1942  {
1943  disconnect(addr.c_str());
1944  }
1945 
1946  void disconnect(const char* addr_)
1947  {
1948  int rc = zmq_disconnect(_handle, addr_);
1949  if (rc != 0)
1950  throw error_t();
1951  }
1952 
1953  bool connected() const ZMQ_NOTHROW
1954  {
1955  return (_handle != ZMQ_NULLPTR);
1956  }
1957 
1958  ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking a const_buffer and send_flags")
1959  size_t send(const void* buf_, size_t len_, int flags_ = 0)
1960  {
1961  int nbytes = zmq_send(_handle, buf_, len_, flags_);
1962  if (nbytes >= 0)
1963  return static_cast<size_t>(nbytes);
1964  if (zmq_errno() == EAGAIN)
1965  return 0;
1966  throw error_t();
1967  }
1968 
1969  ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags")
1970  bool send(message_t& msg_,
1971  int flags_ = 0) // default until removed
1972  {
1973  int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_);
1974  if (nbytes >= 0)
1975  return true;
1976  if (zmq_errno() == EAGAIN)
1977  return false;
1978  throw error_t();
1979  }
1980 
1981  template <typename T>
1982  ZMQ_CPP11_DEPRECATED("from 4.4.1, use send taking message_t or buffer (for contiguous "
1983  "ranges), and send_flags")
1984  bool send(T first, T last, int flags_ = 0)
1985  {
1987  int nbytes = zmq_msg_send(msg.handle(), _handle, flags_);
1988  if (nbytes >= 0)
1989  return true;
1990  if (zmq_errno() == EAGAIN)
1991  return false;
1992  throw error_t();
1993  }
1994 
1995 #ifdef ZMQ_HAS_RVALUE_REFS
1996  ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags")
1997  bool send(message_t&& msg_,
1998  int flags_ = 0) // default until removed
1999  {
2000 #ifdef ZMQ_CPP11
2001  return send(msg_, static_cast<send_flags>(flags_)).has_value();
2002 #else
2003  return send(msg_, flags_);
2004 #endif
2005  }
2006 #endif
2007 
2008 #ifdef ZMQ_CPP11
2009  send_result_t send(const_buffer buf, send_flags flags = send_flags::none)
2010  {
2011  const int nbytes = zmq_send(_handle, buf.data(), buf.size(), static_cast<int>(flags));
2012  if (nbytes >= 0)
2013  return static_cast<size_t>(nbytes);
2014  if (zmq_errno() == EAGAIN)
2015  return {};
2016  throw error_t();
2017  }
2018 
2019  send_result_t send(message_t& msg, send_flags flags)
2020  {
2021  int nbytes = zmq_msg_send(msg.handle(), _handle, static_cast<int>(flags));
2022  if (nbytes >= 0)
2023  return static_cast<size_t>(nbytes);
2024  if (zmq_errno() == EAGAIN)
2025  return {};
2026  throw error_t();
2027  }
2028 
2029  send_result_t send(message_t&& msg, send_flags flags)
2030  {
2031  return send(msg, flags);
2032  }
2033 #endif
2034 
2035  ZMQ_CPP11_DEPRECATED("from 4.3.1, use recv taking a mutable_buffer and recv_flags")
2036  size_t recv(void* buf_, size_t len_, int flags_ = 0)
2037  {
2038  int nbytes = zmq_recv(_handle, buf_, len_, flags_);
2039  if (nbytes >= 0)
2040  return static_cast<size_t>(nbytes);
2041  if (zmq_errno() == EAGAIN)
2042  return 0;
2043  throw error_t();
2044  }
2045 
2046  ZMQ_CPP11_DEPRECATED("from 4.3.1, use recv taking a reference to message_t and "
2047  "recv_flags")
2048  bool recv(message_t* msg_, int flags_ = 0)
2049  {
2050  int nbytes = zmq_msg_recv(msg_->handle(), _handle, flags_);
2051  if (nbytes >= 0)
2052  return true;
2053  if (zmq_errno() == EAGAIN)
2054  return false;
2055  throw error_t();
2056  }
2057 
2058 #ifdef ZMQ_CPP11
2060  recv_buffer_result_t recv(mutable_buffer buf, recv_flags flags = recv_flags::none)
2061  {
2062  const int nbytes = zmq_recv(_handle, buf.data(), buf.size(), static_cast<int>(flags));
2063  if (nbytes >= 0)
2064  {
2065  return recv_buffer_size{ (std::min)(static_cast<size_t>(nbytes), buf.size()),
2066  static_cast<size_t>(nbytes) };
2067  }
2068  if (zmq_errno() == EAGAIN)
2069  return {};
2070  throw error_t();
2071  }
2072 
2074  recv_result_t recv(message_t& msg, recv_flags flags = recv_flags::none)
2075  {
2076  const int nbytes = zmq_msg_recv(msg.handle(), _handle, static_cast<int>(flags));
2077  if (nbytes >= 0)
2078  {
2079  assert(msg.size() == static_cast<size_t>(nbytes));
2080  return static_cast<size_t>(nbytes);
2081  }
2082  if (zmq_errno() == EAGAIN)
2083  return {};
2084  throw error_t();
2085  }
2086 #endif
2087 
2088 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
2089  void join(const char* group)
2090  {
2091  int rc = zmq_join(_handle, group);
2092  if (rc != 0)
2093  throw error_t();
2094  }
2095 
2096  void leave(const char* group)
2097  {
2098  int rc = zmq_leave(_handle, group);
2099  if (rc != 0)
2100  throw error_t();
2101  }
2102 #endif
2103 
2104  ZMQ_NODISCARD void* handle() ZMQ_NOTHROW
2105  {
2106  return _handle;
2107  }
2108  ZMQ_NODISCARD const void* handle() const ZMQ_NOTHROW
2109  {
2110  return _handle;
2111  }
2112 
2113  ZMQ_EXPLICIT operator bool() const ZMQ_NOTHROW
2114  {
2115  return _handle != ZMQ_NULLPTR;
2116  }
2117  // note: non-const operator bool can be removed once
2118  // operator void* is removed from socket_t
2119  ZMQ_EXPLICIT operator bool() ZMQ_NOTHROW
2120  {
2121  return _handle != ZMQ_NULLPTR;
2122  }
2123 
2124 protected:
2125  void* _handle;
2126 
2127 private:
2128  void set_option(int option_, const void* optval_, size_t optvallen_)
2129  {
2130  int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_);
2131  if (rc != 0)
2132  throw error_t();
2133  }
2134 
2135  void get_option(int option_, void* optval_, size_t* optvallen_) const
2136  {
2137  int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_);
2138  if (rc != 0)
2139  throw error_t();
2140  }
2141 };
2142 } // namespace detail
2143 
2144 #ifdef ZMQ_CPP11
2145 enum class socket_type : int
2146 {
2147  req = ZMQ_REQ,
2148  rep = ZMQ_REP,
2149  dealer = ZMQ_DEALER,
2150  router = ZMQ_ROUTER,
2151  pub = ZMQ_PUB,
2152  sub = ZMQ_SUB,
2153  xpub = ZMQ_XPUB,
2154  xsub = ZMQ_XSUB,
2155  push = ZMQ_PUSH,
2156  pull = ZMQ_PULL,
2157 #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0)
2158  server = ZMQ_SERVER,
2159  client = ZMQ_CLIENT,
2160  radio = ZMQ_RADIO,
2161  dish = ZMQ_DISH,
2162 #endif
2163 #if ZMQ_VERSION_MAJOR >= 4
2164  stream = ZMQ_STREAM,
2165 #endif
2166  pair = ZMQ_PAIR
2167 };
2168 #endif
2169 
2171 {
2172  struct _private
2173  {
2174  }; // disabling use other than with from_handle
2176  {
2177  }
2178 };
2179 
2181 
2182 // A non-owning nullable reference to a socket.
2183 // The reference is invalidated on socket close or destruction.
2185 {
2186 public:
2188  {
2189  }
2190 #ifdef ZMQ_CPP11
2191  socket_ref(std::nullptr_t) ZMQ_NOTHROW : detail::socket_base()
2192  {
2193  }
2194 #endif
2196  {
2197  }
2198 };
2199 
2200 #ifdef ZMQ_CPP11
2201 inline bool operator==(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW
2202 {
2203  return sr.handle() == nullptr;
2204 }
2205 inline bool operator==(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW
2206 {
2207  return sr.handle() == nullptr;
2208 }
2209 inline bool operator!=(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW
2210 {
2211  return !(sr == nullptr);
2212 }
2213 inline bool operator!=(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW
2214 {
2215  return !(sr == nullptr);
2216 }
2217 #endif
2218 
2220 {
2221  return std::equal_to<void*>()(a.handle(), b.handle());
2222 }
2224 {
2225  return !(a == b);
2226 }
2228 {
2229  return std::less<void*>()(a.handle(), b.handle());
2230 }
2232 {
2233  return b < a;
2234 }
2236 {
2237  return !(a > b);
2238 }
2240 {
2241  return !(a < b);
2242 }
2243 
2244 } // namespace zmq
2245 
2246 #ifdef ZMQ_CPP11
2247 namespace std
2248 {
2249 template <>
2250 struct hash<zmq::socket_ref>
2251 {
2252  size_t operator()(zmq::socket_ref sr) const ZMQ_NOTHROW
2253  {
2254  return hash<void*>()(sr.handle());
2255  }
2256 };
2257 } // namespace std
2258 #endif
2259 
2260 namespace zmq
2261 {
2263 {
2264  friend class monitor_t;
2265 
2266 public:
2268  {
2269  }
2270 
2271  socket_t(context_t& context_, int type_)
2272  : detail::socket_base(zmq_socket(context_.handle(), type_)), ctxptr(context_.handle())
2273  {
2274  if (_handle == ZMQ_NULLPTR)
2275  throw error_t();
2276  }
2277 
2278 #ifdef ZMQ_CPP11
2279  socket_t(context_t& context_, socket_type type_)
2280  : socket_t(context_, static_cast<int>(type_))
2281  {
2282  }
2283 #endif
2284 
2285 #ifdef ZMQ_HAS_RVALUE_REFS
2286  socket_t(socket_t&& rhs) ZMQ_NOTHROW : detail::socket_base(rhs._handle),
2287  ctxptr(rhs.ctxptr)
2288  {
2289  rhs._handle = ZMQ_NULLPTR;
2290  rhs.ctxptr = ZMQ_NULLPTR;
2291  }
2293  {
2294  close();
2295  std::swap(_handle, rhs._handle);
2296  std::swap(ctxptr, rhs.ctxptr);
2297  return *this;
2298  }
2299 #endif
2300 
2302  {
2303  close();
2304  }
2305 
2306  operator void*() ZMQ_NOTHROW
2307  {
2308  return _handle;
2309  }
2310 
2311  operator void const*() const ZMQ_NOTHROW
2312  {
2313  return _handle;
2314  }
2315 
2317  {
2318  if (_handle == ZMQ_NULLPTR)
2319  // already closed
2320  return;
2321  int rc = zmq_close(_handle);
2322  ZMQ_ASSERT(rc == 0);
2323  _handle = ZMQ_NULLPTR;
2324  ctxptr = ZMQ_NULLPTR;
2325  }
2326 
2328  {
2329  std::swap(_handle, other._handle);
2330  std::swap(ctxptr, other.ctxptr);
2331  }
2332 
2334  {
2335  return socket_ref(from_handle, _handle);
2336  }
2337 
2338 private:
2339  void* ctxptr;
2340 
2343 
2344  // used by monitor_t
2345  socket_t(void* context_, int type_)
2346  : detail::socket_base(zmq_socket(context_, type_)), ctxptr(context_)
2347  {
2348  if (_handle == ZMQ_NULLPTR)
2349  throw error_t();
2350  if (ctxptr == ZMQ_NULLPTR)
2351  throw error_t();
2352  }
2353 };
2354 
2355 inline void swap(socket_t& a, socket_t& b) ZMQ_NOTHROW
2356 {
2357  a.swap(b);
2358 }
2359 
2360 ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects")
2361 inline void proxy(void* frontend, void* backend, void* capture)
2362 {
2363  int rc = zmq_proxy(frontend, backend, capture);
2364  if (rc != 0)
2365  throw error_t();
2366 }
2367 
2368 inline void proxy(socket_ref frontend, socket_ref backend,
2369  socket_ref capture = socket_ref())
2370 {
2371  int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle());
2372  if (rc != 0)
2373  throw error_t();
2374 }
2375 
2376 #ifdef ZMQ_HAS_PROXY_STEERABLE
2377 ZMQ_DEPRECATED("from 4.3.1, use proxy_steerable taking socket_t objects")
2378 inline void proxy_steerable(void* frontend, void* backend, void* capture, void* control)
2379 {
2380  int rc = zmq_proxy_steerable(frontend, backend, capture, control);
2381  if (rc != 0)
2382  throw error_t();
2383 }
2384 
2385 inline void proxy_steerable(socket_ref frontend, socket_ref backend, socket_ref capture,
2386  socket_ref control)
2387 {
2388  int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(), capture.handle(),
2389  control.handle());
2390  if (rc != 0)
2391  throw error_t();
2392 }
2393 #endif
2394 
2396 {
2397 public:
2399  {
2400  }
2401 
2402  virtual ~monitor_t()
2403  {
2404  close();
2405  }
2406 
2407 #ifdef ZMQ_HAS_RVALUE_REFS
2409  {
2410  std::swap(_socket, rhs._socket);
2411  std::swap(_monitor_socket, rhs._monitor_socket);
2412  }
2413 
2415  {
2416  close();
2417  _socket = socket_ref();
2418  std::swap(_socket, rhs._socket);
2419  std::swap(_monitor_socket, rhs._monitor_socket);
2420  return *this;
2421  }
2422 #endif
2423 
2424  void monitor(socket_t& socket, std::string const& addr, int events = ZMQ_EVENT_ALL)
2425  {
2426  monitor(socket, addr.c_str(), events);
2427  }
2428 
2429  void monitor(socket_t& socket, const char* addr_, int events = ZMQ_EVENT_ALL)
2430  {
2431  init(socket, addr_, events);
2432  while (true)
2433  {
2434  check_event(-1);
2435  }
2436  }
2437 
2438  void init(socket_t& socket, std::string const& addr, int events = ZMQ_EVENT_ALL)
2439  {
2440  init(socket, addr.c_str(), events);
2441  }
2442 
2443  void init(socket_t& socket, const char* addr_, int events = ZMQ_EVENT_ALL)
2444  {
2445  int rc = zmq_socket_monitor(socket.handle(), addr_, events);
2446  if (rc != 0)
2447  throw error_t();
2448 
2449  _socket = socket;
2450  _monitor_socket = socket_t(socket.ctxptr, ZMQ_PAIR);
2451  _monitor_socket.connect(addr_);
2452 
2454  }
2455 
2456  bool check_event(int timeout = 0)
2457  {
2459 
2460  zmq_msg_t eventMsg;
2461  zmq_msg_init(&eventMsg);
2462 
2463  zmq::pollitem_t items[] = {
2464  { _monitor_socket.handle(), 0, ZMQ_POLLIN, 0 },
2465  };
2466 
2467  zmq::poll(&items[0], 1, timeout);
2468 
2469  if (items[0].revents & ZMQ_POLLIN)
2470  {
2471  int rc = zmq_msg_recv(&eventMsg, _monitor_socket.handle(), 0);
2472  if (rc == -1 && zmq_errno() == ETERM)
2473  return false;
2474  assert(rc != -1);
2475  }
2476  else
2477  {
2478  zmq_msg_close(&eventMsg);
2479  return false;
2480  }
2481 
2482 #if ZMQ_VERSION_MAJOR >= 4
2483  const char* data = static_cast<const char*>(zmq_msg_data(&eventMsg));
2484  zmq_event_t msgEvent;
2485  memcpy(&msgEvent.event, data, sizeof(uint16_t));
2486  data += sizeof(uint16_t);
2487  memcpy(&msgEvent.value, data, sizeof(int32_t));
2488  zmq_event_t* event = &msgEvent;
2489 #else
2490  zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data(&eventMsg));
2491 #endif
2492 
2493 #ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT
2494  zmq_msg_t addrMsg;
2495  zmq_msg_init(&addrMsg);
2496  int rc = zmq_msg_recv(&addrMsg, _monitor_socket.handle(), 0);
2497  if (rc == -1 && zmq_errno() == ETERM)
2498  {
2499  zmq_msg_close(&eventMsg);
2500  return false;
2501  }
2502 
2503  assert(rc != -1);
2504  const char* str = static_cast<const char*>(zmq_msg_data(&addrMsg));
2505  std::string address(str, str + zmq_msg_size(&addrMsg));
2506  zmq_msg_close(&addrMsg);
2507 #else
2508  // Bit of a hack, but all events in the zmq_event_t union have the same layout so this
2509  // will work for all event types.
2510  std::string address = event->data.connected.addr;
2511 #endif
2512 
2513 #ifdef ZMQ_EVENT_MONITOR_STOPPED
2514  if (event->event == ZMQ_EVENT_MONITOR_STOPPED)
2515  {
2516  zmq_msg_close(&eventMsg);
2517  return false;
2518  }
2519 
2520 #endif
2521 
2522  switch (event->event)
2523  {
2524  case ZMQ_EVENT_CONNECTED:
2525  on_event_connected(*event, address.c_str());
2526  break;
2527  case ZMQ_EVENT_CONNECT_DELAYED:
2528  on_event_connect_delayed(*event, address.c_str());
2529  break;
2530  case ZMQ_EVENT_CONNECT_RETRIED:
2531  on_event_connect_retried(*event, address.c_str());
2532  break;
2533  case ZMQ_EVENT_LISTENING:
2534  on_event_listening(*event, address.c_str());
2535  break;
2536  case ZMQ_EVENT_BIND_FAILED:
2537  on_event_bind_failed(*event, address.c_str());
2538  break;
2539  case ZMQ_EVENT_ACCEPTED:
2540  on_event_accepted(*event, address.c_str());
2541  break;
2542  case ZMQ_EVENT_ACCEPT_FAILED:
2543  on_event_accept_failed(*event, address.c_str());
2544  break;
2545  case ZMQ_EVENT_CLOSED:
2546  on_event_closed(*event, address.c_str());
2547  break;
2548  case ZMQ_EVENT_CLOSE_FAILED:
2549  on_event_close_failed(*event, address.c_str());
2550  break;
2551  case ZMQ_EVENT_DISCONNECTED:
2552  on_event_disconnected(*event, address.c_str());
2553  break;
2554 #ifdef ZMQ_BUILD_DRAFT_API
2555 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
2556  case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL:
2557  on_event_handshake_failed_no_detail(*event, address.c_str());
2558  break;
2559  case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL:
2560  on_event_handshake_failed_protocol(*event, address.c_str());
2561  break;
2562  case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH:
2563  on_event_handshake_failed_auth(*event, address.c_str());
2564  break;
2565  case ZMQ_EVENT_HANDSHAKE_SUCCEEDED:
2566  on_event_handshake_succeeded(*event, address.c_str());
2567  break;
2568 #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1)
2569  case ZMQ_EVENT_HANDSHAKE_FAILED:
2570  on_event_handshake_failed(*event, address.c_str());
2571  break;
2572  case ZMQ_EVENT_HANDSHAKE_SUCCEED:
2573  on_event_handshake_succeed(*event, address.c_str());
2574  break;
2575 #endif
2576 #endif
2577  default:
2578  on_event_unknown(*event, address.c_str());
2579  break;
2580  }
2581  zmq_msg_close(&eventMsg);
2582 
2583  return true;
2584  }
2585 
2586 #ifdef ZMQ_EVENT_MONITOR_STOPPED
2587  void abort()
2588  {
2589  if (_socket)
2590  zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0);
2591 
2592  _socket = socket_ref();
2593  }
2594 #endif
2595  virtual void on_monitor_started()
2596  {
2597  }
2598  virtual void on_event_connected(const zmq_event_t& event_, const char* addr_)
2599  {
2600  (void)event_;
2601  (void)addr_;
2602  }
2603  virtual void on_event_connect_delayed(const zmq_event_t& event_, const char* addr_)
2604  {
2605  (void)event_;
2606  (void)addr_;
2607  }
2608  virtual void on_event_connect_retried(const zmq_event_t& event_, const char* addr_)
2609  {
2610  (void)event_;
2611  (void)addr_;
2612  }
2613  virtual void on_event_listening(const zmq_event_t& event_, const char* addr_)
2614  {
2615  (void)event_;
2616  (void)addr_;
2617  }
2618  virtual void on_event_bind_failed(const zmq_event_t& event_, const char* addr_)
2619  {
2620  (void)event_;
2621  (void)addr_;
2622  }
2623  virtual void on_event_accepted(const zmq_event_t& event_, const char* addr_)
2624  {
2625  (void)event_;
2626  (void)addr_;
2627  }
2628  virtual void on_event_accept_failed(const zmq_event_t& event_, const char* addr_)
2629  {
2630  (void)event_;
2631  (void)addr_;
2632  }
2633  virtual void on_event_closed(const zmq_event_t& event_, const char* addr_)
2634  {
2635  (void)event_;
2636  (void)addr_;
2637  }
2638  virtual void on_event_close_failed(const zmq_event_t& event_, const char* addr_)
2639  {
2640  (void)event_;
2641  (void)addr_;
2642  }
2643  virtual void on_event_disconnected(const zmq_event_t& event_, const char* addr_)
2644  {
2645  (void)event_;
2646  (void)addr_;
2647  }
2648 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
2650  const char* addr_)
2651  {
2652  (void)event_;
2653  (void)addr_;
2654  }
2656  const char* addr_)
2657  {
2658  (void)event_;
2659  (void)addr_;
2660  }
2661  virtual void on_event_handshake_failed_auth(const zmq_event_t& event_,
2662  const char* addr_)
2663  {
2664  (void)event_;
2665  (void)addr_;
2666  }
2667  virtual void on_event_handshake_succeeded(const zmq_event_t& event_, const char* addr_)
2668  {
2669  (void)event_;
2670  (void)addr_;
2671  }
2672 #elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1)
2673  virtual void on_event_handshake_failed(const zmq_event_t& event_, const char* addr_)
2674  {
2675  (void)event_;
2676  (void)addr_;
2677  }
2678  virtual void on_event_handshake_succeed(const zmq_event_t& event_, const char* addr_)
2679  {
2680  (void)event_;
2681  (void)addr_;
2682  }
2683 #endif
2684  virtual void on_event_unknown(const zmq_event_t& event_, const char* addr_)
2685  {
2686  (void)event_;
2687  (void)addr_;
2688  }
2689 
2690 private:
2693 
2696 
2698  {
2699  if (_socket)
2700  zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0);
2702  }
2703 };
2704 
2705 #if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
2706 
2707 // polling events
2708 enum class event_flags : short
2709 {
2710  none = 0,
2711  pollin = ZMQ_POLLIN,
2712  pollout = ZMQ_POLLOUT,
2713  pollerr = ZMQ_POLLERR,
2714  pollpri = ZMQ_POLLPRI
2715 };
2716 
2717 constexpr event_flags operator|(event_flags a, event_flags b) noexcept
2718 {
2719  return detail::enum_bit_or(a, b);
2720 }
2721 constexpr event_flags operator&(event_flags a, event_flags b) noexcept
2722 {
2723  return detail::enum_bit_and(a, b);
2724 }
2725 constexpr event_flags operator^(event_flags a, event_flags b) noexcept
2726 {
2727  return detail::enum_bit_xor(a, b);
2728 }
2729 constexpr event_flags operator~(event_flags a) noexcept
2730 {
2731  return detail::enum_bit_not(a);
2732 }
2733 
2734 struct no_user_data;
2735 
2736 // layout compatible with zmq_poller_event_t
2737 template <class T = no_user_data>
2738 struct poller_event
2739 {
2740  socket_ref socket;
2741 #ifdef _WIN32
2742  SOCKET fd;
2743 #else
2744  int fd;
2745 #endif
2746  T* user_data;
2747  event_flags events;
2748 };
2749 
2750 template <typename T = no_user_data>
2751 class poller_t
2752 {
2753 public:
2754  using event_type = poller_event<T>;
2755 
2756  poller_t() : poller_ptr(zmq_poller_new())
2757  {
2758  if (!poller_ptr)
2759  throw error_t();
2760  }
2761 
2762  template <typename Dummy = void,
2763  typename = typename std::enable_if<!std::is_same<T, no_user_data>::value,
2764  Dummy>::type>
2765  void add(zmq::socket_ref socket, event_flags events, T* user_data)
2766  {
2767  add_impl(socket, events, user_data);
2768  }
2769 
2770  void add(zmq::socket_ref socket, event_flags events)
2771  {
2772  add_impl(socket, events, nullptr);
2773  }
2774 
2775  void remove(zmq::socket_ref socket)
2776  {
2777  if (0 != zmq_poller_remove(poller_ptr.get(), socket.handle()))
2778  {
2779  throw error_t();
2780  }
2781  }
2782 
2783  void modify(zmq::socket_ref socket, event_flags events)
2784  {
2785  if (0 !=
2786  zmq_poller_modify(poller_ptr.get(), socket.handle(), static_cast<short>(events)))
2787  {
2788  throw error_t();
2789  }
2790  }
2791 
2792  size_t wait_all(std::vector<event_type>& poller_events,
2793  const std::chrono::milliseconds timeout)
2794  {
2795  int rc = zmq_poller_wait_all(
2796  poller_ptr.get(), reinterpret_cast<zmq_poller_event_t*>(poller_events.data()),
2797  static_cast<int>(poller_events.size()), static_cast<long>(timeout.count()));
2798  if (rc > 0)
2799  return static_cast<size_t>(rc);
2800 
2801 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3)
2802  if (zmq_errno() == EAGAIN)
2803 #else
2804  if (zmq_errno() == ETIMEDOUT)
2805 #endif
2806  return 0;
2807 
2808  throw error_t();
2809  }
2810 
2811 private:
2812  struct destroy_poller_t
2813  {
2814  void operator()(void* ptr) noexcept
2815  {
2816  int rc = zmq_poller_destroy(&ptr);
2817  ZMQ_ASSERT(rc == 0);
2818  }
2819  };
2820 
2821  std::unique_ptr<void, destroy_poller_t> poller_ptr;
2822 
2823  void add_impl(zmq::socket_ref socket, event_flags events, T* user_data)
2824  {
2825  if (0 != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data,
2826  static_cast<short>(events)))
2827  {
2828  throw error_t();
2829  }
2830  }
2831 };
2832 #endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
2833 
2834 inline std::ostream& operator<<(std::ostream& os, const message_t& msg)
2835 {
2836  return os << msg.str();
2837 }
2838 
2839 } // namespace zmq
2840 
2841 #endif // __ZMQ_HPP_INCLUDED__
zmq_event_t
Definition: zmq.hpp:202
zmq::monitor_t::on_monitor_started
virtual void on_monitor_started()
Definition: zmq.hpp:2595
zmq::context_t::ptr
void * ptr
Definition: zmq.hpp:936
zmq::operator<
bool operator<(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2227
nlohmann::detail::hash
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5097
zmq::message_t::handle
const ZMQ_NODISCARD zmq_msg_t * handle() const ZMQ_NOTHROW
Definition: zmq.hpp:739
ZMQ_NODISCARD
#define ZMQ_NODISCARD
Definition: zmq.hpp:75
detail::operator*
FMT_CONSTEXPR auto operator*(fp x, fp y) -> fp
Definition: format.h:1701
detail::to_string_view
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
Definition: core.h:534
detail::first
auto first(const T &value, const Tail &...) -> const T &
Definition: compile.h:60
zmq::swap
void swap(message_t &a, message_t &b) ZMQ_NOTHROW
Definition: zmq.hpp:754
zmq::poll
int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_=-1)
Definition: zmq.hpp:299
nlohmann::detail::value_t
value_t
the JSON type enumeration
Definition: json.hpp:129
zmq::monitor_t::on_event_handshake_failed_auth
virtual void on_event_handshake_failed_auth(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2661
zmq::message_t::move
void move(message_t &msg_)
Definition: zmq.hpp:544
zmq::message_t
Definition: zmq.hpp:389
mqtt_test.client
client
Definition: mqtt_test.py:10
zmq::from_handle_t
Definition: zmq.hpp:2170
zmq::proxy
void proxy(void *frontend, void *backend, void *capture)
Definition: zmq.hpp:2361
detail::copy
auto copy(const Range &range, OutputIt out) -> OutputIt
Definition: ranges.h:22
zmq::operator>=
bool operator>=(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2239
zmq::monitor_t::monitor
void monitor(socket_t &socket, std::string const &addr, int events=ZMQ_EVENT_ALL)
Definition: zmq.hpp:2424
zmq::detail::socket_base::connected
bool connected() const ZMQ_NOTHROW
Definition: zmq.hpp:1953
zmq::socket_t::swap
void swap(socket_t &other) ZMQ_NOTHROW
Definition: zmq.hpp:2327
zmq::context_t::context_t
context_t()
Definition: zmq.hpp:807
zmq::monitor_t::on_event_handshake_failed_no_detail
virtual void on_event_handshake_failed_no_detail(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2649
backward::ColorMode::type
type
Definition: backward.hpp:3600
zmq::operator>
bool operator>(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2231
zmq::monitor_t::on_event_unknown
virtual void on_event_unknown(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2684
zmq::from_handle_t::from_handle_t
ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private) ZMQ_NOTHROW
Definition: zmq.hpp:2175
zmq::monitor_t::on_event_bind_failed
virtual void on_event_bind_failed(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2618
zmq::pollitem_t
zmq_pollitem_t pollitem_t
Definition: zmq.hpp:275
nonstd::span_lite::size_t
span_CONFIG_SIZE_TYPE size_t
Definition: span.hpp:576
zmq::message_t::copy
void copy(message_t const *msg_)
Definition: zmq.hpp:552
zmq::monitor_t::~monitor_t
virtual ~monitor_t()
Definition: zmq.hpp:2402
zmq::message_t::to_string
std::string to_string() const
Definition: zmq.hpp:668
ZMQ_DELETED_FUNCTION
#define ZMQ_DELETED_FUNCTION
Definition: zmq.hpp:174
zmq::context_t::operator=
void operator=(const context_t &) ZMQ_DELETED_FUNCTION
zmq::context_t::setctxopt
int setctxopt(int option_, int optval_)
Definition: zmq.hpp:846
zmq::message_t::handle
ZMQ_NODISCARD zmq_msg_t * handle() ZMQ_NOTHROW
Definition: zmq.hpp:735
literals
Definition: xchar.h:71
zmq::socket_t
Definition: zmq.hpp:2262
zmq::context_t::swap
void swap(context_t &other) ZMQ_NOTHROW
Definition: zmq.hpp:930
is_range
Definition: ranges.h:378
zmq::error_t::errnum
int errnum
Definition: zmq.hpp:296
zmq::message_t::data
void * data() ZMQ_NOTHROW
Definition: zmq.hpp:572
zmq::socket_t::socket_t
socket_t(void *context_, int type_)
Definition: zmq.hpp:2345
zmq::operator!=
bool operator!=(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2223
zmq::monitor_t::on_event_disconnected
virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2643
zmq::monitor_t::monitor_t
monitor_t()
Definition: zmq.hpp:2398
zmq::message_t::data
const void * data() const ZMQ_NOTHROW
Definition: zmq.hpp:577
zmq::from_handle
ZMQ_CONSTEXPR_VAR from_handle_t from_handle
Definition: zmq.hpp:2180
zmq::detail::socket_base::ZMQ_CPP11_DEPRECATED
ZMQ_CPP11_DEPRECATED("from 4.4.1, use send taking message_t or buffer (for contiguous " "ranges), and send_flags") bool send(T first
zmq::monitor_t::on_event_accept_failed
virtual void on_event_accept_failed(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2628
zmq::detail::socket_base::bind
void bind(const char *addr_)
Definition: zmq.hpp:1910
zmq::detail::socket_base::setsockopt
void setsockopt(int option_, T const &optval)
Definition: zmq.hpp:1761
zmq::monitor_t::monitor
void monitor(socket_t &socket, const char *addr_, int events=ZMQ_EVENT_ALL)
Definition: zmq.hpp:2429
zmq::message_t::more
bool more() const ZMQ_NOTHROW
Definition: zmq.hpp:566
zmq::monitor_t::on_event_listening
virtual void on_event_listening(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2613
ZMQ_CONSTEXPR_VAR
#define ZMQ_CONSTEXPR_VAR
Definition: zmq.hpp:92
zmq::message_t::swap
void swap(message_t &other) ZMQ_NOTHROW
Definition: zmq.hpp:729
nonstd::span_lite::std11::false_type
integral_constant< bool, false > false_type
Definition: span.hpp:657
ZMQ_ASSERT
#define ZMQ_ASSERT(expression)
Definition: zmq.hpp:217
detail
Definition: args.h:19
zmq::detail::socket_base::unbind
void unbind(std::string const &addr)
Definition: zmq.hpp:1917
zmq::monitor_t::check_event
bool check_event(int timeout=0)
Definition: zmq.hpp:2456
zmq::error_t::error_t
error_t() ZMQ_NOTHROW
Definition: zmq.hpp:280
zmq::message_t::message_t
message_t(size_t size_)
Definition: zmq.hpp:398
mqtt_test_proto.msg
msg
Definition: mqtt_test_proto.py:43
zmq::detail::socket_base::send
size_t send(const void *buf_, size_t len_, int flags_=0)
Definition: zmq.hpp:1959
zmq::message_t::equal
bool equal(const message_t *other) const ZMQ_NOTHROW
Definition: zmq.hpp:605
zmq::detail::socket_base::socket_base
ZMQ_EXPLICIT socket_base(void *handle) ZMQ_NOTHROW
Definition: zmq.hpp:1755
zmq::socket_t::operator=
void operator=(const socket_t &) ZMQ_DELETED_FUNCTION
nonstd::span_lite::std11::true_type
integral_constant< bool, true > true_type
Definition: span.hpp:656
zmq::context_t::close
void close() ZMQ_NOTHROW
Definition: zmq.hpp:880
zmq::socket_ref
Definition: zmq.hpp:2184
zmq::detail::socket_base::disconnect
void disconnect(const char *addr_)
Definition: zmq.hpp:1946
zmq::operator<<
std::ostream & operator<<(std::ostream &os, const message_t &msg)
Definition: zmq.hpp:2834
zmq::message_t::message_t
message_t(ForwardIter first, ForwardIter last)
Definition: zmq.hpp:406
zmq::monitor_t::init
void init(socket_t &socket, std::string const &addr, int events=ZMQ_EVENT_ALL)
Definition: zmq.hpp:2438
zmq
Definition: zmq.hpp:222
zmq::context_t
Definition: zmq.hpp:804
ZMQ_OVERRIDE
#define ZMQ_OVERRIDE
Definition: zmq.hpp:89
zmq::detail::socket_base::set_option
void set_option(int option_, const void *optval_, size_t optvallen_)
Definition: zmq.hpp:2128
zmq::message_t::get
int get(int property_)
Definition: zmq.hpp:622
zmq_event_t::event
uint16_t event
Definition: zmq.hpp:204
zmq::context_t::handle
ZMQ_NODISCARD void * handle() ZMQ_NOTHROW
Definition: zmq.hpp:919
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
sol::operator&
constexpr automagic_flags operator&(automagic_flags left, automagic_flags right) noexcept
Definition: sol.hpp:8673
zmq::detail::socket_base::last
T last
Definition: zmq.hpp:1984
zmq::monitor_t::on_event_handshake_failed_protocol
virtual void on_event_handshake_failed_protocol(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2655
nlohmann::detail::void_t
typename make_void< Ts... >::type void_t
Definition: json.hpp:2242
zmq::version
void version(int *major_, int *minor_, int *patch_)
Definition: zmq.hpp:360
zmq::error_t::num
int num() const ZMQ_NOTHROW
Definition: zmq.hpp:290
zmq::operator==
bool operator==(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2219
zmq::message_t::operator!=
bool operator!=(const message_t &other) const ZMQ_NOTHROW
Definition: zmq.hpp:616
zmq::monitor_t::_socket
socket_ref _socket
Definition: zmq.hpp:2694
zmq::socket_ref::socket_ref
socket_ref(from_handle_t, void *handle) ZMQ_NOTHROW
Definition: zmq.hpp:2195
sol::operator+
stack_iterator< proxy_t, is_const > operator+(typename stack_iterator< proxy_t, is_const >::difference_type n, const stack_iterator< proxy_t, is_const > &r)
Definition: sol.hpp:17108
zmq::message_t::gets
const char * gets(const char *property_)
Definition: zmq.hpp:632
zmq::socket_t::close
void close() ZMQ_NOTHROW
Definition: zmq.hpp:2316
std::swap
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:21884
zmq::monitor_t::on_event_close_failed
virtual void on_event_close_failed(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2638
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
zmq::context_t::shutdown
void shutdown() ZMQ_NOTHROW
Definition: zmq.hpp:898
zmq::monitor_t::on_event_closed
virtual void on_event_closed(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2633
nlohmann::detail::parse_event_t::value
@ value
the parser finished reading a JSON value
ZMQ_CPP11_DEPRECATED
#define ZMQ_CPP11_DEPRECATED(msg)
Definition: zmq.hpp:93
zmq::proxy_steerable
void proxy_steerable(void *frontend, void *backend, void *capture, void *control)
Definition: zmq.hpp:2378
zmq::message_t::rebuild
void rebuild()
Definition: zmq.hpp:496
zmq::socket_t::socket_t
socket_t() ZMQ_NOTHROW
Definition: zmq.hpp:2267
ZMQ_NOTHROW
#define ZMQ_NOTHROW
Definition: zmq.hpp:87
zmq::monitor_t
Definition: zmq.hpp:2395
zmq::monitor_t::on_event_handshake_succeeded
virtual void on_event_handshake_succeeded(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2667
zmq::detail::socket_base::socket_base
socket_base() ZMQ_NOTHROW
Definition: zmq.hpp:1752
zmq::message_t::message_t
message_t() ZMQ_NOTHROW
Definition: zmq.hpp:392
zmq::from_handle_t::_private
Definition: zmq.hpp:2172
zmq::message_t::rebuild
void rebuild(const void *data_, size_t size_)
Definition: zmq.hpp:515
zmq::message_t::message_t
message_t(const void *data_, size_t size_)
Definition: zmq.hpp:419
ZMQ_CONSTEXPR_FN
#define ZMQ_CONSTEXPR_FN
Definition: zmq.hpp:91
string_view
basic_string_view< char > string_view
Definition: core.h:518
zmq::free_fn
zmq_free_fn free_fn
Definition: zmq.hpp:274
ZMQ_EXPLICIT
#define ZMQ_EXPLICIT
Definition: zmq.hpp:88
zmq::monitor_t::on_event_connect_retried
virtual void on_event_connect_retried(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2608
socket_type
int socket_type
zmq::monitor_t::init
void init(socket_t &socket, const char *addr_, int events=ZMQ_EVENT_ALL)
Definition: zmq.hpp:2443
zmq::detail::socket_base::getsockopt
void getsockopt(int option_, void *optval_, size_t *optvallen_) const
Definition: zmq.hpp:1775
set
ROSCPP_DECL void set(const std::string &key, bool b)
zmq::detail::socket_base::connect
void connect(const char *addr_)
Definition: zmq.hpp:1934
udp_client.int
int
Definition: udp_client.py:11
zmq::operator<=
bool operator<=(socket_ref a, socket_ref b) ZMQ_NOTHROW
Definition: zmq.hpp:2235
nlohmann::detail::range_value_t
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3579
assert
#define assert(condition)
Definition: lz4.c:271
zmq::socket_t::socket_t
socket_t(context_t &context_, int type_)
Definition: zmq.hpp:2271
sol::detail::none
@ none
Definition: sol.hpp:7745
sol::operator|
constexpr automagic_flags operator|(automagic_flags left, automagic_flags right) noexcept
Definition: sol.hpp:8668
zmq::detail::socket_base::flags_
T int flags_
Definition: zmq.hpp:1984
zmq::detail::socket_base
Definition: zmq.hpp:1749
std
zmq::detail::socket_base::get_option
void get_option(int option_, void *optval_, size_t *optvallen_) const
Definition: zmq.hpp:2135
zmq::monitor_t::on_event_connected
virtual void on_event_connected(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2598
C
#define C(name, bit)
Definition: zstd.c:4811
sol::stack::remove
void remove(lua_State *L_, int rawindex, int count)
Definition: sol.hpp:9945
zmq::detail::socket_base::disconnect
void disconnect(std::string const &addr)
Definition: zmq.hpp:1941
zmq::detail::socket_base::connect
void connect(std::string const &addr)
Definition: zmq.hpp:1929
zmq::message_t::data
T * data() ZMQ_NOTHROW
Definition: zmq.hpp:593
nlohmann::detail::get
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4451
zmq::detail::socket_base::bind
void bind(std::string const &addr)
Definition: zmq.hpp:1905
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
zmq::message_t::copy
void copy(message_t &msg_)
Definition: zmq.hpp:559
zmq::message_t::rebuild
void rebuild(size_t size_)
Definition: zmq.hpp:505
zmq::message_t::str
std::string str() const
Definition: zmq.hpp:686
zmq::socket_t::~socket_t
~socket_t() ZMQ_NOTHROW
Definition: zmq.hpp:2301
zmq::message_t::empty
ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW
Definition: zmq.hpp:587
zmq::message_t::operator==
bool operator==(const message_t &other) const ZMQ_NOTHROW
Definition: zmq.hpp:610
zmq::error_t::error_t
error_t(int err) ZMQ_NOTHROW
Definition: zmq.hpp:283
zmq::message_t::operator=
void operator=(const message_t &) ZMQ_DELETED_FUNCTION
zmq::socket_ref::socket_ref
socket_ref() ZMQ_NOTHROW
Definition: zmq.hpp:2187
ZMQ_NULLPTR
#define ZMQ_NULLPTR
Definition: zmq.hpp:90
zmq::monitor_t::close
void close() ZMQ_NOTHROW
Definition: zmq.hpp:2697
zmq::monitor_t::on_event_accepted
virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2623
zmq::context_t::~context_t
~context_t() ZMQ_NOTHROW
Definition: zmq.hpp:840
zmq::socket_t::ctxptr
void * ctxptr
Definition: zmq.hpp:2339
zmq::context_t::context_t
context_t(int io_threads_, int max_sockets_=ZMQ_MAX_SOCKETS_DFLT)
Definition: zmq.hpp:814
zmq::monitor_t::on_event_connect_delayed
virtual void on_event_connect_delayed(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2603
zmq::detail::socket_base::unbind
void unbind(const char *addr_)
Definition: zmq.hpp:1922
zmq::message_t::msg
zmq_msg_t msg
Definition: zmq.hpp:746
zmq_event_t::value
int32_t value
Definition: zmq.hpp:205
zmq::message_t::move
void move(message_t const *msg_)
Definition: zmq.hpp:537
zmq::message_t::size
size_t size() const ZMQ_NOTHROW
Definition: zmq.hpp:582
zmq::error_t::what
virtual const char * what() const ZMQ_NOTHROW ZMQ_OVERRIDE
Definition: zmq.hpp:286
zmq::message_t::data
T const * data() const ZMQ_NOTHROW
Definition: zmq.hpp:599
join
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Definition: format.h:4280
zmq::context_t::getctxopt
int getctxopt(int option_)
Definition: zmq.hpp:854
zmq::message_t::~message_t
~message_t() ZMQ_NOTHROW
Definition: zmq.hpp:490
sol::stack::push
int push(lua_State *L, T &&t, Args &&... args)
Definition: sol.hpp:11746
zmq::message_t::rebuild
void rebuild(void *data_, size_t size_, free_fn *ffn_, void *hint_=ZMQ_NULLPTR)
Definition: zmq.hpp:526
zmq::error_t
Definition: zmq.hpp:277
sol::detail::ptr
T * ptr(T &val)
Definition: sol.hpp:2106
zmq::message_t::message_t
message_t(void *data_, size_t size_, free_fn *ffn_, void *hint_=ZMQ_NULLPTR)
Definition: zmq.hpp:432
zmq::monitor_t::operator=
void operator=(const monitor_t &) ZMQ_DELETED_FUNCTION
zmq::monitor_t::_monitor_socket
socket_t _monitor_socket
Definition: zmq.hpp:2695


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:48