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