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/concurrent_queues/sync_deque.hpp>
7 
8 // class sync_deque<T>
9 
10 //    sync_deque();
11 
12 #define BOOST_THREAD_VERSION 4
13 
14 #include <boost/thread/concurrent_queues/sync_deque.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_deque<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     // empty queue try_pull fails
51       boost::sync_deque<int> q;
52       int i;
53       BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i));
54       BOOST_TEST(q.empty());
55       BOOST_TEST(! q.full());
56       BOOST_TEST_EQ(q.size(), 0u);
57       BOOST_TEST(! q.closed());
58   }
59   {
60     // empty queue push rvalue/copyable succeeds
61       boost::sync_deque<int> q;
62       q.push_back(1);
63       BOOST_TEST(! q.empty());
64       BOOST_TEST(! q.full());
65       BOOST_TEST_EQ(q.size(), 1u);
66       BOOST_TEST(! q.closed());
67   }
68   {
69     // empty queue push lvalue/copyable succeeds
70       boost::sync_deque<int> q;
71       int i;
72       q.push_back(i);
73       BOOST_TEST(! q.empty());
74       BOOST_TEST(! q.full());
75       BOOST_TEST_EQ(q.size(), 1u);
76       BOOST_TEST(! q.closed());
77   }
78 
79 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
80   {
81     // empty queue push rvalue/non_copyable succeeds
82       boost::sync_deque<non_copyable> q;
83       q.push_back(non_copyable(1));
84       BOOST_TEST(! q.empty());
85       BOOST_TEST(! q.full());
86       BOOST_TEST_EQ(q.size(), 1u);
87       BOOST_TEST(! q.closed());
88   }
89 #endif
90   {
91     // empty queue push rvalue/non_copyable succeeds
92       boost::sync_deque<non_copyable> q;
93       non_copyable nc(1);
94       q.push_back(boost::move(nc));
95       BOOST_TEST(! q.empty());
96       BOOST_TEST(! q.full());
97       BOOST_TEST_EQ(q.size(), 1u);
98       BOOST_TEST(! q.closed());
99   }
100 
101   {
102     // empty queue push rvalue succeeds
103       boost::sync_deque<int> q;
104       q.push_back(1);
105       q.push_back(2);
106       BOOST_TEST(! q.empty());
107       BOOST_TEST(! q.full());
108       BOOST_TEST_EQ(q.size(), 2u);
109       BOOST_TEST(! q.closed());
110   }
111   {
112     // empty queue push lvalue succeeds
113       boost::sync_deque<int> q;
114       int i;
115       q.push_back(i);
116       BOOST_TEST(! q.empty());
117       BOOST_TEST(! q.full());
118       BOOST_TEST_EQ(q.size(), 1u);
119       BOOST_TEST(! q.closed());
120   }
121   {
122     // empty queue try_push rvalue/copyable succeeds
123       boost::sync_deque<int> q;
124       BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
125       BOOST_TEST(! q.empty());
126       BOOST_TEST(! q.full());
127       BOOST_TEST_EQ(q.size(), 1u);
128       BOOST_TEST(! q.closed());
129   }
130   {
131     // empty queue try_push rvalue/copyable succeeds
132       boost::sync_deque<int> q;
133       BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
134       BOOST_TEST(! q.empty());
135       BOOST_TEST(! q.full());
136       BOOST_TEST_EQ(q.size(), 1u);
137       BOOST_TEST(! q.closed());
138   }
139 
140 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
141   {
142     // empty queue try_push rvalue/non-copyable succeeds
143       boost::sync_deque<non_copyable> q;
144       BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable(1)));
145       BOOST_TEST(! q.empty());
146       BOOST_TEST(! q.full());
147       BOOST_TEST_EQ(q.size(), 1u);
148       BOOST_TEST(! q.closed());
149   }
150 #endif
151   {
152     // empty queue try_push rvalue/non-copyable succeeds
153       boost::sync_deque<non_copyable> q;
154       non_copyable nc(1);
155       BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc)));
156       BOOST_TEST(! q.empty());
157       BOOST_TEST(! q.full());
158       BOOST_TEST_EQ(q.size(), 1u);
159       BOOST_TEST(! q.closed());
160   }
161 
162   {
163     // empty queue try_push lvalue succeeds
164       boost::sync_deque<int> q;
165       int i=1;
166       BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i));
167       BOOST_TEST(! q.empty());
168       BOOST_TEST(! q.full());
169       BOOST_TEST_EQ(q.size(), 1u);
170       BOOST_TEST(! q.closed());
171   }
172   {
173     // empty queue try_push rvalue succeeds
174       boost::sync_deque<int> q;
175       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1));
176       BOOST_TEST(! q.empty());
177       BOOST_TEST(! q.full());
178       BOOST_TEST_EQ(q.size(), 1u);
179       BOOST_TEST(! q.closed());
180   }
181 
182 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
183   {
184     // empty queue nonblocking_push_back rvalue/non-copyable succeeds
185       boost::sync_deque<non_copyable> q;
186       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1)));
187       BOOST_TEST(! q.empty());
188       BOOST_TEST(! q.full());
189       BOOST_TEST_EQ(q.size(), 1u);
190       BOOST_TEST(! q.closed());
191   }
192 #endif
193   {
194     // empty queue nonblocking_push_back rvalue/non-copyable succeeds
195       boost::sync_deque<non_copyable> q;
196       non_copyable nc(1);
197       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc)));
198       BOOST_TEST(! q.empty());
199       BOOST_TEST(! q.full());
200       BOOST_TEST_EQ(q.size(), 1u);
201       BOOST_TEST(! q.closed());
202   }
203   {
204     // 1-element queue pull_front succeed
205       boost::sync_deque<int> q;
206       q.push_back(1);
207       int i;
208       q.pull_front(i);
209       BOOST_TEST_EQ(i, 1);
210       BOOST_TEST(q.empty());
211       BOOST_TEST(! q.full());
212       BOOST_TEST_EQ(q.size(), 0u);
213       BOOST_TEST(! q.closed());
214   }
215   {
216     // 1-element queue pull_front succeed
217       boost::sync_deque<non_copyable> q;
218       non_copyable nc1(1);
219       q.push_back(boost::move(nc1));
220       non_copyable nc2(2);
221       q.pull_front(nc2);
222       BOOST_TEST_EQ(nc1, nc2);
223       BOOST_TEST(q.empty());
224       BOOST_TEST(! q.full());
225       BOOST_TEST_EQ(q.size(), 0u);
226       BOOST_TEST(! q.closed());
227   }
228   {
229     // 1-element queue pull_front succeed
230       boost::sync_deque<int> q;
231       q.push_back(1);
232       int i = q.pull_front();
233       BOOST_TEST_EQ(i, 1);
234       BOOST_TEST(q.empty());
235       BOOST_TEST(! q.full());
236       BOOST_TEST_EQ(q.size(), 0u);
237       BOOST_TEST(! q.closed());
238   }
239   {
240     // 1-element queue pull_front succeed
241       boost::sync_deque<non_copyable> q;
242       non_copyable nc1(1);
243       q.push_back(boost::move(nc1));
244       non_copyable nc = q.pull_front();
245       BOOST_TEST_EQ(nc, nc1);
246       BOOST_TEST(q.empty());
247       BOOST_TEST(! q.full());
248       BOOST_TEST_EQ(q.size(), 0u);
249       BOOST_TEST(! q.closed());
250   }
251   {
252     // 1-element queue try_pull_front succeed
253       boost::sync_deque<int> q;
254       q.push_back(1);
255       int i;
256       BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i));
257       BOOST_TEST_EQ(i, 1);
258       BOOST_TEST(q.empty());
259       BOOST_TEST(! q.full());
260       BOOST_TEST_EQ(q.size(), 0u);
261       BOOST_TEST(! q.closed());
262   }
263   {
264     // 1-element queue try_pull_front succeed
265       boost::sync_deque<non_copyable> q;
266       non_copyable nc1(1);
267       q.push_back(boost::move(nc1));
268       non_copyable nc(2);
269       BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc));
270       BOOST_TEST_EQ(nc, nc1);
271       BOOST_TEST(q.empty());
272       BOOST_TEST(! q.full());
273       BOOST_TEST_EQ(q.size(), 0u);
274       BOOST_TEST(! q.closed());
275   }
276   {
277     // 1-element queue nonblocking_pull_front succeed
278       boost::sync_deque<int> q;
279       q.push_back(1);
280       int i;
281       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i));
282       BOOST_TEST_EQ(i, 1);
283       BOOST_TEST(q.empty());
284       BOOST_TEST(! q.full());
285       BOOST_TEST_EQ(q.size(), 0u);
286       BOOST_TEST(! q.closed());
287   }
288   {
289     // 1-element queue nonblocking_pull_front succeed
290       boost::sync_deque<non_copyable> q;
291       non_copyable nc1(1);
292       q.push_back(boost::move(nc1));
293       non_copyable nc(2);
294       BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc));
295       BOOST_TEST_EQ(nc, nc1);
296       BOOST_TEST(q.empty());
297       BOOST_TEST(! q.full());
298       BOOST_TEST_EQ(q.size(), 0u);
299       BOOST_TEST(! q.closed());
300   }
301   {
302     // 1-element queue wait_pull_front succeed
303       boost::sync_deque<non_copyable> q;
304       non_copyable nc1(1);
305       q.push_back(boost::move(nc1));
306       non_copyable nc(2);
307       BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
308       BOOST_TEST_EQ(nc, nc1);
309       BOOST_TEST(q.empty());
310       BOOST_TEST(! q.full());
311       BOOST_TEST_EQ(q.size(), 0u);
312       BOOST_TEST(! q.closed());
313   }
314   {
315     // 1-element queue wait_pull_front succeed
316       boost::sync_deque<int> q;
317       q.push_back(1);
318       int i;
319       BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
320       BOOST_TEST_EQ(i, 1);
321       BOOST_TEST(q.empty());
322       BOOST_TEST(! q.full());
323       BOOST_TEST_EQ(q.size(), 0u);
324       BOOST_TEST(! q.closed());
325   }
326   {
327     // 1-element queue wait_pull_front succeed
328       boost::sync_deque<non_copyable> q;
329       non_copyable nc1(1);
330       q.push_back(boost::move(nc1));
331       non_copyable nc(2);
332       BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
333       BOOST_TEST_EQ(nc, nc1);
334       BOOST_TEST(q.empty());
335       BOOST_TEST(! q.full());
336       BOOST_TEST_EQ(q.size(), 0u);
337       BOOST_TEST(! q.closed());
338   }
339 
340   {
341     // closed invariants
342       boost::sync_deque<int> q;
343       q.close();
344       BOOST_TEST(q.empty());
345       BOOST_TEST(! q.full());
346       BOOST_TEST_EQ(q.size(), 0u);
347       BOOST_TEST(q.closed());
348   }
349   {
350     // closed queue push fails
351       boost::sync_deque<int> q;
352       q.close();
353       try {
354         q.push_back(1);
355         BOOST_TEST(false);
356       } catch (...) {
357         BOOST_TEST(q.empty());
358         BOOST_TEST(! q.full());
359         BOOST_TEST_EQ(q.size(), 0u);
360         BOOST_TEST(q.closed());
361       }
362   }
363   {
364     // 1-element closed queue pull succeed
365       boost::sync_deque<int> q;
366       q.push_back(1);
367       q.close();
368       int i;
369       q.pull_front(i);
370       BOOST_TEST_EQ(i, 1);
371       BOOST_TEST(q.empty());
372       BOOST_TEST(! q.full());
373       BOOST_TEST_EQ(q.size(), 0u);
374       BOOST_TEST(q.closed());
375   }
376   {
377     // 1-element closed queue wait_pull_front succeed
378       boost::sync_deque<int> q;
379       q.push_back(1);
380       q.close();
381       int i;
382       BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
383       BOOST_TEST_EQ(i, 1);
384       BOOST_TEST(q.empty());
385       BOOST_TEST(! q.full());
386       BOOST_TEST_EQ(q.size(), 0u);
387       BOOST_TEST(q.closed());
388   }
389   {
390     // closed empty queue wait_pull_front fails
391       boost::sync_deque<int> q;
392       q.close();
393       BOOST_TEST(q.empty());
394       BOOST_TEST(q.closed());
395       int i;
396       BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i));
397       BOOST_TEST(q.empty());
398       BOOST_TEST(q.closed());
399   }
400 
401   return boost::report_errors();
402 }
403 
404