single_thread_pass.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // Copyright (C) 2014 Vicente J. Botet Escriba
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // <boost/thread/sync_queue.hpp>
  6. // class sync_queue<T>
  7. // sync_queue();
  8. #define BOOST_THREAD_VERSION 4
  9. //#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
  10. #include <boost/thread/concurrent_queues/sync_queue.hpp>
  11. #include <boost/thread/concurrent_queues/queue_adaptor.hpp>
  12. #include <boost/thread/concurrent_queues/queue_views.hpp>
  13. #include <boost/detail/lightweight_test.hpp>
  14. #include <boost/static_assert.hpp>
  15. class non_copyable
  16. {
  17. int val;
  18. public:
  19. BOOST_THREAD_MOVABLE_ONLY(non_copyable)
  20. non_copyable(int v) : val(v){}
  21. non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
  22. non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
  23. bool operator==(non_copyable const& x) const {return val==x.val;}
  24. template <typename OSTREAM>
  25. friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
  26. {
  27. os << x.val;
  28. return os;
  29. }
  30. };
  31. #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
  32. BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value );
  33. BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value );
  34. #endif
  35. int main()
  36. {
  37. {
  38. // default queue invariants
  39. boost::queue_adaptor<boost::sync_queue<int> > sq;
  40. boost::queue_back<int> q(sq);
  41. BOOST_TEST(q.empty());
  42. BOOST_TEST(! q.full());
  43. BOOST_TEST_EQ(q.size(), 0u);
  44. BOOST_TEST(! q.closed());
  45. }
  46. {
  47. // default queue invariants
  48. boost::queue_adaptor<boost::sync_queue<int> > sq;
  49. boost::queue_front<int> q(sq);
  50. BOOST_TEST(q.empty());
  51. BOOST_TEST(! q.full());
  52. BOOST_TEST_EQ(q.size(), 0u);
  53. BOOST_TEST(! q.closed());
  54. }
  55. {
  56. // empty queue try_pull fails
  57. boost::queue_adaptor<boost::sync_queue<int> > sq;
  58. boost::queue_front<int> q(sq);
  59. int i;
  60. BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i));
  61. BOOST_TEST(q.empty());
  62. BOOST_TEST(! q.full());
  63. BOOST_TEST_EQ(q.size(), 0u);
  64. BOOST_TEST(! q.closed());
  65. }
  66. {
  67. // empty queue push rvalue/copyable succeeds
  68. boost::queue_adaptor<boost::sync_queue<int> > sq;
  69. boost::queue_back<int> q(sq);
  70. q.push(1);
  71. BOOST_TEST(! q.empty());
  72. BOOST_TEST(! q.full());
  73. BOOST_TEST_EQ(q.size(), 1u);
  74. BOOST_TEST(! q.closed());
  75. }
  76. {
  77. // empty queue push lvalue/copyable succeeds
  78. boost::queue_adaptor<boost::sync_queue<int> > sq;
  79. boost::queue_back<int> q(sq);
  80. int i;
  81. q.push(i);
  82. BOOST_TEST(! q.empty());
  83. BOOST_TEST(! q.full());
  84. BOOST_TEST_EQ(q.size(), 1u);
  85. BOOST_TEST(! q.closed());
  86. }
  87. #if 0
  88. {
  89. // empty queue push rvalue/non_copyable succeeds
  90. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  91. boost::queue_back<non_copyable> q(sq);
  92. q.push(non_copyable(1));
  93. BOOST_TEST(! q.empty());
  94. BOOST_TEST(! q.full());
  95. BOOST_TEST_EQ(q.size(), 1u);
  96. BOOST_TEST(! q.closed());
  97. }
  98. #endif
  99. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  100. {
  101. // empty queue push rvalue/non_copyable succeeds
  102. boost::queue_adaptor<boost::sync_queue<non_copyable> > q;
  103. //boost::sync_queue<non_copyable> q;
  104. //boost::queue_back<non_copyable> q(sq);
  105. non_copyable nc(1);
  106. q.push(boost::move(nc));
  107. BOOST_TEST(! q.empty());
  108. BOOST_TEST(! q.full());
  109. BOOST_TEST_EQ(q.size(), 1u);
  110. BOOST_TEST(! q.closed());
  111. }
  112. #endif
  113. {
  114. // empty queue push rvalue succeeds
  115. boost::queue_adaptor<boost::sync_queue<int> > sq;
  116. boost::queue_back<int> q(sq);
  117. q.push(1);
  118. q.push(2);
  119. BOOST_TEST(! q.empty());
  120. BOOST_TEST(! q.full());
  121. BOOST_TEST_EQ(q.size(), 2u);
  122. BOOST_TEST(! q.closed());
  123. }
  124. {
  125. // empty queue push lvalue succeeds
  126. boost::queue_adaptor<boost::sync_queue<int> > sq;
  127. boost::queue_back<int> q(sq);
  128. int i;
  129. q.push(i);
  130. BOOST_TEST(! q.empty());
  131. BOOST_TEST(! q.full());
  132. BOOST_TEST_EQ(q.size(), 1u);
  133. BOOST_TEST(! q.closed());
  134. }
  135. {
  136. // empty queue try_push rvalue/copyable succeeds
  137. boost::queue_adaptor<boost::sync_queue<int> > sq;
  138. boost::queue_back<int> q(sq);
  139. BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
  140. BOOST_TEST(! q.empty());
  141. BOOST_TEST(! q.full());
  142. BOOST_TEST_EQ(q.size(), 1u);
  143. BOOST_TEST(! q.closed());
  144. }
  145. {
  146. // empty queue try_push rvalue/copyable succeeds
  147. boost::queue_adaptor<boost::sync_queue<int> > sq;
  148. boost::queue_back<int> q(sq);
  149. BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
  150. BOOST_TEST(! q.empty());
  151. BOOST_TEST(! q.full());
  152. BOOST_TEST_EQ(q.size(), 1u);
  153. BOOST_TEST(! q.closed());
  154. }
  155. #if 0
  156. {
  157. // empty queue try_push rvalue/non-copyable succeeds
  158. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  159. boost::queue_back<non_copyable> q(sq);
  160. non_copyable nc(1);
  161. BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
  162. BOOST_TEST(! q.empty());
  163. BOOST_TEST(! q.full());
  164. BOOST_TEST_EQ(q.size(), 1u);
  165. BOOST_TEST(! q.closed());
  166. }
  167. #endif
  168. {
  169. // empty queue try_push lvalue succeeds
  170. boost::queue_adaptor<boost::sync_queue<int> > sq;
  171. boost::queue_back<int> q(sq);
  172. int i=0;
  173. BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
  174. BOOST_TEST(! q.empty());
  175. BOOST_TEST(! q.full());
  176. BOOST_TEST_EQ(q.size(), 1u);
  177. BOOST_TEST(! q.closed());
  178. }
  179. {
  180. // empty queue try_push rvalue succeeds
  181. boost::queue_adaptor<boost::sync_queue<int> > sq;
  182. boost::queue_back<int> q(sq);
  183. BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
  184. BOOST_TEST(! q.empty());
  185. BOOST_TEST(! q.full());
  186. BOOST_TEST_EQ(q.size(), 1u);
  187. BOOST_TEST(! q.closed());
  188. }
  189. #if 0
  190. {
  191. // empty queue nonblocking_push rvalue/non-copyable succeeds
  192. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  193. boost::queue_back<non_copyable> q(sq);
  194. BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
  195. BOOST_TEST(! q.empty());
  196. BOOST_TEST(! q.full());
  197. BOOST_TEST_EQ(q.size(), 1u);
  198. BOOST_TEST(! q.closed());
  199. }
  200. #endif
  201. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  202. {
  203. // empty queue nonblocking_push rvalue/non-copyable succeeds
  204. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  205. boost::queue_back<non_copyable> q(sq);
  206. non_copyable nc(1);
  207. BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
  208. BOOST_TEST(! q.empty());
  209. BOOST_TEST(! q.full());
  210. BOOST_TEST_EQ(q.size(), 1u);
  211. BOOST_TEST(! q.closed());
  212. }
  213. #endif
  214. {
  215. // 1-element queue pull succeed
  216. boost::queue_adaptor<boost::sync_queue<int> > sq;
  217. boost::queue_front<int> q(sq);
  218. sq.push(1);
  219. int i;
  220. q.pull(i);
  221. BOOST_TEST_EQ(i, 1);
  222. BOOST_TEST(q.empty());
  223. BOOST_TEST(! q.full());
  224. BOOST_TEST_EQ(q.size(), 0u);
  225. BOOST_TEST(! q.closed());
  226. }
  227. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  228. {
  229. // 1-element queue pull succeed
  230. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  231. boost::queue_front<non_copyable> q(sq);
  232. non_copyable nc1(1);
  233. sq.push(boost::move(nc1));
  234. non_copyable nc2(2);
  235. q.pull(nc2);
  236. BOOST_TEST_EQ(nc1, nc2);
  237. BOOST_TEST(q.empty());
  238. BOOST_TEST(! q.full());
  239. BOOST_TEST_EQ(q.size(), 0u);
  240. BOOST_TEST(! q.closed());
  241. }
  242. #endif
  243. {
  244. // 1-element queue pull succeed
  245. boost::queue_adaptor<boost::sync_queue<int> > sq;
  246. boost::queue_front<int> q(sq);
  247. sq.push(1);
  248. int i = q.pull();
  249. BOOST_TEST_EQ(i, 1);
  250. BOOST_TEST(q.empty());
  251. BOOST_TEST(! q.full());
  252. BOOST_TEST_EQ(q.size(), 0u);
  253. BOOST_TEST(! q.closed());
  254. }
  255. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  256. {
  257. // 1-element queue pull succeed
  258. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  259. boost::queue_front<non_copyable> q(sq);
  260. non_copyable nc1(1);
  261. sq.push(boost::move(nc1));
  262. non_copyable nc = q.pull();
  263. BOOST_TEST_EQ(nc, nc1);
  264. BOOST_TEST(q.empty());
  265. BOOST_TEST(! q.full());
  266. BOOST_TEST_EQ(q.size(), 0u);
  267. BOOST_TEST(! q.closed());
  268. }
  269. #endif
  270. {
  271. // 1-element queue try_pull succeed
  272. boost::queue_adaptor<boost::sync_queue<int> > sq;
  273. boost::queue_front<int> q(sq);
  274. sq.push(1);
  275. int i;
  276. BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
  277. BOOST_TEST_EQ(i, 1);
  278. BOOST_TEST(q.empty());
  279. BOOST_TEST(! q.full());
  280. BOOST_TEST_EQ(q.size(), 0u);
  281. BOOST_TEST(! q.closed());
  282. }
  283. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  284. {
  285. // 1-element queue try_pull succeed
  286. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  287. boost::queue_front<non_copyable> q(sq);
  288. non_copyable nc1(1);
  289. sq.push(boost::move(nc1));
  290. non_copyable nc(2);
  291. BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
  292. BOOST_TEST_EQ(nc, nc1);
  293. BOOST_TEST(q.empty());
  294. BOOST_TEST(! q.full());
  295. BOOST_TEST_EQ(q.size(), 0u);
  296. BOOST_TEST(! q.closed());
  297. }
  298. #endif
  299. {
  300. // 1-element queue nonblocking_pull succeed
  301. boost::queue_adaptor<boost::sync_queue<int> > sq;
  302. boost::queue_front<int> q(sq);
  303. sq.push(1);
  304. int i;
  305. BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
  306. BOOST_TEST_EQ(i, 1);
  307. BOOST_TEST(q.empty());
  308. BOOST_TEST(! q.full());
  309. BOOST_TEST_EQ(q.size(), 0u);
  310. BOOST_TEST(! q.closed());
  311. }
  312. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  313. {
  314. // 1-element queue nonblocking_pull succeed
  315. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  316. boost::queue_front<non_copyable> q(sq);
  317. non_copyable nc1(1);
  318. sq.push(boost::move(nc1));
  319. non_copyable nc(2);
  320. BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
  321. BOOST_TEST_EQ(nc, nc1);
  322. BOOST_TEST(q.empty());
  323. BOOST_TEST(! q.full());
  324. BOOST_TEST_EQ(q.size(), 0u);
  325. BOOST_TEST(! q.closed());
  326. }
  327. {
  328. // 1-element queue wait_pull succeed
  329. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  330. boost::queue_front<non_copyable> q(sq);
  331. non_copyable nc1(1);
  332. sq.push(boost::move(nc1));
  333. non_copyable nc(2);
  334. BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
  335. BOOST_TEST_EQ(nc, nc1);
  336. BOOST_TEST(q.empty());
  337. BOOST_TEST(! q.full());
  338. BOOST_TEST_EQ(q.size(), 0u);
  339. BOOST_TEST(! q.closed());
  340. }
  341. #endif
  342. {
  343. // 1-element queue wait_pull succeed
  344. boost::queue_adaptor<boost::sync_queue<int> > sq;
  345. boost::queue_front<int> q(sq);
  346. sq.push(1);
  347. int i;
  348. BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
  349. BOOST_TEST_EQ(i, 1);
  350. BOOST_TEST(q.empty());
  351. BOOST_TEST(! q.full());
  352. BOOST_TEST_EQ(q.size(), 0u);
  353. BOOST_TEST(! q.closed());
  354. }
  355. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
  356. {
  357. // 1-element queue wait_pull succeed
  358. boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
  359. boost::queue_front<non_copyable> q(sq);
  360. non_copyable nc1(1);
  361. sq.push(boost::move(nc1));
  362. non_copyable nc(2);
  363. BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
  364. BOOST_TEST_EQ(nc, nc1);
  365. BOOST_TEST(q.empty());
  366. BOOST_TEST(! q.full());
  367. BOOST_TEST_EQ(q.size(), 0u);
  368. BOOST_TEST(! q.closed());
  369. }
  370. #endif
  371. {
  372. // closed invariants
  373. boost::queue_adaptor<boost::sync_queue<int> > sq;
  374. boost::queue_back<int> q(sq);
  375. q.close();
  376. BOOST_TEST(q.empty());
  377. BOOST_TEST(! q.full());
  378. BOOST_TEST_EQ(q.size(), 0u);
  379. BOOST_TEST(q.closed());
  380. }
  381. {
  382. // closed invariants
  383. boost::queue_adaptor<boost::sync_queue<int> > sq;
  384. boost::queue_front<int> q(sq);
  385. q.close();
  386. BOOST_TEST(q.empty());
  387. BOOST_TEST(! q.full());
  388. BOOST_TEST_EQ(q.size(), 0u);
  389. BOOST_TEST(q.closed());
  390. }
  391. {
  392. // closed queue push fails
  393. boost::queue_adaptor<boost::sync_queue<int> > sq;
  394. boost::queue_back<int> q(sq);
  395. q.close();
  396. try {
  397. q.push(1);
  398. BOOST_TEST(false);
  399. } catch (...) {
  400. BOOST_TEST(q.empty());
  401. BOOST_TEST(! q.full());
  402. BOOST_TEST_EQ(q.size(), 0u);
  403. BOOST_TEST(q.closed());
  404. }
  405. }
  406. {
  407. // 1-element closed queue pull succeed
  408. boost::queue_adaptor<boost::sync_queue<int> > sq;
  409. boost::queue_front<int> q(sq);
  410. sq.push(1);
  411. q.close();
  412. int i;
  413. q.pull(i);
  414. BOOST_TEST_EQ(i, 1);
  415. BOOST_TEST(q.empty());
  416. BOOST_TEST(! q.full());
  417. BOOST_TEST_EQ(q.size(), 0u);
  418. BOOST_TEST(q.closed());
  419. }
  420. {
  421. // 1-element closed queue wait_pull succeed
  422. boost::queue_adaptor<boost::sync_queue<int> > sq;
  423. boost::queue_front<int> q(sq);
  424. sq.push(1);
  425. q.close();
  426. int i;
  427. BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
  428. BOOST_TEST_EQ(i, 1);
  429. BOOST_TEST(q.empty());
  430. BOOST_TEST(! q.full());
  431. BOOST_TEST_EQ(q.size(), 0u);
  432. BOOST_TEST(q.closed());
  433. }
  434. {
  435. // closed empty queue wait_pull fails
  436. boost::queue_adaptor<boost::sync_queue<int> > sq;
  437. boost::queue_front<int> q(sq);
  438. q.close();
  439. BOOST_TEST(q.empty());
  440. BOOST_TEST(q.closed());
  441. int i;
  442. BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
  443. BOOST_TEST(q.empty());
  444. BOOST_TEST(q.closed());
  445. }
  446. return boost::report_errors();
  447. }