zmq.hpp 79 KB

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