1 // Copyright (C) 2013,2015 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 
6 // <boost/thread/sync_queue.hpp>
7 
8 // class sync_queue<T>
9 
10 //    sync_queue();
11 
12 #define BOOST_THREAD_VERSION 4
13 
14 #include <boost/thread/sync_queue.hpp>
15 
16 #include <boost/detail/lightweight_test.hpp>
17 
18 class non_copyable
19 {
20   BOOST_THREAD_MOVABLE_ONLY(non_copyable)
21   int val;
22 public:
non_copyable(int v)23   non_copyable(int v) : val(v){}
non_copyable(BOOST_RV_REF (non_copyable)x)24   non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
operator =(BOOST_RV_REF (non_copyable)x)25   non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
operator ==(non_copyable const & x) const26   bool operator==(non_copyable const& x) const {return val==x.val;}
27   template <typename OSTREAM>
operator <<(OSTREAM & os,non_copyable const & x)28   friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
29   {
30     os << x.val;
31     return os;
32   }
33 
34 };
35 
36 
37 
main()38 int main()
39 {
40 
41   {
42     // default queue invariants
43       boost::sync_queue<int> q;
44       BOOST_TEST(q.empty());
45       BOOST_TEST(! q.full());
46       BOOST_TEST_EQ(q.size(), 0u);
47       BOOST_TEST(! q.closed());
48   }
49 
50 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
51   {
52     // empty queue push rvalue/non_copyable succeeds
53       boost::sync_queue<non_copyable> q;
54       q.push(non_copyable(1));
55       BOOST_TEST(! q.empty());
56       BOOST_TEST(! q.full());
57       BOOST_TEST_EQ(q.size(), 1u);
58       BOOST_TEST(! q.closed());
59   }
60 #endif
61   {
62     // empty queue push rvalue/non_copyable succeeds
63       boost::sync_queue<non_copyable> q;
64       non_copyable nc(1);
65       q.push(boost::move(nc));
66       BOOST_TEST(! q.empty());
67       BOOST_TEST(! q.full());
68       BOOST_TEST_EQ(q.size(), 1u);
69       BOOST_TEST(! q.closed());
70   }
71 
72   {
73     // empty queue push rvalue succeeds
74       boost::sync_queue<int> q;
75       q.push(1);
76       q.push(2);
77       BOOST_TEST(! q.empty());
78       BOOST_TEST(! q.full());
79       BOOST_TEST_EQ(q.size(), 2u);
80       BOOST_TEST(! q.closed());
81   }
82   {
83     // empty queue push lvalue succeeds
84       boost::sync_queue<int> q;
85       int i;
86       q.push(i);
87       BOOST_TEST(! q.empty());
88       BOOST_TEST(! q.full());
89       BOOST_TEST_EQ(q.size(), 1u);
90       BOOST_TEST(! q.closed());
91   }
92   {
93     // empty queue try_push rvalue/copyable succeeds
94       boost::sync_queue<int> q;
95       BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
96       BOOST_TEST(! q.empty());
97       BOOST_TEST(! q.full());
98       BOOST_TEST_EQ(q.size(), 1u);
99       BOOST_TEST(! q.closed());
100   }
101   {
102     // empty queue try_push rvalue/copyable succeeds
103       boost::sync_queue<int> q;
104       BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
105       BOOST_TEST(! q.empty());
106       BOOST_TEST(! q.full());
107       BOOST_TEST_EQ(q.size(), 1u);
108       BOOST_TEST(! q.closed());
109   }
110 
111 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
112   {
113     // empty queue try_push rvalue/non-copyable succeeds
114       boost::sync_queue<non_copyable> q;
115       BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1)));
116       BOOST_TEST(! q.empty());
117       BOOST_TEST(! q.full());
118       BOOST_TEST_EQ(q.size(), 1u);
119       BOOST_TEST(! q.closed());
120   }
121 #endif
122   {
123     // empty queue try_push rvalue/non-copyable succeeds
124       boost::sync_queue<non_copyable> q;
125       non_copyable nc(1);
126       BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
127       BOOST_TEST(! q.empty());
128       BOOST_TEST(! q.full());
129       BOOST_TEST_EQ(q.size(), 1u);
130       BOOST_TEST(! q.closed());
131   }
132 
133   {
134     // empty queue try_push lvalue succeeds
135       boost::sync_queue<int> q;
136       int i=1;
137       BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
138       BOOST_TEST(! q.empty());
139       BOOST_TEST(! q.full());
140       BOOST_TEST_EQ(q.size(), 1u);
141       BOOST_TEST(! q.closed());
142   }
143   {
144     // empty queue try_push rvalue succeeds
145       boost::sync_queue<int> q;
146       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
147       BOOST_TEST(! q.empty());
148       BOOST_TEST(! q.full());
149       BOOST_TEST_EQ(q.size(), 1u);
150       BOOST_TEST(! q.closed());
151   }
152 
153 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
154   {
155     // empty queue nonblocking_push rvalue/non-copyable succeeds
156       boost::sync_queue<non_copyable> q;
157       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
158       BOOST_TEST(! q.empty());
159       BOOST_TEST(! q.full());
160       BOOST_TEST_EQ(q.size(), 1u);
161       BOOST_TEST(! q.closed());
162   }
163 #endif
164   {
165     // empty queue nonblocking_push rvalue/non-copyable succeeds
166       boost::sync_queue<non_copyable> q;
167       non_copyable nc(1);
168       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
169       BOOST_TEST(! q.empty());
170       BOOST_TEST(! q.full());
171       BOOST_TEST_EQ(q.size(), 1u);
172       BOOST_TEST(! q.closed());
173   }
174   {
175     // 1-element queue pull succeed
176       boost::sync_queue<int> q;
177       q.push(1);
178       int i;
179       q.pull(i);
180       BOOST_TEST_EQ(i, 1);
181       BOOST_TEST(q.empty());
182       BOOST_TEST(! q.full());
183       BOOST_TEST_EQ(q.size(), 0u);
184       BOOST_TEST(! q.closed());
185   }
186   {
187     // 1-element queue pull succeed
188       boost::sync_queue<non_copyable> q;
189       non_copyable nc1(1);
190       q.push(boost::move(nc1));
191       non_copyable nc2(2);
192       q.pull(nc2);
193       BOOST_TEST_EQ(nc1, nc2);
194       BOOST_TEST(q.empty());
195       BOOST_TEST(! q.full());
196       BOOST_TEST_EQ(q.size(), 0u);
197       BOOST_TEST(! q.closed());
198   }
199   {
200     // 1-element queue pull succeed
201       boost::sync_queue<int> q;
202       q.push(1);
203       int i = q.pull();
204       BOOST_TEST_EQ(i, 1);
205       BOOST_TEST(q.empty());
206       BOOST_TEST(! q.full());
207       BOOST_TEST_EQ(q.size(), 0u);
208       BOOST_TEST(! q.closed());
209   }
210   {
211     // 1-element queue pull succeed
212       boost::sync_queue<non_copyable> q;
213       non_copyable nc1(1);
214       q.push(boost::move(nc1));
215       non_copyable nc = q.pull();
216       BOOST_TEST_EQ(nc, nc1);
217       BOOST_TEST(q.empty());
218       BOOST_TEST(! q.full());
219       BOOST_TEST_EQ(q.size(), 0u);
220       BOOST_TEST(! q.closed());
221   }
222   {
223     // 1-element queue try_pull succeed
224       boost::sync_queue<int> q;
225       q.push(1);
226       int i;
227       BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
228       BOOST_TEST_EQ(i, 1);
229       BOOST_TEST(q.empty());
230       BOOST_TEST(! q.full());
231       BOOST_TEST_EQ(q.size(), 0u);
232       BOOST_TEST(! q.closed());
233   }
234   {
235     // 1-element queue try_pull succeed
236       boost::sync_queue<non_copyable> q;
237       non_copyable nc1(1);
238       q.push(boost::move(nc1));
239       non_copyable nc(2);
240       BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
241       BOOST_TEST_EQ(nc, nc1);
242       BOOST_TEST(q.empty());
243       BOOST_TEST(! q.full());
244       BOOST_TEST_EQ(q.size(), 0u);
245       BOOST_TEST(! q.closed());
246   }
247   {
248     // 1-element queue nonblocking_pull succeed
249       boost::sync_queue<int> q;
250       q.push(1);
251       int i;
252       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
253       BOOST_TEST_EQ(i, 1);
254       BOOST_TEST(q.empty());
255       BOOST_TEST(! q.full());
256       BOOST_TEST_EQ(q.size(), 0u);
257       BOOST_TEST(! q.closed());
258   }
259   {
260     // 1-element queue nonblocking_pull succeed
261       boost::sync_queue<non_copyable> q;
262       non_copyable nc1(1);
263       q.push(boost::move(nc1));
264       non_copyable nc(2);
265       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
266       BOOST_TEST_EQ(nc, nc1);
267       BOOST_TEST(q.empty());
268       BOOST_TEST(! q.full());
269       BOOST_TEST_EQ(q.size(), 0u);
270       BOOST_TEST(! q.closed());
271   }
272   {
273     // 1-element queue wait_pull succeed
274       boost::sync_queue<non_copyable> q;
275       non_copyable nc1(1);
276       q.push(boost::move(nc1));
277       non_copyable nc(2);
278       BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
279       BOOST_TEST_EQ(nc, nc1);
280       BOOST_TEST(q.empty());
281       BOOST_TEST(! q.full());
282       BOOST_TEST_EQ(q.size(), 0u);
283       BOOST_TEST(! q.closed());
284   }
285   {
286     // 1-element queue wait_pull succeed
287       boost::sync_queue<int> q;
288       q.push(1);
289       int i;
290       BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
291       BOOST_TEST_EQ(i, 1);
292       BOOST_TEST(q.empty());
293       BOOST_TEST(! q.full());
294       BOOST_TEST_EQ(q.size(), 0u);
295       BOOST_TEST(! q.closed());
296   }
297   {
298     // 1-element queue wait_pull succeed
299       boost::sync_queue<non_copyable> q;
300       non_copyable nc1(1);
301       q.push(boost::move(nc1));
302       non_copyable nc(2);
303       BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
304       BOOST_TEST_EQ(nc, nc1);
305       BOOST_TEST(q.empty());
306       BOOST_TEST(! q.full());
307       BOOST_TEST_EQ(q.size(), 0u);
308       BOOST_TEST(! q.closed());
309   }
310 
311   {
312     // closed invariants
313       boost::sync_queue<int> q;
314       q.close();
315       BOOST_TEST(q.empty());
316       BOOST_TEST(! q.full());
317       BOOST_TEST_EQ(q.size(), 0u);
318       BOOST_TEST(q.closed());
319   }
320   {
321     // closed queue push fails
322       boost::sync_queue<int> q;
323       q.close();
324       try {
325         q.push(1);
326         BOOST_TEST(false);
327       } catch (...) {
328         BOOST_TEST(q.empty());
329         BOOST_TEST(! q.full());
330         BOOST_TEST_EQ(q.size(), 0u);
331         BOOST_TEST(q.closed());
332       }
333   }
334   {
335     // 1-element closed queue pull succeed
336       boost::sync_queue<int> q;
337       q.push(1);
338       q.close();
339       int i;
340       q.pull(i);
341       BOOST_TEST_EQ(i, 1);
342       BOOST_TEST(q.empty());
343       BOOST_TEST(! q.full());
344       BOOST_TEST_EQ(q.size(), 0u);
345       BOOST_TEST(q.closed());
346   }
347   {
348     // 1-element closed queue wait_pull succeed
349       boost::sync_queue<int> q;
350       q.push(1);
351       q.close();
352       int i;
353       BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
354       BOOST_TEST_EQ(i, 1);
355       BOOST_TEST(q.empty());
356       BOOST_TEST(! q.full());
357       BOOST_TEST_EQ(q.size(), 0u);
358       BOOST_TEST(q.closed());
359   }
360   {
361     // closed empty queue wait_pull fails
362       boost::sync_queue<int> q;
363       q.close();
364       BOOST_TEST(q.empty());
365       BOOST_TEST(q.closed());
366       int i;
367       BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
368       BOOST_TEST(q.empty());
369       BOOST_TEST(q.closed());
370   }
371 
372   return boost::report_errors();
373 }
374 
375