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