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


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Dec 13 2024 03:19:17