]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <boost/config.hpp> |
2 | ||
3 | #if defined(BOOST_MSVC) | |
4 | ||
5 | #pragma warning(disable: 4786) // identifier truncated in debug info | |
6 | #pragma warning(disable: 4710) // function not inlined | |
7 | #pragma warning(disable: 4711) // function selected for automatic inline expansion | |
8 | #pragma warning(disable: 4514) // unreferenced inline removed | |
9 | #pragma warning(disable: 4355) // 'this' : used in base member initializer list | |
10 | #pragma warning(disable: 4511) // copy constructor could not be generated | |
11 | #pragma warning(disable: 4512) // assignment operator could not be generated | |
12 | ||
13 | #if (BOOST_MSVC >= 1310) | |
14 | #pragma warning(disable: 4675) // resolved overload found with Koenig lookup | |
15 | #endif | |
16 | ||
17 | #endif | |
18 | ||
19 | // | |
20 | // intrusive_ptr_test.cpp | |
21 | // | |
22 | // Copyright (c) 2002-2005 Peter Dimov | |
23 | // | |
24 | // Distributed under the Boost Software License, Version 1.0. (See | |
25 | // accompanying file LICENSE_1_0.txt or copy at | |
26 | // http://www.boost.org/LICENSE_1_0.txt) | |
27 | // | |
28 | ||
f67539c2 | 29 | #include <boost/core/lightweight_test.hpp> |
7c673cae FG |
30 | #include <boost/intrusive_ptr.hpp> |
31 | #include <boost/detail/atomic_count.hpp> | |
32 | #include <boost/config.hpp> | |
33 | #include <algorithm> | |
34 | #include <functional> | |
35 | ||
36 | // | |
37 | ||
38 | namespace N | |
39 | { | |
40 | ||
41 | class base | |
42 | { | |
43 | private: | |
44 | ||
92f5a8d4 | 45 | mutable boost::detail::atomic_count use_count_; |
7c673cae FG |
46 | |
47 | base(base const &); | |
48 | base & operator=(base const &); | |
49 | ||
50 | protected: | |
51 | ||
52 | base(): use_count_(0) | |
53 | { | |
54 | ++instances; | |
55 | } | |
56 | ||
57 | virtual ~base() | |
58 | { | |
59 | --instances; | |
60 | } | |
61 | ||
62 | public: | |
63 | ||
64 | static long instances; | |
65 | ||
66 | long use_count() const | |
67 | { | |
68 | return use_count_; | |
69 | } | |
70 | ||
71 | #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
72 | ||
92f5a8d4 | 73 | inline friend void intrusive_ptr_add_ref(base const * p) |
7c673cae FG |
74 | { |
75 | ++p->use_count_; | |
76 | } | |
77 | ||
92f5a8d4 | 78 | inline friend void intrusive_ptr_release(base const * p) |
7c673cae FG |
79 | { |
80 | if(--p->use_count_ == 0) delete p; | |
81 | } | |
82 | ||
83 | #else | |
84 | ||
92f5a8d4 | 85 | void add_ref() const |
7c673cae FG |
86 | { |
87 | ++use_count_; | |
88 | } | |
89 | ||
92f5a8d4 | 90 | void release() const |
7c673cae FG |
91 | { |
92 | if(--use_count_ == 0) delete this; | |
93 | } | |
94 | ||
95 | #endif | |
96 | }; | |
97 | ||
98 | long base::instances = 0; | |
99 | ||
100 | } // namespace N | |
101 | ||
102 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
103 | ||
104 | namespace boost | |
105 | { | |
106 | ||
92f5a8d4 | 107 | inline void intrusive_ptr_add_ref(N::base const * p) |
7c673cae FG |
108 | { |
109 | p->add_ref(); | |
110 | } | |
111 | ||
92f5a8d4 | 112 | inline void intrusive_ptr_release(N::base const * p) |
7c673cae FG |
113 | { |
114 | p->release(); | |
115 | } | |
116 | ||
117 | } // namespace boost | |
118 | ||
119 | #endif | |
120 | ||
121 | // | |
122 | ||
123 | struct X: public virtual N::base | |
124 | { | |
125 | }; | |
126 | ||
127 | struct Y: public X | |
128 | { | |
129 | }; | |
130 | ||
131 | // | |
132 | ||
133 | namespace n_element_type | |
134 | { | |
135 | ||
136 | void f(X &) | |
137 | { | |
138 | } | |
139 | ||
140 | void test() | |
141 | { | |
142 | typedef boost::intrusive_ptr<X>::element_type T; | |
143 | T t; | |
144 | f(t); | |
145 | } | |
146 | ||
147 | } // namespace n_element_type | |
148 | ||
149 | namespace n_constructors | |
150 | { | |
151 | ||
152 | void default_constructor() | |
153 | { | |
154 | boost::intrusive_ptr<X> px; | |
155 | BOOST_TEST(px.get() == 0); | |
156 | } | |
157 | ||
158 | void pointer_constructor() | |
159 | { | |
160 | { | |
161 | boost::intrusive_ptr<X> px(0); | |
162 | BOOST_TEST(px.get() == 0); | |
163 | } | |
164 | ||
165 | { | |
166 | boost::intrusive_ptr<X> px(0, false); | |
167 | BOOST_TEST(px.get() == 0); | |
168 | } | |
169 | ||
170 | BOOST_TEST( N::base::instances == 0 ); | |
171 | ||
172 | { | |
173 | X * p = new X; | |
174 | BOOST_TEST(p->use_count() == 0); | |
175 | ||
176 | BOOST_TEST( N::base::instances == 1 ); | |
177 | ||
178 | boost::intrusive_ptr<X> px(p); | |
179 | BOOST_TEST(px.get() == p); | |
180 | BOOST_TEST(px->use_count() == 1); | |
181 | } | |
182 | ||
183 | BOOST_TEST( N::base::instances == 0 ); | |
184 | ||
185 | { | |
186 | X * p = new X; | |
187 | BOOST_TEST(p->use_count() == 0); | |
188 | ||
189 | BOOST_TEST( N::base::instances == 1 ); | |
190 | ||
191 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
192 | using boost::intrusive_ptr_add_ref; | |
193 | #endif | |
194 | intrusive_ptr_add_ref(p); | |
195 | BOOST_TEST(p->use_count() == 1); | |
196 | ||
197 | boost::intrusive_ptr<X> px(p, false); | |
198 | BOOST_TEST(px.get() == p); | |
199 | BOOST_TEST(px->use_count() == 1); | |
200 | } | |
201 | ||
202 | BOOST_TEST( N::base::instances == 0 ); | |
203 | } | |
204 | ||
205 | void copy_constructor() | |
206 | { | |
207 | { | |
208 | boost::intrusive_ptr<X> px; | |
209 | boost::intrusive_ptr<X> px2(px); | |
210 | BOOST_TEST(px2.get() == px.get()); | |
211 | } | |
212 | ||
213 | { | |
214 | boost::intrusive_ptr<Y> py; | |
215 | boost::intrusive_ptr<X> px(py); | |
216 | BOOST_TEST(px.get() == py.get()); | |
217 | } | |
218 | ||
219 | { | |
220 | boost::intrusive_ptr<X> px(0); | |
221 | boost::intrusive_ptr<X> px2(px); | |
222 | BOOST_TEST(px2.get() == px.get()); | |
223 | } | |
224 | ||
225 | { | |
226 | boost::intrusive_ptr<Y> py(0); | |
227 | boost::intrusive_ptr<X> px(py); | |
228 | BOOST_TEST(px.get() == py.get()); | |
229 | } | |
230 | ||
231 | { | |
232 | boost::intrusive_ptr<X> px(0, false); | |
233 | boost::intrusive_ptr<X> px2(px); | |
234 | BOOST_TEST(px2.get() == px.get()); | |
235 | } | |
236 | ||
237 | { | |
238 | boost::intrusive_ptr<Y> py(0, false); | |
239 | boost::intrusive_ptr<X> px(py); | |
240 | BOOST_TEST(px.get() == py.get()); | |
241 | } | |
242 | ||
243 | BOOST_TEST( N::base::instances == 0 ); | |
244 | ||
245 | { | |
246 | boost::intrusive_ptr<X> px(new X); | |
247 | boost::intrusive_ptr<X> px2(px); | |
248 | BOOST_TEST( px2.get() == px.get() ); | |
249 | ||
250 | BOOST_TEST( N::base::instances == 1 ); | |
251 | } | |
252 | ||
253 | BOOST_TEST( N::base::instances == 0 ); | |
254 | ||
255 | { | |
256 | boost::intrusive_ptr<Y> py(new Y); | |
257 | boost::intrusive_ptr<X> px(py); | |
258 | BOOST_TEST( px.get() == py.get() ); | |
259 | ||
260 | BOOST_TEST( N::base::instances == 1 ); | |
261 | } | |
262 | ||
263 | BOOST_TEST( N::base::instances == 0 ); | |
264 | } | |
265 | ||
266 | void test() | |
267 | { | |
268 | default_constructor(); | |
269 | pointer_constructor(); | |
270 | copy_constructor(); | |
271 | } | |
272 | ||
273 | } // namespace n_constructors | |
274 | ||
275 | namespace n_destructor | |
276 | { | |
277 | ||
278 | void test() | |
279 | { | |
280 | BOOST_TEST( N::base::instances == 0 ); | |
281 | ||
282 | { | |
283 | boost::intrusive_ptr<X> px(new X); | |
284 | BOOST_TEST(px->use_count() == 1); | |
285 | ||
286 | BOOST_TEST( N::base::instances == 1 ); | |
287 | ||
288 | { | |
289 | boost::intrusive_ptr<X> px2(px); | |
290 | BOOST_TEST(px->use_count() == 2); | |
291 | } | |
292 | ||
293 | BOOST_TEST(px->use_count() == 1); | |
294 | } | |
295 | ||
296 | BOOST_TEST( N::base::instances == 0 ); | |
297 | } | |
298 | ||
299 | } // namespace n_destructor | |
300 | ||
301 | namespace n_assignment | |
302 | { | |
303 | ||
304 | void copy_assignment() | |
305 | { | |
92f5a8d4 TL |
306 | BOOST_TEST( N::base::instances == 0 ); |
307 | ||
308 | { | |
309 | boost::intrusive_ptr<X> p1; | |
310 | ||
311 | p1 = p1; | |
312 | ||
313 | BOOST_TEST(p1 == p1); | |
314 | BOOST_TEST(p1? false: true); | |
315 | BOOST_TEST(!p1); | |
316 | BOOST_TEST(p1.get() == 0); | |
317 | ||
318 | boost::intrusive_ptr<X> p2; | |
319 | ||
320 | p1 = p2; | |
321 | ||
322 | BOOST_TEST(p1 == p2); | |
323 | BOOST_TEST(p1? false: true); | |
324 | BOOST_TEST(!p1); | |
325 | BOOST_TEST(p1.get() == 0); | |
326 | ||
327 | boost::intrusive_ptr<X> p3(p1); | |
328 | ||
329 | p1 = p3; | |
330 | ||
331 | BOOST_TEST(p1 == p3); | |
332 | BOOST_TEST(p1? false: true); | |
333 | BOOST_TEST(!p1); | |
334 | BOOST_TEST(p1.get() == 0); | |
335 | ||
336 | BOOST_TEST(N::base::instances == 0); | |
337 | ||
338 | boost::intrusive_ptr<X> p4(new X); | |
339 | ||
340 | BOOST_TEST(N::base::instances == 1); | |
341 | ||
342 | p1 = p4; | |
343 | ||
344 | BOOST_TEST(N::base::instances == 1); | |
345 | ||
346 | BOOST_TEST(p1 == p4); | |
347 | ||
348 | BOOST_TEST(p1->use_count() == 2); | |
349 | ||
350 | p1 = p2; | |
351 | ||
352 | BOOST_TEST(p1 == p2); | |
353 | BOOST_TEST(N::base::instances == 1); | |
354 | ||
355 | p4 = p3; | |
356 | ||
357 | BOOST_TEST(p4 == p3); | |
358 | BOOST_TEST(N::base::instances == 0); | |
359 | } | |
7c673cae FG |
360 | } |
361 | ||
362 | void conversion_assignment() | |
363 | { | |
92f5a8d4 TL |
364 | BOOST_TEST( N::base::instances == 0 ); |
365 | ||
366 | { | |
367 | boost::intrusive_ptr<X> p1; | |
368 | ||
369 | boost::intrusive_ptr<Y> p2; | |
370 | ||
371 | p1 = p2; | |
372 | ||
373 | BOOST_TEST(p1 == p2); | |
374 | BOOST_TEST(p1? false: true); | |
375 | BOOST_TEST(!p1); | |
376 | BOOST_TEST(p1.get() == 0); | |
377 | ||
378 | BOOST_TEST(N::base::instances == 0); | |
379 | ||
380 | boost::intrusive_ptr<Y> p4(new Y); | |
381 | ||
382 | BOOST_TEST(N::base::instances == 1); | |
383 | BOOST_TEST(p4->use_count() == 1); | |
384 | ||
385 | boost::intrusive_ptr<X> p5(p4); | |
386 | BOOST_TEST(p4->use_count() == 2); | |
387 | ||
388 | p1 = p4; | |
389 | ||
390 | BOOST_TEST(N::base::instances == 1); | |
391 | ||
392 | BOOST_TEST(p1 == p4); | |
393 | ||
394 | BOOST_TEST(p1->use_count() == 3); | |
395 | BOOST_TEST(p4->use_count() == 3); | |
396 | ||
397 | p1 = p2; | |
398 | ||
399 | BOOST_TEST(p1 == p2); | |
400 | BOOST_TEST(N::base::instances == 1); | |
401 | BOOST_TEST(p4->use_count() == 2); | |
402 | ||
403 | p4 = p2; | |
404 | p5 = p2; | |
405 | ||
406 | BOOST_TEST(p4 == p2); | |
407 | BOOST_TEST(N::base::instances == 0); | |
408 | } | |
7c673cae FG |
409 | } |
410 | ||
411 | void pointer_assignment() | |
412 | { | |
92f5a8d4 TL |
413 | BOOST_TEST( N::base::instances == 0 ); |
414 | ||
415 | { | |
416 | boost::intrusive_ptr<X> p1; | |
417 | ||
418 | p1 = p1.get(); | |
419 | ||
420 | BOOST_TEST(p1 == p1); | |
421 | BOOST_TEST(p1? false: true); | |
422 | BOOST_TEST(!p1); | |
423 | BOOST_TEST(p1.get() == 0); | |
424 | ||
425 | boost::intrusive_ptr<X> p2; | |
426 | ||
427 | p1 = p2.get(); | |
428 | ||
429 | BOOST_TEST(p1 == p2); | |
430 | BOOST_TEST(p1? false: true); | |
431 | BOOST_TEST(!p1); | |
432 | BOOST_TEST(p1.get() == 0); | |
433 | ||
434 | boost::intrusive_ptr<X> p3(p1); | |
435 | ||
436 | p1 = p3.get(); | |
437 | ||
438 | BOOST_TEST(p1 == p3); | |
439 | BOOST_TEST(p1? false: true); | |
440 | BOOST_TEST(!p1); | |
441 | BOOST_TEST(p1.get() == 0); | |
442 | ||
443 | BOOST_TEST(N::base::instances == 0); | |
444 | ||
445 | boost::intrusive_ptr<X> p4(new X); | |
446 | ||
447 | BOOST_TEST(N::base::instances == 1); | |
448 | ||
449 | p1 = p4.get(); | |
450 | ||
451 | BOOST_TEST(N::base::instances == 1); | |
452 | ||
453 | BOOST_TEST(p1 == p4); | |
454 | ||
455 | BOOST_TEST(p1->use_count() == 2); | |
456 | ||
457 | p1 = p2.get(); | |
458 | ||
459 | BOOST_TEST(p1 == p2); | |
460 | BOOST_TEST(N::base::instances == 1); | |
461 | ||
462 | p4 = p3.get(); | |
463 | ||
464 | BOOST_TEST(p4 == p3); | |
465 | BOOST_TEST(N::base::instances == 0); | |
466 | } | |
467 | ||
468 | { | |
469 | boost::intrusive_ptr<X> p1; | |
470 | ||
471 | boost::intrusive_ptr<Y> p2; | |
472 | ||
473 | p1 = p2.get(); | |
474 | ||
475 | BOOST_TEST(p1 == p2); | |
476 | BOOST_TEST(p1? false: true); | |
477 | BOOST_TEST(!p1); | |
478 | BOOST_TEST(p1.get() == 0); | |
479 | ||
480 | BOOST_TEST(N::base::instances == 0); | |
481 | ||
482 | boost::intrusive_ptr<Y> p4(new Y); | |
483 | ||
484 | BOOST_TEST(N::base::instances == 1); | |
485 | BOOST_TEST(p4->use_count() == 1); | |
486 | ||
487 | boost::intrusive_ptr<X> p5(p4); | |
488 | BOOST_TEST(p4->use_count() == 2); | |
489 | ||
490 | p1 = p4.get(); | |
491 | ||
492 | BOOST_TEST(N::base::instances == 1); | |
493 | ||
494 | BOOST_TEST(p1 == p4); | |
495 | ||
496 | BOOST_TEST(p1->use_count() == 3); | |
497 | BOOST_TEST(p4->use_count() == 3); | |
498 | ||
499 | p1 = p2.get(); | |
500 | ||
501 | BOOST_TEST(p1 == p2); | |
502 | BOOST_TEST(N::base::instances == 1); | |
503 | BOOST_TEST(p4->use_count() == 2); | |
504 | ||
505 | p4 = p2.get(); | |
506 | p5 = p2.get(); | |
507 | ||
508 | BOOST_TEST(p4 == p2); | |
509 | BOOST_TEST(N::base::instances == 0); | |
510 | } | |
7c673cae FG |
511 | } |
512 | ||
513 | void test() | |
514 | { | |
515 | copy_assignment(); | |
516 | conversion_assignment(); | |
517 | pointer_assignment(); | |
518 | } | |
519 | ||
520 | } // namespace n_assignment | |
521 | ||
522 | namespace n_reset | |
523 | { | |
524 | ||
525 | void test() | |
526 | { | |
527 | BOOST_TEST( N::base::instances == 0 ); | |
528 | ||
529 | { | |
530 | boost::intrusive_ptr<X> px; | |
531 | BOOST_TEST( px.get() == 0 ); | |
532 | ||
533 | px.reset(); | |
534 | BOOST_TEST( px.get() == 0 ); | |
535 | ||
536 | X * p = new X; | |
537 | BOOST_TEST( p->use_count() == 0 ); | |
538 | BOOST_TEST( N::base::instances == 1 ); | |
539 | ||
540 | px.reset( p ); | |
541 | BOOST_TEST( px.get() == p ); | |
542 | BOOST_TEST( px->use_count() == 1 ); | |
543 | ||
544 | px.reset(); | |
545 | BOOST_TEST( px.get() == 0 ); | |
546 | } | |
547 | ||
548 | BOOST_TEST( N::base::instances == 0 ); | |
549 | ||
550 | { | |
551 | boost::intrusive_ptr<X> px( new X ); | |
552 | BOOST_TEST( N::base::instances == 1 ); | |
553 | ||
554 | px.reset( 0 ); | |
555 | BOOST_TEST( px.get() == 0 ); | |
556 | } | |
557 | ||
558 | BOOST_TEST( N::base::instances == 0 ); | |
559 | ||
560 | { | |
561 | boost::intrusive_ptr<X> px( new X ); | |
562 | BOOST_TEST( N::base::instances == 1 ); | |
563 | ||
564 | px.reset( 0, false ); | |
565 | BOOST_TEST( px.get() == 0 ); | |
566 | } | |
567 | ||
568 | BOOST_TEST( N::base::instances == 0 ); | |
569 | ||
570 | { | |
571 | boost::intrusive_ptr<X> px( new X ); | |
572 | BOOST_TEST( N::base::instances == 1 ); | |
573 | ||
574 | px.reset( 0, true ); | |
575 | BOOST_TEST( px.get() == 0 ); | |
576 | } | |
577 | ||
578 | BOOST_TEST( N::base::instances == 0 ); | |
579 | ||
580 | { | |
581 | X * p = new X; | |
582 | BOOST_TEST( p->use_count() == 0 ); | |
583 | ||
584 | BOOST_TEST( N::base::instances == 1 ); | |
585 | ||
586 | boost::intrusive_ptr<X> px; | |
587 | BOOST_TEST( px.get() == 0 ); | |
588 | ||
589 | px.reset( p, true ); | |
590 | BOOST_TEST( px.get() == p ); | |
591 | BOOST_TEST( px->use_count() == 1 ); | |
592 | } | |
593 | ||
594 | BOOST_TEST( N::base::instances == 0 ); | |
595 | ||
596 | { | |
597 | X * p = new X; | |
598 | BOOST_TEST( p->use_count() == 0 ); | |
599 | ||
600 | BOOST_TEST( N::base::instances == 1 ); | |
601 | ||
602 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
603 | using boost::intrusive_ptr_add_ref; | |
604 | #endif | |
605 | intrusive_ptr_add_ref( p ); | |
606 | BOOST_TEST( p->use_count() == 1 ); | |
607 | ||
608 | boost::intrusive_ptr<X> px; | |
609 | BOOST_TEST( px.get() == 0 ); | |
610 | ||
611 | px.reset( p, false ); | |
612 | BOOST_TEST( px.get() == p ); | |
613 | BOOST_TEST( px->use_count() == 1 ); | |
614 | } | |
615 | ||
616 | BOOST_TEST( N::base::instances == 0 ); | |
617 | ||
618 | { | |
619 | boost::intrusive_ptr<X> px( new X ); | |
620 | BOOST_TEST( px.get() != 0 ); | |
621 | BOOST_TEST( px->use_count() == 1 ); | |
622 | ||
623 | BOOST_TEST( N::base::instances == 1 ); | |
624 | ||
625 | X * p = new X; | |
626 | BOOST_TEST( p->use_count() == 0 ); | |
627 | ||
628 | BOOST_TEST( N::base::instances == 2 ); | |
629 | ||
630 | px.reset( p ); | |
631 | BOOST_TEST( px.get() == p ); | |
632 | BOOST_TEST( px->use_count() == 1 ); | |
633 | ||
634 | BOOST_TEST( N::base::instances == 1 ); | |
635 | } | |
636 | ||
637 | BOOST_TEST( N::base::instances == 0 ); | |
638 | ||
639 | { | |
640 | boost::intrusive_ptr<X> px( new X ); | |
641 | BOOST_TEST( px.get() != 0 ); | |
642 | BOOST_TEST( px->use_count() == 1 ); | |
643 | ||
644 | BOOST_TEST( N::base::instances == 1 ); | |
645 | ||
646 | X * p = new X; | |
647 | BOOST_TEST( p->use_count() == 0 ); | |
648 | ||
649 | BOOST_TEST( N::base::instances == 2 ); | |
650 | ||
651 | px.reset( p, true ); | |
652 | BOOST_TEST( px.get() == p ); | |
653 | BOOST_TEST( px->use_count() == 1 ); | |
654 | ||
655 | BOOST_TEST( N::base::instances == 1 ); | |
656 | } | |
657 | ||
658 | BOOST_TEST( N::base::instances == 0 ); | |
659 | ||
660 | { | |
661 | boost::intrusive_ptr<X> px( new X ); | |
662 | BOOST_TEST( px.get() != 0 ); | |
663 | BOOST_TEST( px->use_count() == 1 ); | |
664 | ||
665 | BOOST_TEST( N::base::instances == 1 ); | |
666 | ||
667 | X * p = new X; | |
668 | BOOST_TEST( p->use_count() == 0 ); | |
669 | ||
670 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
671 | using boost::intrusive_ptr_add_ref; | |
672 | #endif | |
673 | intrusive_ptr_add_ref( p ); | |
674 | BOOST_TEST( p->use_count() == 1 ); | |
675 | ||
676 | BOOST_TEST( N::base::instances == 2 ); | |
677 | ||
678 | px.reset( p, false ); | |
679 | BOOST_TEST( px.get() == p ); | |
680 | BOOST_TEST( px->use_count() == 1 ); | |
681 | ||
682 | BOOST_TEST( N::base::instances == 1 ); | |
683 | } | |
684 | ||
685 | BOOST_TEST( N::base::instances == 0 ); | |
686 | } | |
687 | ||
688 | } // namespace n_reset | |
689 | ||
690 | namespace n_access | |
691 | { | |
692 | ||
693 | void test() | |
694 | { | |
695 | { | |
696 | boost::intrusive_ptr<X> px; | |
697 | BOOST_TEST(px? false: true); | |
698 | BOOST_TEST(!px); | |
699 | ||
700 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
701 | using boost::get_pointer; | |
702 | #endif | |
703 | ||
704 | BOOST_TEST(get_pointer(px) == px.get()); | |
705 | } | |
706 | ||
707 | { | |
708 | boost::intrusive_ptr<X> px(0); | |
709 | BOOST_TEST(px? false: true); | |
710 | BOOST_TEST(!px); | |
711 | ||
712 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
713 | using boost::get_pointer; | |
714 | #endif | |
715 | ||
716 | BOOST_TEST(get_pointer(px) == px.get()); | |
717 | } | |
718 | ||
719 | { | |
720 | boost::intrusive_ptr<X> px(new X); | |
721 | BOOST_TEST(px? true: false); | |
722 | BOOST_TEST(!!px); | |
723 | BOOST_TEST(&*px == px.get()); | |
724 | BOOST_TEST(px.operator ->() == px.get()); | |
725 | ||
726 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
727 | using boost::get_pointer; | |
728 | #endif | |
729 | ||
730 | BOOST_TEST(get_pointer(px) == px.get()); | |
731 | } | |
732 | ||
733 | { | |
734 | boost::intrusive_ptr<X> px; | |
735 | X* detached = px.detach(); | |
736 | BOOST_TEST( px.get() == 0 ); | |
737 | BOOST_TEST( detached == 0 ); | |
738 | } | |
739 | ||
740 | { | |
741 | X * p = new X; | |
742 | BOOST_TEST( p->use_count() == 0 ); | |
743 | ||
744 | boost::intrusive_ptr<X> px( p ); | |
745 | BOOST_TEST( px.get() == p ); | |
746 | BOOST_TEST( px->use_count() == 1 ); | |
747 | ||
748 | X * detached = px.detach(); | |
749 | BOOST_TEST( px.get() == 0 ); | |
750 | ||
751 | BOOST_TEST( detached == p ); | |
752 | BOOST_TEST( detached->use_count() == 1 ); | |
753 | ||
754 | delete detached; | |
755 | } | |
756 | } | |
757 | ||
758 | } // namespace n_access | |
759 | ||
760 | namespace n_swap | |
761 | { | |
762 | ||
763 | void test() | |
764 | { | |
765 | { | |
766 | boost::intrusive_ptr<X> px; | |
767 | boost::intrusive_ptr<X> px2; | |
768 | ||
769 | px.swap(px2); | |
770 | ||
771 | BOOST_TEST(px.get() == 0); | |
772 | BOOST_TEST(px2.get() == 0); | |
773 | ||
774 | using std::swap; | |
775 | swap(px, px2); | |
776 | ||
777 | BOOST_TEST(px.get() == 0); | |
778 | BOOST_TEST(px2.get() == 0); | |
779 | } | |
780 | ||
781 | { | |
782 | X * p = new X; | |
783 | boost::intrusive_ptr<X> px; | |
784 | boost::intrusive_ptr<X> px2(p); | |
785 | boost::intrusive_ptr<X> px3(px2); | |
786 | ||
787 | px.swap(px2); | |
788 | ||
789 | BOOST_TEST(px.get() == p); | |
790 | BOOST_TEST(px->use_count() == 2); | |
791 | BOOST_TEST(px2.get() == 0); | |
792 | BOOST_TEST(px3.get() == p); | |
793 | BOOST_TEST(px3->use_count() == 2); | |
794 | ||
795 | using std::swap; | |
796 | swap(px, px2); | |
797 | ||
798 | BOOST_TEST(px.get() == 0); | |
799 | BOOST_TEST(px2.get() == p); | |
800 | BOOST_TEST(px2->use_count() == 2); | |
801 | BOOST_TEST(px3.get() == p); | |
802 | BOOST_TEST(px3->use_count() == 2); | |
803 | } | |
804 | ||
805 | { | |
806 | X * p1 = new X; | |
807 | X * p2 = new X; | |
808 | boost::intrusive_ptr<X> px(p1); | |
809 | boost::intrusive_ptr<X> px2(p2); | |
810 | boost::intrusive_ptr<X> px3(px2); | |
811 | ||
812 | px.swap(px2); | |
813 | ||
814 | BOOST_TEST(px.get() == p2); | |
815 | BOOST_TEST(px->use_count() == 2); | |
816 | BOOST_TEST(px2.get() == p1); | |
817 | BOOST_TEST(px2->use_count() == 1); | |
818 | BOOST_TEST(px3.get() == p2); | |
819 | BOOST_TEST(px3->use_count() == 2); | |
820 | ||
821 | using std::swap; | |
822 | swap(px, px2); | |
823 | ||
824 | BOOST_TEST(px.get() == p1); | |
825 | BOOST_TEST(px->use_count() == 1); | |
826 | BOOST_TEST(px2.get() == p2); | |
827 | BOOST_TEST(px2->use_count() == 2); | |
828 | BOOST_TEST(px3.get() == p2); | |
829 | BOOST_TEST(px3->use_count() == 2); | |
830 | } | |
831 | } | |
832 | ||
833 | } // namespace n_swap | |
834 | ||
835 | namespace n_comparison | |
836 | { | |
837 | ||
838 | template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q) | |
839 | { | |
840 | BOOST_TEST((p == q) == (p.get() == q.get())); | |
841 | BOOST_TEST((p != q) == (p.get() != q.get())); | |
842 | } | |
843 | ||
844 | template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q) | |
845 | { | |
846 | BOOST_TEST((p == q) == (p.get() == q.get())); | |
847 | BOOST_TEST((p.get() == q) == (p.get() == q.get())); | |
848 | BOOST_TEST((p == q.get()) == (p.get() == q.get())); | |
849 | BOOST_TEST((p != q) == (p.get() != q.get())); | |
850 | BOOST_TEST((p.get() != q) == (p.get() != q.get())); | |
851 | BOOST_TEST((p != q.get()) == (p.get() != q.get())); | |
852 | ||
853 | // 'less' moved here as a g++ 2.9x parse error workaround | |
854 | std::less<T*> less; | |
855 | BOOST_TEST((p < q) == less(p.get(), q.get())); | |
856 | } | |
857 | ||
858 | void test() | |
859 | { | |
860 | { | |
861 | boost::intrusive_ptr<X> px; | |
862 | test3(px, px); | |
863 | ||
864 | boost::intrusive_ptr<X> px2; | |
865 | test3(px, px2); | |
866 | ||
867 | boost::intrusive_ptr<X> px3(px); | |
868 | test3(px3, px3); | |
869 | test3(px, px3); | |
870 | } | |
871 | ||
872 | { | |
873 | boost::intrusive_ptr<X> px; | |
874 | ||
875 | boost::intrusive_ptr<X> px2(new X); | |
876 | test3(px, px2); | |
877 | test3(px2, px2); | |
878 | ||
879 | boost::intrusive_ptr<X> px3(new X); | |
880 | test3(px2, px3); | |
881 | ||
882 | boost::intrusive_ptr<X> px4(px2); | |
883 | test3(px2, px4); | |
884 | test3(px4, px4); | |
885 | } | |
886 | ||
887 | { | |
888 | boost::intrusive_ptr<X> px(new X); | |
889 | ||
890 | boost::intrusive_ptr<Y> py(new Y); | |
891 | test2(px, py); | |
892 | ||
893 | boost::intrusive_ptr<X> px2(py); | |
894 | test2(px2, py); | |
895 | test3(px, px2); | |
896 | test3(px2, px2); | |
897 | } | |
898 | } | |
899 | ||
900 | } // namespace n_comparison | |
901 | ||
902 | namespace n_static_cast | |
903 | { | |
904 | ||
905 | void test() | |
906 | { | |
92f5a8d4 TL |
907 | { |
908 | boost::intrusive_ptr<X> px(new Y); | |
909 | ||
910 | boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>(px); | |
911 | BOOST_TEST(px.get() == py.get()); | |
912 | BOOST_TEST(px->use_count() == 2); | |
913 | BOOST_TEST(py->use_count() == 2); | |
914 | ||
915 | boost::intrusive_ptr<X> px2(py); | |
916 | BOOST_TEST(px2.get() == px.get()); | |
917 | } | |
918 | ||
919 | BOOST_TEST( N::base::instances == 0 ); | |
920 | ||
921 | { | |
922 | boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( boost::intrusive_ptr<X>(new Y) ); | |
923 | BOOST_TEST(py.get() != 0); | |
924 | BOOST_TEST(py->use_count() == 1); | |
925 | } | |
926 | ||
927 | BOOST_TEST( N::base::instances == 0 ); | |
7c673cae FG |
928 | } |
929 | ||
930 | } // namespace n_static_cast | |
931 | ||
92f5a8d4 TL |
932 | namespace n_const_cast |
933 | { | |
934 | ||
935 | void test() | |
936 | { | |
937 | { | |
938 | boost::intrusive_ptr<X const> px; | |
939 | ||
940 | boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(px); | |
941 | BOOST_TEST(px2.get() == 0); | |
942 | } | |
943 | ||
944 | { | |
945 | boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>( boost::intrusive_ptr<X const>() ); | |
946 | BOOST_TEST(px2.get() == 0); | |
947 | } | |
948 | ||
949 | BOOST_TEST( N::base::instances == 0 ); | |
950 | ||
951 | { | |
952 | boost::intrusive_ptr<X const> px(new X); | |
953 | ||
954 | boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(px); | |
955 | BOOST_TEST(px2.get() == px.get()); | |
956 | BOOST_TEST(px2->use_count() == 2); | |
957 | BOOST_TEST(px->use_count() == 2); | |
958 | } | |
959 | ||
960 | BOOST_TEST( N::base::instances == 0 ); | |
961 | ||
962 | { | |
963 | boost::intrusive_ptr<X> px = boost::const_pointer_cast<X>( boost::intrusive_ptr<X const>(new X) ); | |
964 | BOOST_TEST(px.get() != 0); | |
965 | BOOST_TEST(px->use_count() == 1); | |
966 | } | |
967 | ||
968 | BOOST_TEST( N::base::instances == 0 ); | |
969 | } | |
970 | ||
971 | } // namespace n_const_cast | |
972 | ||
7c673cae FG |
973 | namespace n_dynamic_cast |
974 | { | |
975 | ||
976 | void test() | |
977 | { | |
92f5a8d4 TL |
978 | { |
979 | boost::intrusive_ptr<X> px; | |
980 | ||
981 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | |
982 | BOOST_TEST(py.get() == 0); | |
983 | } | |
984 | ||
985 | { | |
986 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>() ); | |
987 | BOOST_TEST(py.get() == 0); | |
988 | } | |
989 | ||
990 | { | |
991 | boost::intrusive_ptr<X> px(static_cast<X*>(0)); | |
992 | ||
993 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | |
994 | BOOST_TEST(py.get() == 0); | |
995 | } | |
996 | ||
997 | { | |
998 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(static_cast<X*>(0)) ); | |
999 | BOOST_TEST(py.get() == 0); | |
1000 | } | |
1001 | ||
1002 | { | |
1003 | boost::intrusive_ptr<X> px(new X); | |
1004 | ||
1005 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | |
1006 | BOOST_TEST(py.get() == 0); | |
1007 | } | |
1008 | ||
1009 | BOOST_TEST( N::base::instances == 0 ); | |
1010 | ||
1011 | { | |
1012 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(new X) ); | |
1013 | BOOST_TEST(py.get() == 0); | |
1014 | } | |
1015 | ||
1016 | BOOST_TEST( N::base::instances == 0 ); | |
1017 | ||
1018 | { | |
1019 | boost::intrusive_ptr<X> px(new Y); | |
1020 | ||
1021 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | |
1022 | BOOST_TEST(py.get() == px.get()); | |
1023 | BOOST_TEST(py->use_count() == 2); | |
1024 | BOOST_TEST(px->use_count() == 2); | |
1025 | } | |
1026 | ||
1027 | BOOST_TEST( N::base::instances == 0 ); | |
1028 | ||
1029 | { | |
1030 | boost::intrusive_ptr<X> px(new Y); | |
1031 | ||
1032 | boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(new Y) ); | |
1033 | BOOST_TEST(py.get() != 0); | |
1034 | BOOST_TEST(py->use_count() == 1); | |
1035 | } | |
1036 | ||
1037 | BOOST_TEST( N::base::instances == 0 ); | |
7c673cae FG |
1038 | } |
1039 | ||
1040 | } // namespace n_dynamic_cast | |
1041 | ||
1042 | namespace n_transitive | |
1043 | { | |
1044 | ||
1045 | struct X: public N::base | |
1046 | { | |
1047 | boost::intrusive_ptr<X> next; | |
1048 | }; | |
1049 | ||
1050 | void test() | |
1051 | { | |
1052 | boost::intrusive_ptr<X> p(new X); | |
1053 | p->next = boost::intrusive_ptr<X>(new X); | |
1054 | BOOST_TEST(!p->next->next); | |
1055 | p = p->next; | |
1056 | BOOST_TEST(!p->next); | |
1057 | } | |
1058 | ||
1059 | } // namespace n_transitive | |
1060 | ||
1061 | namespace n_report_1 | |
1062 | { | |
1063 | ||
1064 | class foo: public N::base | |
1065 | { | |
1066 | public: | |
1067 | ||
1068 | foo(): m_self(this) | |
1069 | { | |
1070 | } | |
1071 | ||
1072 | void suicide() | |
1073 | { | |
1074 | m_self = 0; | |
1075 | } | |
1076 | ||
1077 | private: | |
1078 | ||
1079 | boost::intrusive_ptr<foo> m_self; | |
1080 | }; | |
1081 | ||
1082 | void test() | |
1083 | { | |
1084 | foo * foo_ptr = new foo; | |
1085 | foo_ptr->suicide(); | |
1086 | } | |
1087 | ||
1088 | } // namespace n_report_1 | |
1089 | ||
1090 | int main() | |
1091 | { | |
1092 | n_element_type::test(); | |
1093 | n_constructors::test(); | |
1094 | n_destructor::test(); | |
1095 | n_assignment::test(); | |
1096 | n_reset::test(); | |
1097 | n_access::test(); | |
1098 | n_swap::test(); | |
1099 | n_comparison::test(); | |
1100 | n_static_cast::test(); | |
92f5a8d4 | 1101 | n_const_cast::test(); |
7c673cae FG |
1102 | n_dynamic_cast::test(); |
1103 | ||
1104 | n_transitive::test(); | |
1105 | n_report_1::test(); | |
1106 | ||
1107 | return boost::report_errors(); | |
1108 | } |