buffer.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include <catch.hpp>
  2. #include <zmq.hpp>
  3. #ifdef ZMQ_CPP17
  4. static_assert(std::is_nothrow_swappable_v<zmq::const_buffer>);
  5. static_assert(std::is_nothrow_swappable_v<zmq::mutable_buffer>);
  6. static_assert(std::is_trivially_copyable_v<zmq::const_buffer>);
  7. static_assert(std::is_trivially_copyable_v<zmq::mutable_buffer>);
  8. #endif
  9. #ifdef ZMQ_CPP11
  10. using BT = int16_t;
  11. TEST_CASE("buffer default ctor", "[buffer]")
  12. {
  13. constexpr zmq::mutable_buffer mb;
  14. constexpr zmq::const_buffer cb;
  15. CHECK(mb.size() == 0);
  16. CHECK(mb.data() == nullptr);
  17. CHECK(cb.size() == 0);
  18. CHECK(cb.data() == nullptr);
  19. }
  20. TEST_CASE("buffer data ctor", "[buffer]")
  21. {
  22. std::vector<BT> v(10);
  23. zmq::const_buffer cb(v.data(), v.size() * sizeof(BT));
  24. CHECK(cb.size() == v.size() * sizeof(BT));
  25. CHECK(cb.data() == v.data());
  26. zmq::mutable_buffer mb(v.data(), v.size() * sizeof(BT));
  27. CHECK(mb.size() == v.size() * sizeof(BT));
  28. CHECK(mb.data() == v.data());
  29. zmq::const_buffer from_mut = mb;
  30. CHECK(mb.size() == from_mut.size());
  31. CHECK(mb.data() == from_mut.data());
  32. const auto cmb = mb;
  33. static_assert(std::is_same<decltype(cmb.data()), void *>::value, "");
  34. constexpr const void *cp = nullptr;
  35. constexpr void *p = nullptr;
  36. constexpr zmq::const_buffer cecb = zmq::buffer(p, 0);
  37. constexpr zmq::mutable_buffer cemb = zmq::buffer(p, 0);
  38. CHECK(cecb.data() == nullptr);
  39. CHECK(cemb.data() == nullptr);
  40. }
  41. TEST_CASE("const_buffer operator+", "[buffer]")
  42. {
  43. std::vector<BT> v(10);
  44. zmq::const_buffer cb(v.data(), v.size() * sizeof(BT));
  45. const size_t shift = 4;
  46. auto shifted = cb + shift;
  47. CHECK(shifted.size() == v.size() * sizeof(BT) - shift);
  48. CHECK(shifted.data() == v.data() + shift / sizeof(BT));
  49. auto shifted2 = shift + cb;
  50. CHECK(shifted.size() == shifted2.size());
  51. CHECK(shifted.data() == shifted2.data());
  52. auto cbinp = cb;
  53. cbinp += shift;
  54. CHECK(shifted.size() == cbinp.size());
  55. CHECK(shifted.data() == cbinp.data());
  56. }
  57. TEST_CASE("mutable_buffer operator+", "[buffer]")
  58. {
  59. std::vector<BT> v(10);
  60. zmq::mutable_buffer mb(v.data(), v.size() * sizeof(BT));
  61. const size_t shift = 4;
  62. auto shifted = mb + shift;
  63. CHECK(shifted.size() == v.size() * sizeof(BT) - shift);
  64. CHECK(shifted.data() == v.data() + shift / sizeof(BT));
  65. auto shifted2 = shift + mb;
  66. CHECK(shifted.size() == shifted2.size());
  67. CHECK(shifted.data() == shifted2.data());
  68. auto mbinp = mb;
  69. mbinp += shift;
  70. CHECK(shifted.size() == mbinp.size());
  71. CHECK(shifted.data() == mbinp.data());
  72. }
  73. TEST_CASE("mutable_buffer creation basic", "[buffer]")
  74. {
  75. std::vector<BT> v(10);
  76. zmq::mutable_buffer mb(v.data(), v.size() * sizeof(BT));
  77. zmq::mutable_buffer mb2 = zmq::buffer(v.data(), v.size() * sizeof(BT));
  78. CHECK(mb.data() == mb2.data());
  79. CHECK(mb.size() == mb2.size());
  80. zmq::mutable_buffer mb3 = zmq::buffer(mb);
  81. CHECK(mb.data() == mb3.data());
  82. CHECK(mb.size() == mb3.size());
  83. zmq::mutable_buffer mb4 = zmq::buffer(mb, 10 * v.size() * sizeof(BT));
  84. CHECK(mb.data() == mb4.data());
  85. CHECK(mb.size() == mb4.size());
  86. zmq::mutable_buffer mb5 = zmq::buffer(mb, 4);
  87. CHECK(mb.data() == mb5.data());
  88. CHECK(4 == mb5.size());
  89. }
  90. TEST_CASE("const_buffer creation basic", "[buffer]")
  91. {
  92. const std::vector<BT> v(10);
  93. zmq::const_buffer cb(v.data(), v.size() * sizeof(BT));
  94. zmq::const_buffer cb2 = zmq::buffer(v.data(), v.size() * sizeof(BT));
  95. CHECK(cb.data() == cb2.data());
  96. CHECK(cb.size() == cb2.size());
  97. zmq::const_buffer cb3 = zmq::buffer(cb);
  98. CHECK(cb.data() == cb3.data());
  99. CHECK(cb.size() == cb3.size());
  100. zmq::const_buffer cb4 = zmq::buffer(cb, 10 * v.size() * sizeof(BT));
  101. CHECK(cb.data() == cb4.data());
  102. CHECK(cb.size() == cb4.size());
  103. zmq::const_buffer cb5 = zmq::buffer(cb, 4);
  104. CHECK(cb.data() == cb5.data());
  105. CHECK(4 == cb5.size());
  106. }
  107. TEST_CASE("mutable_buffer creation C array", "[buffer]")
  108. {
  109. BT d[10] = {};
  110. zmq::mutable_buffer b = zmq::buffer(d);
  111. CHECK(b.size() == 10 * sizeof(BT));
  112. CHECK(b.data() == static_cast<BT*>(d));
  113. zmq::const_buffer b2 = zmq::buffer(d, 4);
  114. CHECK(b2.size() == 4);
  115. CHECK(b2.data() == static_cast<BT*>(d));
  116. }
  117. TEST_CASE("const_buffer creation C array", "[buffer]")
  118. {
  119. const BT d[10] = {};
  120. zmq::const_buffer b = zmq::buffer(d);
  121. CHECK(b.size() == 10 * sizeof(BT));
  122. CHECK(b.data() == static_cast<const BT*>(d));
  123. zmq::const_buffer b2 = zmq::buffer(d, 4);
  124. CHECK(b2.size() == 4);
  125. CHECK(b2.data() == static_cast<const BT*>(d));
  126. }
  127. TEST_CASE("mutable_buffer creation array", "[buffer]")
  128. {
  129. std::array<BT, 10> d = {};
  130. zmq::mutable_buffer b = zmq::buffer(d);
  131. CHECK(b.size() == d.size() * sizeof(BT));
  132. CHECK(b.data() == d.data());
  133. zmq::mutable_buffer b2 = zmq::buffer(d, 4);
  134. CHECK(b2.size() == 4);
  135. CHECK(b2.data() == d.data());
  136. }
  137. TEST_CASE("const_buffer creation array", "[buffer]")
  138. {
  139. const std::array<BT, 10> d = {};
  140. zmq::const_buffer b = zmq::buffer(d);
  141. CHECK(b.size() == d.size() * sizeof(BT));
  142. CHECK(b.data() == d.data());
  143. zmq::const_buffer b2 = zmq::buffer(d, 4);
  144. CHECK(b2.size() == 4);
  145. CHECK(b2.data() == d.data());
  146. }
  147. TEST_CASE("const_buffer creation array 2", "[buffer]")
  148. {
  149. std::array<const BT, 10> d = {{}};
  150. zmq::const_buffer b = zmq::buffer(d);
  151. CHECK(b.size() == d.size() * sizeof(BT));
  152. CHECK(b.data() == d.data());
  153. zmq::const_buffer b2 = zmq::buffer(d, 4);
  154. CHECK(b2.size() == 4);
  155. CHECK(b2.data() == d.data());
  156. }
  157. TEST_CASE("mutable_buffer creation vector", "[buffer]")
  158. {
  159. std::vector<BT> d(10);
  160. zmq::mutable_buffer b = zmq::buffer(d);
  161. CHECK(b.size() == d.size() * sizeof(BT));
  162. CHECK(b.data() == d.data());
  163. zmq::mutable_buffer b2 = zmq::buffer(d, 4);
  164. CHECK(b2.size() == 4);
  165. CHECK(b2.data() == d.data());
  166. d.clear();
  167. b = zmq::buffer(d);
  168. CHECK(b.size() == 0);
  169. CHECK(b.data() == nullptr);
  170. }
  171. TEST_CASE("const_buffer creation vector", "[buffer]")
  172. {
  173. std::vector<BT> d(10);
  174. zmq::const_buffer b = zmq::buffer(static_cast<const std::vector<BT> &>(d));
  175. CHECK(b.size() == d.size() * sizeof(BT));
  176. CHECK(b.data() == d.data());
  177. zmq::const_buffer b2 = zmq::buffer(static_cast<const std::vector<BT> &>(d), 4);
  178. CHECK(b2.size() == 4);
  179. CHECK(b2.data() == d.data());
  180. d.clear();
  181. b = zmq::buffer(static_cast<const std::vector<BT> &>(d));
  182. CHECK(b.size() == 0);
  183. CHECK(b.data() == nullptr);
  184. }
  185. TEST_CASE("const_buffer creation string", "[buffer]")
  186. {
  187. const std::wstring d(10, L'a');
  188. zmq::const_buffer b = zmq::buffer(d);
  189. CHECK(b.size() == d.size() * sizeof(wchar_t));
  190. CHECK(b.data() == d.data());
  191. zmq::const_buffer b2 = zmq::buffer(d, 4);
  192. CHECK(b2.size() == 4);
  193. CHECK(b2.data() == d.data());
  194. }
  195. TEST_CASE("mutable_buffer creation string", "[buffer]")
  196. {
  197. std::wstring d(10, L'a');
  198. zmq::mutable_buffer b = zmq::buffer(d);
  199. CHECK(b.size() == d.size() * sizeof(wchar_t));
  200. CHECK(b.data() == d.data());
  201. zmq::mutable_buffer b2 = zmq::buffer(d, 4);
  202. CHECK(b2.size() == 4);
  203. CHECK(b2.data() == d.data());
  204. }
  205. #if CPPZMQ_HAS_STRING_VIEW
  206. TEST_CASE("const_buffer creation string_view", "[buffer]")
  207. {
  208. std::wstring dstr(10, L'a');
  209. std::wstring_view d = dstr;
  210. zmq::const_buffer b = zmq::buffer(d);
  211. CHECK(b.size() == d.size() * sizeof(wchar_t));
  212. CHECK(b.data() == d.data());
  213. zmq::const_buffer b2 = zmq::buffer(d, 4);
  214. CHECK(b2.size() == 4);
  215. CHECK(b2.data() == d.data());
  216. }
  217. #endif
  218. TEST_CASE("const_buffer creation with str_buffer", "[buffer]")
  219. {
  220. const wchar_t wd[10] = {};
  221. zmq::const_buffer b = zmq::str_buffer(wd);
  222. CHECK(b.size() == 9 * sizeof(wchar_t));
  223. CHECK(b.data() == static_cast<const wchar_t*>(wd));
  224. zmq::const_buffer b2_null = zmq::buffer("hello");
  225. constexpr zmq::const_buffer b2 = zmq::str_buffer("hello");
  226. CHECK(b2_null.size() == 6);
  227. CHECK(b2.size() == 5);
  228. CHECK(std::string(static_cast<const char*>(b2.data()), b2.size()) == "hello");
  229. }
  230. TEST_CASE("const_buffer creation with zbuf string literal char", "[buffer]")
  231. {
  232. using namespace zmq::literals;
  233. constexpr zmq::const_buffer b = "hello"_zbuf;
  234. CHECK(b.size() == 5);
  235. CHECK(std::memcmp(b.data(), "hello", b.size()) == 0);
  236. }
  237. TEST_CASE("const_buffer creation with zbuf string literal wchar_t", "[buffer]")
  238. {
  239. using namespace zmq::literals;
  240. constexpr zmq::const_buffer b = L"hello"_zbuf;
  241. CHECK(b.size() == 5 * sizeof(wchar_t));
  242. CHECK(std::memcmp(b.data(), L"hello", b.size()) == 0);
  243. }
  244. TEST_CASE("const_buffer creation with zbuf string literal char16_t", "[buffer]")
  245. {
  246. using namespace zmq::literals;
  247. constexpr zmq::const_buffer b = u"hello"_zbuf;
  248. CHECK(b.size() == 5 * sizeof(char16_t));
  249. CHECK(std::memcmp(b.data(), u"hello", b.size()) == 0);
  250. }
  251. TEST_CASE("const_buffer creation with zbuf string literal char32_t", "[buffer]")
  252. {
  253. using namespace zmq::literals;
  254. constexpr zmq::const_buffer b = U"hello"_zbuf;
  255. CHECK(b.size() == 5 * sizeof(char32_t));
  256. CHECK(std::memcmp(b.data(), U"hello", b.size()) == 0);
  257. }
  258. TEST_CASE("buffer of structs", "[buffer]")
  259. {
  260. struct some_pod
  261. {
  262. int64_t val;
  263. char arr[8];
  264. };
  265. struct some_non_pod
  266. {
  267. int64_t val;
  268. char arr[8];
  269. std::vector<int> s; // not trivially copyable
  270. };
  271. static_assert(zmq::detail::is_pod_like<some_pod>::value, "");
  272. static_assert(!zmq::detail::is_pod_like<some_non_pod>::value, "");
  273. std::array<some_pod, 1> d;
  274. zmq::mutable_buffer b = zmq::buffer(d);
  275. CHECK(b.size() == d.size() * sizeof(some_pod));
  276. CHECK(b.data() == d.data());
  277. }
  278. #endif