zmq.hpp 75 KB

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