|
1 /* |
|
2 Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
3 |
|
4 Redistribution and use in source and binary forms, with or without |
|
5 modification, are permitted provided that the following conditions are met: |
|
6 |
|
7 * Redistributions of source code must retain the above copyright notice, this |
|
8 list of conditions and the following disclaimer. |
|
9 * Redistributions in binary form must reproduce the above copyright notice, |
|
10 this list of conditions and the following disclaimer in the documentation |
|
11 and/or other materials provided with the distribution. |
|
12 * Neither the name of Nokia Corporation nor the names of its contributors |
|
13 may be used to endorse or promote products derived from this software |
|
14 without specific prior written permission. |
|
15 |
|
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
|
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
26 |
|
27 * Description: |
|
28 * |
|
29 */ |
|
30 |
|
31 |
|
32 |
|
33 #include <boost/config.hpp> |
|
34 |
|
35 #ifdef __SYMBIAN32__ |
|
36 #include "std_log_result.h" |
|
37 #define LOG_FILENAME_LINE __FILE__, __LINE__ |
|
38 #endif |
|
39 |
|
40 #if defined(BOOST_MSVC) |
|
41 |
|
42 #pragma warning(disable: 4786) // identifier truncated in debug info |
|
43 #pragma warning(disable: 4710) // function not inlined |
|
44 #pragma warning(disable: 4711) // function selected for automatic inline expansion |
|
45 #pragma warning(disable: 4514) // unreferenced inline removed |
|
46 #pragma warning(disable: 4355) // 'this' : used in base member initializer list |
|
47 #pragma warning(disable: 4511) // copy constructor could not be generated |
|
48 #pragma warning(disable: 4512) // assignment operator could not be generated |
|
49 |
|
50 #if (BOOST_MSVC >= 1310) |
|
51 #pragma warning(disable: 4675) // resolved overload found with Koenig lookup |
|
52 #endif |
|
53 |
|
54 #endif |
|
55 |
|
56 // |
|
57 // intrusive_ptr_test.cpp |
|
58 // |
|
59 // Copyright (c) 2002-2005 Peter Dimov |
|
60 // |
|
61 // Distributed under the Boost Software License, Version 1.0. (See |
|
62 // accompanying file LICENSE_1_0.txt or copy at |
|
63 // http://www.boost.org/LICENSE_1_0.txt) |
|
64 // |
|
65 |
|
66 #include <boost/detail/lightweight_test.hpp> |
|
67 #include <boost/intrusive_ptr.hpp> |
|
68 #include <boost/detail/atomic_count.hpp> |
|
69 #include <boost/config.hpp> |
|
70 #include <algorithm> |
|
71 #include <functional> |
|
72 |
|
73 // |
|
74 |
|
75 namespace N |
|
76 { |
|
77 |
|
78 class base |
|
79 { |
|
80 private: |
|
81 |
|
82 boost::detail::atomic_count use_count_; |
|
83 |
|
84 base(base const &); |
|
85 base & operator=(base const &); |
|
86 |
|
87 protected: |
|
88 |
|
89 base(): use_count_(0) |
|
90 { |
|
91 } |
|
92 |
|
93 virtual ~base() |
|
94 { |
|
95 } |
|
96 |
|
97 public: |
|
98 |
|
99 long use_count() const |
|
100 { |
|
101 return use_count_; |
|
102 } |
|
103 |
|
104 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
105 |
|
106 inline friend void intrusive_ptr_add_ref(base * p) |
|
107 { |
|
108 ++p->use_count_; |
|
109 } |
|
110 |
|
111 inline friend void intrusive_ptr_release(base * p) |
|
112 { |
|
113 if(--p->use_count_ == 0) delete p; |
|
114 } |
|
115 |
|
116 #else |
|
117 |
|
118 void add_ref() |
|
119 { |
|
120 ++use_count_; |
|
121 } |
|
122 |
|
123 void release() |
|
124 { |
|
125 if(--use_count_ == 0) delete this; |
|
126 } |
|
127 |
|
128 #endif |
|
129 }; |
|
130 |
|
131 } // namespace N |
|
132 |
|
133 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
134 |
|
135 namespace boost |
|
136 { |
|
137 |
|
138 inline void intrusive_ptr_add_ref(N::base * p) |
|
139 { |
|
140 p->add_ref(); |
|
141 } |
|
142 |
|
143 inline void intrusive_ptr_release(N::base * p) |
|
144 { |
|
145 p->release(); |
|
146 } |
|
147 |
|
148 } // namespace boost |
|
149 |
|
150 #endif |
|
151 |
|
152 // |
|
153 |
|
154 struct X: public virtual N::base |
|
155 { |
|
156 }; |
|
157 |
|
158 struct Y: public X |
|
159 { |
|
160 }; |
|
161 |
|
162 // |
|
163 |
|
164 namespace n_element_type |
|
165 { |
|
166 |
|
167 void f(X &) |
|
168 { |
|
169 } |
|
170 |
|
171 void test() |
|
172 { |
|
173 typedef boost::intrusive_ptr<X>::element_type T; |
|
174 T t; |
|
175 f(t); |
|
176 } |
|
177 |
|
178 } // namespace n_element_type |
|
179 |
|
180 namespace n_constructors |
|
181 { |
|
182 |
|
183 void default_constructor() |
|
184 { |
|
185 boost::intrusive_ptr<X> px; |
|
186 BOOST_TEST(px.get() == 0); |
|
187 } |
|
188 |
|
189 void pointer_constructor() |
|
190 { |
|
191 { |
|
192 boost::intrusive_ptr<X> px(0); |
|
193 BOOST_TEST(px.get() == 0); |
|
194 } |
|
195 |
|
196 { |
|
197 boost::intrusive_ptr<X> px(0, false); |
|
198 BOOST_TEST(px.get() == 0); |
|
199 } |
|
200 |
|
201 { |
|
202 X * p = new X; |
|
203 BOOST_TEST(p->use_count() == 0); |
|
204 |
|
205 boost::intrusive_ptr<X> px(p); |
|
206 BOOST_TEST(px.get() == p); |
|
207 BOOST_TEST(px->use_count() == 1); |
|
208 } |
|
209 |
|
210 { |
|
211 X * p = new X; |
|
212 BOOST_TEST(p->use_count() == 0); |
|
213 |
|
214 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
215 using boost::intrusive_ptr_add_ref; |
|
216 #endif |
|
217 intrusive_ptr_add_ref(p); |
|
218 BOOST_TEST(p->use_count() == 1); |
|
219 |
|
220 boost::intrusive_ptr<X> px(p, false); |
|
221 BOOST_TEST(px.get() == p); |
|
222 BOOST_TEST(px->use_count() == 1); |
|
223 } |
|
224 } |
|
225 |
|
226 void copy_constructor() |
|
227 { |
|
228 { |
|
229 boost::intrusive_ptr<X> px; |
|
230 boost::intrusive_ptr<X> px2(px); |
|
231 BOOST_TEST(px2.get() == px.get()); |
|
232 } |
|
233 |
|
234 { |
|
235 boost::intrusive_ptr<Y> py; |
|
236 boost::intrusive_ptr<X> px(py); |
|
237 BOOST_TEST(px.get() == py.get()); |
|
238 } |
|
239 |
|
240 { |
|
241 boost::intrusive_ptr<X> px(0); |
|
242 boost::intrusive_ptr<X> px2(px); |
|
243 BOOST_TEST(px2.get() == px.get()); |
|
244 } |
|
245 |
|
246 { |
|
247 boost::intrusive_ptr<Y> py(0); |
|
248 boost::intrusive_ptr<X> px(py); |
|
249 BOOST_TEST(px.get() == py.get()); |
|
250 } |
|
251 |
|
252 { |
|
253 boost::intrusive_ptr<X> px(0, false); |
|
254 boost::intrusive_ptr<X> px2(px); |
|
255 BOOST_TEST(px2.get() == px.get()); |
|
256 } |
|
257 |
|
258 { |
|
259 boost::intrusive_ptr<Y> py(0, false); |
|
260 boost::intrusive_ptr<X> px(py); |
|
261 BOOST_TEST(px.get() == py.get()); |
|
262 } |
|
263 |
|
264 { |
|
265 boost::intrusive_ptr<X> px(new X); |
|
266 boost::intrusive_ptr<X> px2(px); |
|
267 BOOST_TEST(px2.get() == px.get()); |
|
268 } |
|
269 |
|
270 { |
|
271 boost::intrusive_ptr<Y> py(new Y); |
|
272 boost::intrusive_ptr<X> px(py); |
|
273 BOOST_TEST(px.get() == py.get()); |
|
274 } |
|
275 } |
|
276 |
|
277 void test() |
|
278 { |
|
279 default_constructor(); |
|
280 pointer_constructor(); |
|
281 copy_constructor(); |
|
282 } |
|
283 |
|
284 } // namespace n_constructors |
|
285 |
|
286 namespace n_destructor |
|
287 { |
|
288 |
|
289 void test() |
|
290 { |
|
291 boost::intrusive_ptr<X> px(new X); |
|
292 BOOST_TEST(px->use_count() == 1); |
|
293 |
|
294 { |
|
295 boost::intrusive_ptr<X> px2(px); |
|
296 BOOST_TEST(px->use_count() == 2); |
|
297 } |
|
298 |
|
299 BOOST_TEST(px->use_count() == 1); |
|
300 } |
|
301 |
|
302 } // namespace n_destructor |
|
303 |
|
304 namespace n_assignment |
|
305 { |
|
306 |
|
307 void copy_assignment() |
|
308 { |
|
309 } |
|
310 |
|
311 void conversion_assignment() |
|
312 { |
|
313 } |
|
314 |
|
315 void pointer_assignment() |
|
316 { |
|
317 } |
|
318 |
|
319 void test() |
|
320 { |
|
321 copy_assignment(); |
|
322 conversion_assignment(); |
|
323 pointer_assignment(); |
|
324 } |
|
325 |
|
326 } // namespace n_assignment |
|
327 |
|
328 namespace n_access |
|
329 { |
|
330 |
|
331 void test() |
|
332 { |
|
333 { |
|
334 boost::intrusive_ptr<X> px; |
|
335 BOOST_TEST(px? false: true); |
|
336 BOOST_TEST(!px); |
|
337 |
|
338 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
339 using boost::get_pointer; |
|
340 #endif |
|
341 |
|
342 BOOST_TEST(get_pointer(px) == px.get()); |
|
343 } |
|
344 |
|
345 { |
|
346 boost::intrusive_ptr<X> px(0); |
|
347 BOOST_TEST(px? false: true); |
|
348 BOOST_TEST(!px); |
|
349 |
|
350 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
351 using boost::get_pointer; |
|
352 #endif |
|
353 |
|
354 BOOST_TEST(get_pointer(px) == px.get()); |
|
355 } |
|
356 |
|
357 { |
|
358 boost::intrusive_ptr<X> px(new X); |
|
359 BOOST_TEST(px? true: false); |
|
360 BOOST_TEST(!!px); |
|
361 BOOST_TEST(&*px == px.get()); |
|
362 BOOST_TEST(px.operator ->() == px.get()); |
|
363 |
|
364 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
|
365 using boost::get_pointer; |
|
366 #endif |
|
367 |
|
368 BOOST_TEST(get_pointer(px) == px.get()); |
|
369 } |
|
370 } |
|
371 |
|
372 } // namespace n_access |
|
373 |
|
374 namespace n_swap |
|
375 { |
|
376 |
|
377 void test() |
|
378 { |
|
379 { |
|
380 boost::intrusive_ptr<X> px; |
|
381 boost::intrusive_ptr<X> px2; |
|
382 |
|
383 px.swap(px2); |
|
384 |
|
385 BOOST_TEST(px.get() == 0); |
|
386 BOOST_TEST(px2.get() == 0); |
|
387 |
|
388 using std::swap; |
|
389 swap(px, px2); |
|
390 |
|
391 BOOST_TEST(px.get() == 0); |
|
392 BOOST_TEST(px2.get() == 0); |
|
393 } |
|
394 |
|
395 { |
|
396 X * p = new X; |
|
397 boost::intrusive_ptr<X> px; |
|
398 boost::intrusive_ptr<X> px2(p); |
|
399 boost::intrusive_ptr<X> px3(px2); |
|
400 |
|
401 px.swap(px2); |
|
402 |
|
403 BOOST_TEST(px.get() == p); |
|
404 BOOST_TEST(px->use_count() == 2); |
|
405 BOOST_TEST(px2.get() == 0); |
|
406 BOOST_TEST(px3.get() == p); |
|
407 BOOST_TEST(px3->use_count() == 2); |
|
408 |
|
409 using std::swap; |
|
410 swap(px, px2); |
|
411 |
|
412 BOOST_TEST(px.get() == 0); |
|
413 BOOST_TEST(px2.get() == p); |
|
414 BOOST_TEST(px2->use_count() == 2); |
|
415 BOOST_TEST(px3.get() == p); |
|
416 BOOST_TEST(px3->use_count() == 2); |
|
417 } |
|
418 |
|
419 { |
|
420 X * p1 = new X; |
|
421 X * p2 = new X; |
|
422 boost::intrusive_ptr<X> px(p1); |
|
423 boost::intrusive_ptr<X> px2(p2); |
|
424 boost::intrusive_ptr<X> px3(px2); |
|
425 |
|
426 px.swap(px2); |
|
427 |
|
428 BOOST_TEST(px.get() == p2); |
|
429 BOOST_TEST(px->use_count() == 2); |
|
430 BOOST_TEST(px2.get() == p1); |
|
431 BOOST_TEST(px2->use_count() == 1); |
|
432 BOOST_TEST(px3.get() == p2); |
|
433 BOOST_TEST(px3->use_count() == 2); |
|
434 |
|
435 using std::swap; |
|
436 swap(px, px2); |
|
437 |
|
438 BOOST_TEST(px.get() == p1); |
|
439 BOOST_TEST(px->use_count() == 1); |
|
440 BOOST_TEST(px2.get() == p2); |
|
441 BOOST_TEST(px2->use_count() == 2); |
|
442 BOOST_TEST(px3.get() == p2); |
|
443 BOOST_TEST(px3->use_count() == 2); |
|
444 } |
|
445 } |
|
446 |
|
447 } // namespace n_swap |
|
448 |
|
449 namespace n_comparison |
|
450 { |
|
451 |
|
452 template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q) |
|
453 { |
|
454 BOOST_TEST((p == q) == (p.get() == q.get())); |
|
455 BOOST_TEST((p != q) == (p.get() != q.get())); |
|
456 } |
|
457 |
|
458 template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q) |
|
459 { |
|
460 BOOST_TEST((p == q) == (p.get() == q.get())); |
|
461 BOOST_TEST((p.get() == q) == (p.get() == q.get())); |
|
462 BOOST_TEST((p == q.get()) == (p.get() == q.get())); |
|
463 BOOST_TEST((p != q) == (p.get() != q.get())); |
|
464 BOOST_TEST((p.get() != q) == (p.get() != q.get())); |
|
465 BOOST_TEST((p != q.get()) == (p.get() != q.get())); |
|
466 |
|
467 // 'less' moved here as a g++ 2.9x parse error workaround |
|
468 std::less<T*> less; |
|
469 BOOST_TEST((p < q) == less(p.get(), q.get())); |
|
470 } |
|
471 |
|
472 void test() |
|
473 { |
|
474 { |
|
475 boost::intrusive_ptr<X> px; |
|
476 test3(px, px); |
|
477 |
|
478 boost::intrusive_ptr<X> px2; |
|
479 test3(px, px2); |
|
480 |
|
481 boost::intrusive_ptr<X> px3(px); |
|
482 test3(px3, px3); |
|
483 test3(px, px3); |
|
484 } |
|
485 |
|
486 { |
|
487 boost::intrusive_ptr<X> px; |
|
488 |
|
489 boost::intrusive_ptr<X> px2(new X); |
|
490 test3(px, px2); |
|
491 test3(px2, px2); |
|
492 |
|
493 boost::intrusive_ptr<X> px3(new X); |
|
494 test3(px2, px3); |
|
495 |
|
496 boost::intrusive_ptr<X> px4(px2); |
|
497 test3(px2, px4); |
|
498 test3(px4, px4); |
|
499 } |
|
500 |
|
501 { |
|
502 boost::intrusive_ptr<X> px(new X); |
|
503 |
|
504 boost::intrusive_ptr<Y> py(new Y); |
|
505 test2(px, py); |
|
506 |
|
507 boost::intrusive_ptr<X> px2(py); |
|
508 test2(px2, py); |
|
509 test3(px, px2); |
|
510 test3(px2, px2); |
|
511 } |
|
512 } |
|
513 |
|
514 } // namespace n_comparison |
|
515 |
|
516 namespace n_static_cast |
|
517 { |
|
518 |
|
519 void test() |
|
520 { |
|
521 } |
|
522 |
|
523 } // namespace n_static_cast |
|
524 |
|
525 namespace n_dynamic_cast |
|
526 { |
|
527 |
|
528 void test() |
|
529 { |
|
530 } |
|
531 |
|
532 } // namespace n_dynamic_cast |
|
533 |
|
534 namespace n_transitive |
|
535 { |
|
536 |
|
537 struct X: public N::base |
|
538 { |
|
539 boost::intrusive_ptr<X> next; |
|
540 }; |
|
541 |
|
542 void test() |
|
543 { |
|
544 boost::intrusive_ptr<X> p(new X); |
|
545 p->next = boost::intrusive_ptr<X>(new X); |
|
546 BOOST_TEST(!p->next->next); |
|
547 p = p->next; |
|
548 BOOST_TEST(!p->next); |
|
549 } |
|
550 |
|
551 } // namespace n_transitive |
|
552 |
|
553 namespace n_report_1 |
|
554 { |
|
555 |
|
556 class foo: public N::base |
|
557 { |
|
558 public: |
|
559 |
|
560 foo(): m_self(this) |
|
561 { |
|
562 } |
|
563 |
|
564 void suicide() |
|
565 { |
|
566 m_self = 0; |
|
567 } |
|
568 |
|
569 private: |
|
570 |
|
571 boost::intrusive_ptr<foo> m_self; |
|
572 }; |
|
573 |
|
574 void test() |
|
575 { |
|
576 foo * foo_ptr = new foo; |
|
577 foo_ptr->suicide(); |
|
578 } |
|
579 |
|
580 } // namespace n_report_1 |
|
581 |
|
582 int main() |
|
583 { |
|
584 std_log(LOG_FILENAME_LINE,"[Test Case for intrusive_ptr_test]"); |
|
585 n_element_type::test(); |
|
586 n_constructors::test(); |
|
587 n_destructor::test(); |
|
588 n_assignment::test(); |
|
589 n_access::test(); |
|
590 n_swap::test(); |
|
591 n_comparison::test(); |
|
592 n_static_cast::test(); |
|
593 n_dynamic_cast::test(); |
|
594 |
|
595 n_transitive::test(); |
|
596 n_report_1::test(); |
|
597 |
|
598 #ifdef __SYMBIAN32__ |
|
599 int failures = boost::report_errors(); |
|
600 if(failures) |
|
601 { |
|
602 std_log(LOG_FILENAME_LINE,"Result : Failed"); |
|
603 assert_failed = true; |
|
604 } |
|
605 else |
|
606 { |
|
607 std_log(LOG_FILENAME_LINE,"Result : Passed"); |
|
608 } |
|
609 std_log(LOG_FILENAME_LINE,"[End Test Case ]"); |
|
610 #endif |
|
611 testResultXml("intrusive_ptr_test"); |
|
612 close_log_file(); |
|
613 return failures; |
|
614 } |