CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // ====================================================================== 00002 // 00003 // Test compilability and basic functionality of Utility/memory.h 00004 // 00005 // Author: W. E. Brown, 2010-03-19, adapted from the boost library's 00006 // shared_ptr and related functionality whose internal attributions bear 00007 // the following various notices: 00008 // 00009 // Copyright (c) 2002, 2003 Peter Dimov 00010 // Distributed under the Boost Software License, Version 1.0. 00011 // See http://www.boost.org/LICENSE_1_0.txt 00012 // 00013 // ====================================================================== 00014 00015 00016 #include "CLHEP/Utility/memory.h" 00017 00018 #include <cassert> 00019 #include <map> 00020 #include <vector> 00021 00022 00023 using namespace CLHEP; 00024 using CLHEP::shared_ptr; 00025 using CLHEP::weak_ptr; 00026 00027 00028 #if defined(_MSC_VER) && (_MSC_VER >= 1310) 00029 # pragma warning (disable : 4675) // suppress ADL warning 00030 #endif 00031 00032 00033 namespace n_element_type 00034 { 00035 00036 void 00037 f(int &) 00038 { } 00039 00040 void 00041 test() 00042 { 00043 typedef shared_ptr<int>::element_type T; 00044 T t; 00045 f(t); 00046 } 00047 00048 } // namespace n_element_type 00049 00050 namespace n_constructors 00051 { 00052 00053 class incomplete; 00054 00055 void 00056 default_constructor() 00057 { 00058 { 00059 shared_ptr<int> pi; 00060 assert(pi? false: true); 00061 assert(!pi); 00062 assert(pi.get() == 0); 00063 assert(pi.use_count() == 0); 00064 } 00065 00066 { 00067 shared_ptr<void> pv; 00068 assert(pv? false: true); 00069 assert(!pv); 00070 assert(pv.get() == 0); 00071 assert(pv.use_count() == 0); 00072 } 00073 00074 { 00075 shared_ptr<incomplete> px; 00076 assert(px? false: true); 00077 assert(!px); 00078 assert(px.get() == 0); 00079 assert(px.use_count() == 0); 00080 } 00081 } 00082 00083 struct A 00084 { 00085 int dummy; 00086 }; 00087 00088 struct X 00089 { 00090 static long instances; 00091 00092 X() 00093 { 00094 ++instances; 00095 } 00096 00097 ~X() 00098 { 00099 --instances; 00100 } 00101 00102 private: 00103 X(X const &); 00104 X & operator= (X const &); 00105 }; 00106 00107 long X::instances = 0; 00108 00109 // virtual inheritance stresses the implementation 00110 00111 struct Y 00112 : public A 00113 , public virtual X 00114 { 00115 static long instances; 00116 00117 Y() 00118 { 00119 ++instances; 00120 } 00121 00122 ~Y() 00123 { 00124 --instances; 00125 } 00126 00127 private: 00128 Y(Y const &); 00129 Y & operator= (Y const &); 00130 }; 00131 00132 long Y::instances = 0; 00133 00134 template< class T > 00135 void 00136 pc0_test(T * p) 00137 { 00138 assert(p == 0); 00139 shared_ptr<T> pt(p); 00140 assert(pt? false: true); 00141 assert(!pt); 00142 assert(pt.get() == 0); 00143 assert(pt.use_count() == 1); 00144 assert(pt.unique()); 00145 } 00146 00147 void 00148 pointer_constructor() 00149 { 00150 pc0_test(static_cast<int*>(0)); 00151 00152 pc0_test(static_cast<int const*>(0)); 00153 pc0_test(static_cast<int volatile*>(0)); 00154 pc0_test(static_cast<int const volatile*>(0)); 00155 00156 { 00157 shared_ptr<int const> pi(static_cast<int*>(0)); 00158 assert(pi? false: true); 00159 assert(!pi); 00160 assert(pi.get() == 0); 00161 assert(pi.use_count() == 1); 00162 assert(pi.unique()); 00163 } 00164 00165 { 00166 shared_ptr<int volatile> pi(static_cast<int*>(0)); 00167 assert(pi? false: true); 00168 assert(!pi); 00169 assert(pi.get() == 0); 00170 assert(pi.use_count() == 1); 00171 assert(pi.unique()); 00172 } 00173 00174 { 00175 shared_ptr<void> pv(static_cast<int*>(0)); 00176 assert(pv? false: true); 00177 assert(!pv); 00178 assert(pv.get() == 0); 00179 assert(pv.use_count() == 1); 00180 assert(pv.unique()); 00181 } 00182 00183 { 00184 shared_ptr<void const> pv(static_cast<int*>(0)); 00185 assert(pv? false: true); 00186 assert(!pv); 00187 assert(pv.get() == 0); 00188 assert(pv.use_count() == 1); 00189 assert(pv.unique()); 00190 } 00191 00192 pc0_test(static_cast<X*>(0)); 00193 pc0_test(static_cast<X const*>(0)); 00194 pc0_test(static_cast<X volatile*>(0)); 00195 pc0_test(static_cast<X const volatile*>(0)); 00196 00197 { 00198 shared_ptr<X const> px(static_cast<X*>(0)); 00199 assert(px? false: true); 00200 assert(!px); 00201 assert(px.get() == 0); 00202 assert(px.use_count() == 1); 00203 assert(px.unique()); 00204 } 00205 00206 { 00207 shared_ptr<X> px(static_cast<Y*>(0)); 00208 assert(px? false: true); 00209 assert(!px); 00210 assert(px.get() == 0); 00211 assert(px.use_count() == 1); 00212 assert(px.unique()); 00213 } 00214 00215 { 00216 shared_ptr<X const> px(static_cast<Y*>(0)); 00217 assert(px? false: true); 00218 assert(!px); 00219 assert(px.get() == 0); 00220 assert(px.use_count() == 1); 00221 assert(px.unique()); 00222 } 00223 00224 { 00225 shared_ptr<void> pv(static_cast<X*>(0)); 00226 assert(pv? false: true); 00227 assert(!pv); 00228 assert(pv.get() == 0); 00229 assert(pv.use_count() == 1); 00230 assert(pv.unique()); 00231 } 00232 00233 { 00234 shared_ptr<void const> pv(static_cast<X*>(0)); 00235 assert(pv? false: true); 00236 assert(!pv); 00237 assert(pv.get() == 0); 00238 assert(pv.use_count() == 1); 00239 assert(pv.unique()); 00240 } 00241 00242 { 00243 int * p = new int(7); 00244 shared_ptr<int> pi(p); 00245 assert(pi? true: false); 00246 assert(!!pi); 00247 assert(pi.get() == p); 00248 assert(pi.use_count() == 1); 00249 assert(pi.unique()); 00250 assert(*pi == 7); 00251 } 00252 00253 { 00254 int * p = new int(7); 00255 shared_ptr<int const> pi(p); 00256 assert(pi? true: false); 00257 assert(!!pi); 00258 assert(pi.get() == p); 00259 assert(pi.use_count() == 1); 00260 assert(pi.unique()); 00261 assert(*pi == 7); 00262 } 00263 00264 { 00265 int * p = new int(7); 00266 shared_ptr<void> pv(p); 00267 assert(pv? true: false); 00268 assert(!!pv); 00269 assert(pv.get() == p); 00270 assert(pv.use_count() == 1); 00271 assert(pv.unique()); 00272 } 00273 00274 { 00275 int * p = new int(7); 00276 shared_ptr<void const> pv(p); 00277 assert(pv? true: false); 00278 assert(!!pv); 00279 assert(pv.get() == p); 00280 assert(pv.use_count() == 1); 00281 assert(pv.unique()); 00282 } 00283 00284 assert(X::instances == 0); 00285 00286 { 00287 X * p = new X; 00288 shared_ptr<X> px(p); 00289 assert(px? true: false); 00290 assert(!!px); 00291 assert(px.get() == p); 00292 assert(px.use_count() == 1); 00293 assert(px.unique()); 00294 assert(X::instances == 1); 00295 } 00296 00297 assert(X::instances == 0); 00298 00299 { 00300 X * p = new X; 00301 shared_ptr<X const> px(p); 00302 assert(px? true: false); 00303 assert(!!px); 00304 assert(px.get() == p); 00305 assert(px.use_count() == 1); 00306 assert(px.unique()); 00307 assert(X::instances == 1); 00308 } 00309 00310 assert(X::instances == 0); 00311 00312 { 00313 X * p = new X; 00314 shared_ptr<void> pv(p); 00315 assert(pv? true: false); 00316 assert(!!pv); 00317 assert(pv.get() == p); 00318 assert(pv.use_count() == 1); 00319 assert(pv.unique()); 00320 assert(X::instances == 1); 00321 } 00322 00323 assert(X::instances == 0); 00324 00325 { 00326 X * p = new X; 00327 shared_ptr<void const> pv(p); 00328 assert(pv? true: false); 00329 assert(!!pv); 00330 assert(pv.get() == p); 00331 assert(pv.use_count() == 1); 00332 assert(pv.unique()); 00333 assert(X::instances == 1); 00334 } 00335 00336 assert(X::instances == 0); 00337 assert(Y::instances == 0); 00338 00339 { 00340 Y * p = new Y; 00341 shared_ptr<X> px(p); 00342 assert(px? true: false); 00343 assert(!!px); 00344 assert(px.get() == p); 00345 assert(px.use_count() == 1); 00346 assert(px.unique()); 00347 assert(X::instances == 1); 00348 assert(Y::instances == 1); 00349 } 00350 00351 assert(X::instances == 0); 00352 assert(Y::instances == 0); 00353 00354 { 00355 Y * p = new Y; 00356 shared_ptr<X const> px(p); 00357 assert(px? true: false); 00358 assert(!!px); 00359 assert(px.get() == p); 00360 assert(px.use_count() == 1); 00361 assert(px.unique()); 00362 assert(X::instances == 1); 00363 assert(Y::instances == 1); 00364 } 00365 00366 assert(X::instances == 0); 00367 assert(Y::instances == 0); 00368 } 00369 00370 int m = 0; 00371 00372 void 00373 deleter(int * p) 00374 { 00375 assert(p == 0); 00376 } 00377 00378 void 00379 deleter2(int * p) 00380 { 00381 assert(p == &m); 00382 ++*p; 00383 } 00384 00385 struct deleter3 00386 { 00387 void operator()(incomplete * p) 00388 { 00389 assert(p == 0); 00390 } 00391 }; 00392 00393 incomplete * p0 = 0; 00394 00395 void 00396 deleter_constructor() 00397 { 00398 { 00399 shared_ptr<int> pi(static_cast<int*>(0), deleter); 00400 assert(pi? false: true); 00401 assert(!pi); 00402 assert(pi.get() == 0); 00403 assert(pi.use_count() == 1); 00404 assert(pi.unique()); 00405 } 00406 00407 { 00408 shared_ptr<void> pv(static_cast<int*>(0), &deleter); 00409 assert(pv? false: true); 00410 assert(!pv); 00411 assert(pv.get() == 0); 00412 assert(pv.use_count() == 1); 00413 assert(pv.unique()); 00414 } 00415 00416 { 00417 shared_ptr<void const> pv(static_cast<int*>(0), deleter); 00418 assert(pv? false: true); 00419 assert(!pv); 00420 assert(pv.get() == 0); 00421 assert(pv.use_count() == 1); 00422 assert(pv.unique()); 00423 } 00424 00425 { 00426 shared_ptr<incomplete> px(p0, deleter3()); 00427 assert(px? false: true); 00428 assert(!px); 00429 assert(px.get() == 0); 00430 assert(px.use_count() == 1); 00431 assert(px.unique()); 00432 } 00433 00434 { 00435 shared_ptr<void> pv(p0, deleter3()); 00436 assert(pv? false: true); 00437 assert(!pv); 00438 assert(pv.get() == 0); 00439 assert(pv.use_count() == 1); 00440 assert(pv.unique()); 00441 } 00442 00443 { 00444 shared_ptr<void const> pv(p0, deleter3()); 00445 assert(pv? false: true); 00446 assert(!pv); 00447 assert(pv.get() == 0); 00448 assert(pv.use_count() == 1); 00449 assert(pv.unique()); 00450 } 00451 00452 assert(m == 0); 00453 00454 { 00455 shared_ptr<int> pi(&m, deleter2); 00456 assert(pi? true: false); 00457 assert(!!pi); 00458 assert(pi.get() == &m); 00459 assert(pi.use_count() == 1); 00460 assert(pi.unique()); 00461 } 00462 00463 assert(m == 1); 00464 00465 { 00466 shared_ptr<int const> pi(&m, &deleter2); 00467 assert(pi? true: false); 00468 assert(!!pi); 00469 assert(pi.get() == &m); 00470 assert(pi.use_count() == 1); 00471 assert(pi.unique()); 00472 } 00473 00474 assert(m == 2); 00475 00476 { 00477 shared_ptr<void> pv(&m, deleter2); 00478 assert(pv? true: false); 00479 assert(!!pv); 00480 assert(pv.get() == &m); 00481 assert(pv.use_count() == 1); 00482 assert(pv.unique()); 00483 } 00484 00485 assert(m == 3); 00486 00487 { 00488 shared_ptr<void const> pv(&m, &deleter2); 00489 assert(pv? true: false); 00490 assert(!!pv); 00491 assert(pv.get() == &m); 00492 assert(pv.use_count() == 1); 00493 assert(pv.unique()); 00494 } 00495 00496 assert(m == 4); 00497 } 00498 00499 void 00500 copy_constructor() 00501 { 00502 { 00503 shared_ptr<int> pi; 00504 00505 shared_ptr<int> pi2(pi); 00506 assert(pi2 == pi); 00507 assert(pi2? false: true); 00508 assert(!pi2); 00509 assert(pi2.get() == 0); 00510 assert(pi2.use_count() == pi.use_count()); 00511 00512 shared_ptr<void> pi3(pi); 00513 assert(pi3 == pi); 00514 assert(pi3? false: true); 00515 assert(!pi3); 00516 assert(pi3.get() == 0); 00517 assert(pi3.use_count() == pi.use_count()); 00518 00519 shared_ptr<void> pi4(pi3); 00520 assert(pi4 == pi3); 00521 assert(pi4? false: true); 00522 assert(!pi4); 00523 assert(pi4.get() == 0); 00524 assert(pi4.use_count() == pi3.use_count()); 00525 } 00526 00527 { 00528 shared_ptr<void> pv; 00529 00530 shared_ptr<void> pv2(pv); 00531 assert(pv2 == pv); 00532 assert(pv2? false: true); 00533 assert(!pv2); 00534 assert(pv2.get() == 0); 00535 assert(pv2.use_count() == pv.use_count()); 00536 } 00537 00538 { 00539 shared_ptr<incomplete> px; 00540 00541 shared_ptr<incomplete> px2(px); 00542 assert(px2 == px); 00543 assert(px2? false: true); 00544 assert(!px2); 00545 assert(px2.get() == 0); 00546 assert(px2.use_count() == px.use_count()); 00547 00548 shared_ptr<void> px3(px); 00549 assert(px3 == px); 00550 assert(px3? false: true); 00551 assert(!px3); 00552 assert(px3.get() == 0); 00553 assert(px3.use_count() == px.use_count()); 00554 } 00555 00556 { 00557 shared_ptr<int> pi(static_cast<int*>(0)); 00558 00559 shared_ptr<int> pi2(pi); 00560 assert(pi2 == pi); 00561 assert(pi2? false: true); 00562 assert(!pi2); 00563 assert(pi2.get() == 0); 00564 assert(pi2.use_count() == 2); 00565 assert(!pi2.unique()); 00566 assert(pi2.use_count() == pi.use_count()); 00567 assert(!(pi < pi2 || pi2 < pi)); // shared ownership test 00568 00569 shared_ptr<void> pi3(pi); 00570 assert(pi3 == pi); 00571 assert(pi3? false: true); 00572 assert(!pi3); 00573 assert(pi3.get() == 0); 00574 assert(pi3.use_count() == 3); 00575 assert(!pi3.unique()); 00576 assert(pi3.use_count() == pi.use_count()); 00577 assert(!(pi < pi3 || pi3 < pi)); // shared ownership test 00578 00579 shared_ptr<void> pi4(pi2); 00580 assert(pi4 == pi2); 00581 assert(pi4? false: true); 00582 assert(!pi4); 00583 assert(pi4.get() == 0); 00584 assert(pi4.use_count() == 4); 00585 assert(!pi4.unique()); 00586 assert(pi4.use_count() == pi2.use_count()); 00587 assert(!(pi2 < pi4 || pi4 < pi2)); // shared ownership test 00588 00589 assert(pi3.use_count() == pi4.use_count()); 00590 assert(!(pi3 < pi4 || pi4 < pi3)); // shared ownership test 00591 } 00592 00593 { 00594 shared_ptr<X> px(static_cast<X*>(0)); 00595 00596 shared_ptr<X> px2(px); 00597 assert(px2 == px); 00598 assert(px2? false: true); 00599 assert(!px2); 00600 assert(px2.get() == 0); 00601 assert(px2.use_count() == 2); 00602 assert(!px2.unique()); 00603 assert(px2.use_count() == px.use_count()); 00604 assert(!(px < px2 || px2 < px)); // shared ownership test 00605 00606 shared_ptr<void> px3(px); 00607 assert(px3 == px); 00608 assert(px3? false: true); 00609 assert(!px3); 00610 assert(px3.get() == 0); 00611 assert(px3.use_count() == 3); 00612 assert(!px3.unique()); 00613 assert(px3.use_count() == px.use_count()); 00614 assert(!(px < px3 || px3 < px)); // shared ownership test 00615 00616 shared_ptr<void> px4(px2); 00617 assert(px4 == px2); 00618 assert(px4? false: true); 00619 assert(!px4); 00620 assert(px4.get() == 0); 00621 assert(px4.use_count() == 4); 00622 assert(!px4.unique()); 00623 assert(px4.use_count() == px2.use_count()); 00624 assert(!(px2 < px4 || px4 < px2)); // shared ownership test 00625 00626 assert(px3.use_count() == px4.use_count()); 00627 assert(!(px3 < px4 || px4 < px3)); // shared ownership test 00628 } 00629 00630 { 00631 int * p = new int(7); 00632 shared_ptr<int> pi(p); 00633 00634 shared_ptr<int> pi2(pi); 00635 assert(pi2 == pi); 00636 assert(pi2? true: false); 00637 assert(!!pi2); 00638 assert(pi2.get() == p); 00639 assert(pi2.use_count() == 2); 00640 assert(!pi2.unique()); 00641 assert(*pi2 == 7); 00642 assert(pi2.use_count() == pi.use_count()); 00643 assert(!(pi < pi2 || pi2 < pi)); // shared ownership test 00644 } 00645 00646 { 00647 int * p = new int(7); 00648 shared_ptr<void> pv(p); 00649 assert(pv.get() == p); 00650 00651 shared_ptr<void> pv2(pv); 00652 assert(pv2 == pv); 00653 assert(pv2? true: false); 00654 assert(!!pv2); 00655 assert(pv2.get() == p); 00656 assert(pv2.use_count() == 2); 00657 assert(!pv2.unique()); 00658 assert(pv2.use_count() == pv.use_count()); 00659 assert(!(pv < pv2 || pv2 < pv)); // shared ownership test 00660 } 00661 00662 assert(X::instances == 0); 00663 00664 { 00665 X * p = new X; 00666 shared_ptr<X> px(p); 00667 assert(px.get() == p); 00668 00669 shared_ptr<X> px2(px); 00670 assert(px2 == px); 00671 assert(px2? true: false); 00672 assert(!!px2); 00673 assert(px2.get() == p); 00674 assert(px2.use_count() == 2); 00675 assert(!px2.unique()); 00676 00677 assert(X::instances == 1); 00678 00679 assert(px2.use_count() == px.use_count()); 00680 assert(!(px < px2 || px2 < px)); // shared ownership test 00681 00682 shared_ptr<void> px3(px); 00683 assert(px3 == px); 00684 assert(px3? true: false); 00685 assert(!!px3); 00686 assert(px3.get() == p); 00687 assert(px3.use_count() == 3); 00688 assert(!px3.unique()); 00689 assert(px3.use_count() == px.use_count()); 00690 assert(!(px < px3 || px3 < px)); // shared ownership test 00691 00692 shared_ptr<void> px4(px2); 00693 assert(px4 == px2); 00694 assert(px4? true: false); 00695 assert(!!px4); 00696 assert(px4.get() == p); 00697 assert(px4.use_count() == 4); 00698 assert(!px4.unique()); 00699 assert(px4.use_count() == px2.use_count()); 00700 assert(!(px2 < px4 || px4 < px2)); // shared ownership test 00701 00702 assert(px3.use_count() == px4.use_count()); 00703 assert(!(px3 < px4 || px4 < px3)); // shared ownership test 00704 } 00705 00706 assert(X::instances == 0); 00707 assert(Y::instances == 0); 00708 00709 { 00710 Y * p = new Y; 00711 shared_ptr<Y> py(p); 00712 assert(py.get() == p); 00713 00714 shared_ptr<X> px(py); 00715 assert(px == py); 00716 assert(px? true: false); 00717 assert(!!px); 00718 assert(px.get() == p); 00719 assert(px.use_count() == 2); 00720 assert(!px.unique()); 00721 assert(px.use_count() == py.use_count()); 00722 assert(!(px < py || py < px)); // shared ownership test 00723 00724 assert(X::instances == 1); 00725 assert(Y::instances == 1); 00726 00727 shared_ptr<void const> pv(px); 00728 assert(pv == px); 00729 assert(pv? true: false); 00730 assert(!!pv); 00731 assert(pv.get() == px.get()); 00732 assert(pv.use_count() == 3); 00733 assert(!pv.unique()); 00734 assert(pv.use_count() == px.use_count()); 00735 assert(!(px < pv || pv < px)); // shared ownership test 00736 00737 shared_ptr<void const> pv2(py); 00738 assert(pv2 == py); 00739 assert(pv2? true: false); 00740 assert(!!pv2); 00741 assert(pv2.get() == py.get()); 00742 assert(pv2.use_count() == 4); 00743 assert(!pv2.unique()); 00744 assert(pv2.use_count() == py.use_count()); 00745 assert(!(py < pv2 || pv2 < py)); // shared ownership test 00746 00747 assert(pv.use_count() == pv2.use_count()); 00748 assert(!(pv < pv2 || pv2 < pv)); // shared ownership test 00749 } 00750 00751 assert(X::instances == 0); 00752 assert(Y::instances == 0); 00753 } 00754 00755 void 00756 weak_ptr_constructor() 00757 { 00758 { 00759 weak_ptr<Y> wp; 00760 assert(wp.use_count() == 0); 00761 00762 try 00763 { 00764 shared_ptr<Y> p2(wp); 00765 throw "shared_ptr<Y> p2(wp) failed to throw"; 00766 } 00767 catch(bad_weak_ptr) 00768 { 00769 } 00770 00771 try 00772 { 00773 shared_ptr<X> p3(wp); 00774 throw "shared_ptr<X> p3(wp) failed to throw"; 00775 } 00776 catch(bad_weak_ptr) 00777 { 00778 } 00779 } 00780 00781 { 00782 shared_ptr<Y> p; 00783 weak_ptr<Y> wp(p); 00784 00785 if(wp.use_count() != 0) // 0 allowed but not required 00786 { 00787 shared_ptr<Y> p2(wp); 00788 assert(p2.use_count() == wp.use_count()); 00789 assert(p2.get() == 0); 00790 00791 shared_ptr<X> p3(wp); 00792 assert(p3.use_count() == wp.use_count()); 00793 assert(p3.get() == 0); 00794 } 00795 } 00796 00797 { 00798 shared_ptr<Y> p(new Y); 00799 weak_ptr<Y> wp(p); 00800 00801 { 00802 shared_ptr<Y> p2(wp); 00803 assert(p2? true: false); 00804 assert(!!p2); 00805 assert(p2.get() == p.get()); 00806 assert(p2.use_count() == 2); 00807 assert(!p2.unique()); 00808 assert(p2.use_count() == wp.use_count()); 00809 00810 assert(p.use_count() == p2.use_count()); 00811 assert(!(p < p2 || p2 < p)); // shared ownership test 00812 00813 shared_ptr<X> p3(wp); 00814 assert(p3? true: false); 00815 assert(!!p3); 00816 assert(p3.get() == p.get()); 00817 assert(p3.use_count() == 3); 00818 assert(!p3.unique()); 00819 assert(p3.use_count() == wp.use_count()); 00820 00821 assert(p.use_count() == p3.use_count()); 00822 } 00823 00824 p.reset(); 00825 assert(wp.use_count() == 0); 00826 00827 try 00828 { 00829 shared_ptr<Y> p2(wp); 00830 throw "shared_ptr<Y> p2(wp) failed to throw"; 00831 } 00832 catch(bad_weak_ptr) 00833 { 00834 } 00835 00836 try 00837 { 00838 shared_ptr<X> p3(wp); 00839 throw "shared_ptr<X> p3(wp) failed to throw"; 00840 } 00841 catch(bad_weak_ptr) 00842 { 00843 } 00844 } 00845 } 00846 00847 void 00848 auto_ptr_constructor() 00849 { 00850 { 00851 std::auto_ptr<int> p; 00852 shared_ptr<int> pi(p); 00853 assert(pi? false: true); 00854 assert(!pi); 00855 assert(pi.get() == 0); 00856 assert(pi.use_count() == 1); 00857 assert(pi.unique()); 00858 assert(p.get() == 0); 00859 } 00860 00861 { 00862 std::auto_ptr<int> p; 00863 shared_ptr<int const> pi(p); 00864 assert(pi? false: true); 00865 assert(!pi); 00866 assert(pi.get() == 0); 00867 assert(pi.use_count() == 1); 00868 assert(pi.unique()); 00869 assert(p.get() == 0); 00870 } 00871 00872 { 00873 std::auto_ptr<int> p; 00874 shared_ptr<void> pv(p); 00875 assert(pv? false: true); 00876 assert(!pv); 00877 assert(pv.get() == 0); 00878 assert(pv.use_count() == 1); 00879 assert(pv.unique()); 00880 assert(p.get() == 0); 00881 } 00882 00883 { 00884 std::auto_ptr<int> p; 00885 shared_ptr<void const> pv(p); 00886 assert(pv? false: true); 00887 assert(!pv); 00888 assert(pv.get() == 0); 00889 assert(pv.use_count() == 1); 00890 assert(pv.unique()); 00891 assert(p.get() == 0); 00892 } 00893 00894 { 00895 std::auto_ptr<X> p; 00896 shared_ptr<X> px(p); 00897 assert(px? false: true); 00898 assert(!px); 00899 assert(px.get() == 0); 00900 assert(px.use_count() == 1); 00901 assert(px.unique()); 00902 assert(p.get() == 0); 00903 } 00904 00905 { 00906 std::auto_ptr<X> p; 00907 shared_ptr<X const> px(p); 00908 assert(px? false: true); 00909 assert(!px); 00910 assert(px.get() == 0); 00911 assert(px.use_count() == 1); 00912 assert(px.unique()); 00913 assert(p.get() == 0); 00914 } 00915 00916 { 00917 std::auto_ptr<Y> p; 00918 shared_ptr<X> px(p); 00919 assert(px? false: true); 00920 assert(!px); 00921 assert(px.get() == 0); 00922 assert(px.use_count() == 1); 00923 assert(px.unique()); 00924 assert(p.get() == 0); 00925 } 00926 00927 { 00928 std::auto_ptr<Y> p; 00929 shared_ptr<X const> px(p); 00930 assert(px? false: true); 00931 assert(!px); 00932 assert(px.get() == 0); 00933 assert(px.use_count() == 1); 00934 assert(px.unique()); 00935 assert(p.get() == 0); 00936 } 00937 00938 { 00939 std::auto_ptr<Y> p; 00940 shared_ptr<void> pv(p); 00941 assert(pv? false: true); 00942 assert(!pv); 00943 assert(pv.get() == 0); 00944 assert(pv.use_count() == 1); 00945 assert(pv.unique()); 00946 assert(p.get() == 0); 00947 } 00948 00949 { 00950 std::auto_ptr<Y> p; 00951 shared_ptr<void const> pv(p); 00952 assert(pv? false: true); 00953 assert(!pv); 00954 assert(pv.get() == 0); 00955 assert(pv.use_count() == 1); 00956 assert(pv.unique()); 00957 assert(p.get() == 0); 00958 } 00959 00960 { 00961 std::auto_ptr<int> p(new int(7)); 00962 int * q = p.get(); 00963 shared_ptr<int> pi(p); 00964 assert(pi? true: false); 00965 assert(!!pi); 00966 assert(pi.get() == q); 00967 assert(pi.use_count() == 1); 00968 assert(pi.unique()); 00969 assert(*pi == 7); 00970 00971 assert(p.get() == 0); 00972 } 00973 00974 { 00975 std::auto_ptr<int> p(new int(7)); 00976 int * q = p.get(); 00977 shared_ptr<int const> pi(p); 00978 assert(pi? true: false); 00979 assert(!!pi); 00980 assert(pi.get() == q); 00981 assert(pi.use_count() == 1); 00982 assert(pi.unique()); 00983 assert(*pi == 7); 00984 00985 assert(p.get() == 0); 00986 } 00987 00988 { 00989 std::auto_ptr<int> p(new int(7)); 00990 int * q = p.get(); 00991 shared_ptr<void> pv(p); 00992 assert(pv? true: false); 00993 assert(!!pv); 00994 assert(pv.get() == q); 00995 assert(pv.use_count() == 1); 00996 assert(pv.unique()); 00997 00998 assert(p.get() == 0); 00999 } 01000 01001 { 01002 std::auto_ptr<int> p(new int(7)); 01003 int * q = p.get(); 01004 shared_ptr<void const> pv(p); 01005 assert(pv? true: false); 01006 assert(!!pv); 01007 assert(pv.get() == q); 01008 assert(pv.use_count() == 1); 01009 assert(pv.unique()); 01010 01011 assert(p.get() == 0); 01012 } 01013 01014 assert(X::instances == 0); 01015 01016 { 01017 std::auto_ptr<X> p(new X); 01018 X * q = p.get(); 01019 shared_ptr<X> px(p); 01020 assert(px? true: false); 01021 assert(!!px); 01022 assert(px.get() == q); 01023 assert(px.use_count() == 1); 01024 assert(px.unique()); 01025 assert(X::instances == 1); 01026 01027 assert(p.get() == 0); 01028 } 01029 01030 assert(X::instances == 0); 01031 01032 { 01033 std::auto_ptr<X> p(new X); 01034 X * q = p.get(); 01035 shared_ptr<X const> px(p); 01036 assert(px? true: false); 01037 assert(!!px); 01038 assert(px.get() == q); 01039 assert(px.use_count() == 1); 01040 assert(px.unique()); 01041 assert(X::instances == 1); 01042 01043 assert(p.get() == 0); 01044 } 01045 01046 assert(X::instances == 0); 01047 01048 { 01049 std::auto_ptr<X> p(new X); 01050 X * q = p.get(); 01051 shared_ptr<void> pv(p); 01052 assert(pv? true: false); 01053 assert(!!pv); 01054 assert(pv.get() == q); 01055 assert(pv.use_count() == 1); 01056 assert(pv.unique()); 01057 assert(X::instances == 1); 01058 01059 assert(p.get() == 0); 01060 } 01061 01062 assert(X::instances == 0); 01063 01064 { 01065 std::auto_ptr<X> p(new X); 01066 X * q = p.get(); 01067 shared_ptr<void const> pv(p); 01068 assert(pv? true: false); 01069 assert(!!pv); 01070 assert(pv.get() == q); 01071 assert(pv.use_count() == 1); 01072 assert(pv.unique()); 01073 assert(X::instances == 1); 01074 01075 assert(p.get() == 0); 01076 } 01077 01078 assert(X::instances == 0); 01079 assert(Y::instances == 0); 01080 01081 { 01082 std::auto_ptr<Y> p(new Y); 01083 Y * q = p.get(); 01084 shared_ptr<X> px(p); 01085 assert(px? true: false); 01086 assert(!!px); 01087 assert(px.get() == q); 01088 assert(px.use_count() == 1); 01089 assert(px.unique()); 01090 assert(X::instances == 1); 01091 assert(Y::instances == 1); 01092 01093 assert(p.get() == 0); 01094 } 01095 01096 assert(X::instances == 0); 01097 assert(Y::instances == 0); 01098 01099 { 01100 std::auto_ptr<Y> p(new Y); 01101 Y * q = p.get(); 01102 shared_ptr<X const> px(p); 01103 assert(px? true: false); 01104 assert(!!px); 01105 assert(px.get() == q); 01106 assert(px.use_count() == 1); 01107 assert(px.unique()); 01108 assert(X::instances == 1); 01109 assert(Y::instances == 1); 01110 01111 assert(p.get() == 0); 01112 } 01113 01114 assert(X::instances == 0); 01115 assert(Y::instances == 0); 01116 } 01117 01118 void 01119 test() 01120 { 01121 default_constructor(); 01122 pointer_constructor(); 01123 deleter_constructor(); 01124 copy_constructor(); 01125 weak_ptr_constructor(); 01126 auto_ptr_constructor(); 01127 } 01128 01129 } // namespace n_constructors 01130 01131 namespace n_assignment 01132 { 01133 01134 class incomplete; 01135 01136 struct A 01137 { 01138 int dummy; 01139 }; 01140 01141 struct X 01142 { 01143 static long instances; 01144 01145 X() 01146 { 01147 ++instances; 01148 } 01149 01150 ~X() 01151 { 01152 --instances; 01153 } 01154 01155 private: 01156 X(X const &); 01157 X & operator= (X const &); 01158 }; 01159 01160 long X::instances = 0; 01161 01162 struct Y 01163 : public A 01164 , public virtual X 01165 { 01166 static long instances; 01167 01168 Y() 01169 { 01170 ++instances; 01171 } 01172 01173 ~Y() 01174 { 01175 --instances; 01176 } 01177 01178 private: 01179 Y(Y const &); 01180 Y & operator= (Y const &); 01181 }; 01182 01183 long Y::instances = 0; 01184 01185 void 01186 copy_assignment() 01187 { 01188 { 01189 shared_ptr<incomplete> p1; 01190 01191 p1 = p1; 01192 01193 assert(p1 == p1); 01194 assert(p1? false: true); 01195 assert(!p1); 01196 assert(p1.get() == 0); 01197 01198 shared_ptr<incomplete> p2; 01199 01200 p1 = p2; 01201 01202 assert(p1 == p2); 01203 assert(p1? false: true); 01204 assert(!p1); 01205 assert(p1.get() == 0); 01206 01207 shared_ptr<incomplete> p3(p1); 01208 01209 p1 = p3; 01210 01211 assert(p1 == p3); 01212 assert(p1? false: true); 01213 assert(!p1); 01214 assert(p1.get() == 0); 01215 } 01216 01217 { 01218 shared_ptr<void> p1; 01219 01220 p1 = p1; 01221 01222 assert(p1 == p1); 01223 assert(p1? false: true); 01224 assert(!p1); 01225 assert(p1.get() == 0); 01226 01227 shared_ptr<void> p2; 01228 01229 p1 = p2; 01230 01231 assert(p1 == p2); 01232 assert(p1? false: true); 01233 assert(!p1); 01234 assert(p1.get() == 0); 01235 01236 shared_ptr<void> p3(p1); 01237 01238 p1 = p3; 01239 01240 assert(p1 == p3); 01241 assert(p1? false: true); 01242 assert(!p1); 01243 assert(p1.get() == 0); 01244 01245 shared_ptr<void> p4(new int); 01246 assert(p4.use_count() == 1); 01247 01248 p1 = p4; 01249 01250 assert(p1 == p4); 01251 assert(!(p1 < p4 || p4 < p1)); 01252 assert(p1.use_count() == 2); 01253 assert(p4.use_count() == 2); 01254 01255 p1 = p3; 01256 01257 assert(p1 == p3); 01258 assert(p4.use_count() == 1); 01259 } 01260 01261 { 01262 shared_ptr<X> p1; 01263 01264 p1 = p1; 01265 01266 assert(p1 == p1); 01267 assert(p1? false: true); 01268 assert(!p1); 01269 assert(p1.get() == 0); 01270 01271 shared_ptr<X> p2; 01272 01273 p1 = p2; 01274 01275 assert(p1 == p2); 01276 assert(p1? false: true); 01277 assert(!p1); 01278 assert(p1.get() == 0); 01279 01280 shared_ptr<X> p3(p1); 01281 01282 p1 = p3; 01283 01284 assert(p1 == p3); 01285 assert(p1? false: true); 01286 assert(!p1); 01287 assert(p1.get() == 0); 01288 01289 assert(X::instances == 0); 01290 01291 shared_ptr<X> p4(new X); 01292 01293 assert(X::instances == 1); 01294 01295 p1 = p4; 01296 01297 assert(X::instances == 1); 01298 01299 assert(p1 == p4); 01300 assert(!(p1 < p4 || p4 < p1)); 01301 01302 assert(p1.use_count() == 2); 01303 01304 p1 = p2; 01305 01306 assert(p1 == p2); 01307 assert(X::instances == 1); 01308 01309 p4 = p3; 01310 01311 assert(p4 == p3); 01312 assert(X::instances == 0); 01313 } 01314 } 01315 01316 void 01317 conversion_assignment() 01318 { 01319 { 01320 shared_ptr<void> p1; 01321 01322 shared_ptr<incomplete> p2; 01323 01324 p1 = p2; 01325 01326 assert(p1 == p2); 01327 assert(p1? false: true); 01328 assert(!p1); 01329 assert(p1.get() == 0); 01330 01331 shared_ptr<int> p4(new int); 01332 assert(p4.use_count() == 1); 01333 01334 shared_ptr<void> p5(p4); 01335 assert(p4.use_count() == 2); 01336 01337 p1 = p4; 01338 01339 assert(p1 == p4); 01340 assert(!(p1 < p5 || p5 < p1)); 01341 assert(p1.use_count() == 3); 01342 assert(p4.use_count() == 3); 01343 01344 p1 = p2; 01345 01346 assert(p1 == p2); 01347 assert(p4.use_count() == 2); 01348 } 01349 01350 { 01351 shared_ptr<X> p1; 01352 01353 shared_ptr<Y> p2; 01354 01355 p1 = p2; 01356 01357 assert(p1 == p2); 01358 assert(p1? false: true); 01359 assert(!p1); 01360 assert(p1.get() == 0); 01361 01362 assert(X::instances == 0); 01363 assert(Y::instances == 0); 01364 01365 shared_ptr<Y> p4(new Y); 01366 01367 assert(X::instances == 1); 01368 assert(Y::instances == 1); 01369 assert(p4.use_count() == 1); 01370 01371 shared_ptr<X> p5(p4); 01372 assert(p4.use_count() == 2); 01373 01374 p1 = p4; 01375 01376 assert(X::instances == 1); 01377 assert(Y::instances == 1); 01378 01379 assert(p1 == p4); 01380 assert(!(p1 < p5 || p5 < p1)); 01381 01382 assert(p1.use_count() == 3); 01383 assert(p4.use_count() == 3); 01384 01385 p1 = p2; 01386 01387 assert(p1 == p2); 01388 assert(X::instances == 1); 01389 assert(Y::instances == 1); 01390 assert(p4.use_count() == 2); 01391 01392 p4 = p2; 01393 p5 = p2; 01394 01395 assert(p4 == p2); 01396 assert(X::instances == 0); 01397 assert(Y::instances == 0); 01398 } 01399 } 01400 01401 void 01402 auto_ptr_assignment() 01403 { 01404 { 01405 shared_ptr<int> p1; 01406 01407 std::auto_ptr<int> p2; 01408 01409 p1 = p2; 01410 assert(p1? false: true); 01411 assert(!p1); 01412 assert(p1.get() == 0); 01413 assert(p1.use_count() == 1); 01414 01415 int * p = new int; 01416 std::auto_ptr<int> p3(p); 01417 01418 p1 = p3; 01419 assert(p1.get() == p); 01420 assert(p1.use_count() == 1); 01421 01422 assert(p3.get() == 0); 01423 01424 p1 = p2; 01425 assert(p1? false: true); 01426 assert(!p1); 01427 assert(p1.get() == 0); 01428 assert(p1.use_count() == 1); 01429 } 01430 01431 { 01432 shared_ptr<void> p1; 01433 01434 std::auto_ptr<int> p2; 01435 01436 p1 = p2; 01437 assert(p1? false: true); 01438 assert(!p1); 01439 assert(p1.get() == 0); 01440 assert(p1.use_count() == 1); 01441 01442 int * p = new int; 01443 std::auto_ptr<int> p3(p); 01444 01445 p1 = p3; 01446 assert(p1.get() == p); 01447 assert(p1.use_count() == 1); 01448 01449 assert(p3.get() == 0); 01450 01451 p1 = p2; 01452 assert(p1? false: true); 01453 assert(!p1); 01454 assert(p1.get() == 0); 01455 assert(p1.use_count() == 1); 01456 } 01457 01458 01459 { 01460 shared_ptr<X> p1; 01461 01462 std::auto_ptr<Y> p2; 01463 01464 p1 = p2; 01465 assert(p1? false: true); 01466 assert(!p1); 01467 assert(p1.get() == 0); 01468 assert(p1.use_count() == 1); 01469 assert(X::instances == 0); 01470 assert(Y::instances == 0); 01471 01472 Y * p = new Y; 01473 std::auto_ptr<Y> p3(p); 01474 01475 assert(X::instances == 1); 01476 assert(Y::instances == 1); 01477 01478 p1 = p3; 01479 assert(p1.get() == p); 01480 assert(p1.use_count() == 1); 01481 assert(X::instances == 1); 01482 assert(Y::instances == 1); 01483 01484 assert(p3.get() == 0); 01485 01486 p1 = p2; 01487 assert(p1? false: true); 01488 assert(!p1); 01489 assert(p1.get() == 0); 01490 assert(p1.use_count() == 1); 01491 assert(X::instances == 0); 01492 assert(Y::instances == 0); 01493 } 01494 } 01495 01496 void 01497 test() 01498 { 01499 copy_assignment(); 01500 conversion_assignment(); 01501 auto_ptr_assignment(); 01502 } 01503 01504 } // namespace n_assignment 01505 01506 namespace n_reset 01507 { 01508 01509 class incomplete; 01510 01511 incomplete * p0 = 0; 01512 01513 void 01514 deleter(incomplete *) 01515 { 01516 } 01517 01518 struct X 01519 { 01520 static long instances; 01521 01522 X() 01523 { 01524 ++instances; 01525 } 01526 01527 ~X() 01528 { 01529 --instances; 01530 } 01531 01532 private: 01533 X(X const &); 01534 X & operator= (X const &); 01535 }; 01536 01537 long X::instances = 0; 01538 01539 void 01540 plain_reset() 01541 { 01542 { 01543 shared_ptr<int> pi; 01544 pi.reset(); 01545 assert(pi? false: true); 01546 assert(!pi); 01547 assert(pi.get() == 0); 01548 assert(pi.use_count() == 0); 01549 } 01550 01551 { 01552 shared_ptr<int> pi(static_cast<int*>(0)); 01553 pi.reset(); 01554 assert(pi? false: true); 01555 assert(!pi); 01556 assert(pi.get() == 0); 01557 assert(pi.use_count() == 0); 01558 } 01559 01560 { 01561 shared_ptr<int> pi(new int); 01562 pi.reset(); 01563 assert(pi? false: true); 01564 assert(!pi); 01565 assert(pi.get() == 0); 01566 assert(pi.use_count() == 0); 01567 } 01568 01569 { 01570 shared_ptr<incomplete> px; 01571 px.reset(); 01572 assert(px? false: true); 01573 assert(!px); 01574 assert(px.get() == 0); 01575 assert(px.use_count() == 0); 01576 } 01577 01578 { 01579 shared_ptr<incomplete> px(p0, deleter); 01580 px.reset(); 01581 assert(px? false: true); 01582 assert(!px); 01583 assert(px.get() == 0); 01584 assert(px.use_count() == 0); 01585 } 01586 01587 { 01588 shared_ptr<X> px; 01589 px.reset(); 01590 assert(px? false: true); 01591 assert(!px); 01592 assert(px.get() == 0); 01593 assert(px.use_count() == 0); 01594 } 01595 01596 { 01597 assert(X::instances == 0); 01598 shared_ptr<X> px(new X); 01599 assert(X::instances == 1); 01600 px.reset(); 01601 assert(px? false: true); 01602 assert(!px); 01603 assert(px.get() == 0); 01604 assert(px.use_count() == 0); 01605 assert(X::instances == 0); 01606 } 01607 01608 { 01609 shared_ptr<void> pv; 01610 pv.reset(); 01611 assert(pv? false: true); 01612 assert(!pv); 01613 assert(pv.get() == 0); 01614 assert(pv.use_count() == 0); 01615 } 01616 01617 { 01618 assert(X::instances == 0); 01619 shared_ptr<void> pv(new X); 01620 assert(X::instances == 1); 01621 pv.reset(); 01622 assert(pv? false: true); 01623 assert(!pv); 01624 assert(pv.get() == 0); 01625 assert(pv.use_count() == 0); 01626 assert(X::instances == 0); 01627 } 01628 } 01629 01630 struct A 01631 { 01632 int dummy; 01633 }; 01634 01635 struct Y 01636 : public A 01637 , public virtual X 01638 { 01639 static long instances; 01640 01641 Y() 01642 { 01643 ++instances; 01644 } 01645 01646 ~Y() 01647 { 01648 --instances; 01649 } 01650 01651 private: 01652 Y(Y const &); 01653 Y & operator= (Y const &); 01654 }; 01655 01656 long Y::instances = 0; 01657 01658 void 01659 pointer_reset() 01660 { 01661 { 01662 shared_ptr<int> pi; 01663 01664 pi.reset(static_cast<int*>(0)); 01665 assert(pi? false: true); 01666 assert(!pi); 01667 assert(pi.get() == 0); 01668 assert(pi.use_count() == 1); 01669 assert(pi.unique()); 01670 01671 int * p = new int; 01672 pi.reset(p); 01673 assert(pi? true: false); 01674 assert(!!pi); 01675 assert(pi.get() == p); 01676 assert(pi.use_count() == 1); 01677 assert(pi.unique()); 01678 01679 pi.reset(static_cast<int*>(0)); 01680 assert(pi? false: true); 01681 assert(!pi); 01682 assert(pi.get() == 0); 01683 assert(pi.use_count() == 1); 01684 assert(pi.unique()); 01685 } 01686 01687 { 01688 shared_ptr<X> px; 01689 01690 px.reset(static_cast<X*>(0)); 01691 assert(px? false: true); 01692 assert(!px); 01693 assert(px.get() == 0); 01694 assert(px.use_count() == 1); 01695 assert(px.unique()); 01696 assert(X::instances == 0); 01697 01698 X * p = new X; 01699 px.reset(p); 01700 assert(px? true: false); 01701 assert(!!px); 01702 assert(px.get() == p); 01703 assert(px.use_count() == 1); 01704 assert(px.unique()); 01705 assert(X::instances == 1); 01706 01707 px.reset(static_cast<X*>(0)); 01708 assert(px? false: true); 01709 assert(!px); 01710 assert(px.get() == 0); 01711 assert(px.use_count() == 1); 01712 assert(px.unique()); 01713 assert(X::instances == 0); 01714 assert(Y::instances == 0); 01715 01716 Y * q = new Y; 01717 px.reset(q); 01718 assert(px? true: false); 01719 assert(!!px); 01720 assert(px.get() == q); 01721 assert(px.use_count() == 1); 01722 assert(px.unique()); 01723 assert(X::instances == 1); 01724 assert(Y::instances == 1); 01725 01726 px.reset(static_cast<Y*>(0)); 01727 assert(px? false: true); 01728 assert(!px); 01729 assert(px.get() == 0); 01730 assert(px.use_count() == 1); 01731 assert(px.unique()); 01732 assert(X::instances == 0); 01733 assert(Y::instances == 0); 01734 } 01735 01736 { 01737 shared_ptr<void> pv; 01738 01739 pv.reset(static_cast<X*>(0)); 01740 assert(pv? false: true); 01741 assert(!pv); 01742 assert(pv.get() == 0); 01743 assert(pv.use_count() == 1); 01744 assert(pv.unique()); 01745 assert(X::instances == 0); 01746 01747 X * p = new X; 01748 pv.reset(p); 01749 assert(pv? true: false); 01750 assert(!!pv); 01751 assert(pv.get() == p); 01752 assert(pv.use_count() == 1); 01753 assert(pv.unique()); 01754 assert(X::instances == 1); 01755 01756 pv.reset(static_cast<X*>(0)); 01757 assert(pv? false: true); 01758 assert(!pv); 01759 assert(pv.get() == 0); 01760 assert(pv.use_count() == 1); 01761 assert(pv.unique()); 01762 assert(X::instances == 0); 01763 assert(Y::instances == 0); 01764 01765 Y * q = new Y; 01766 pv.reset(q); 01767 assert(pv? true: false); 01768 assert(!!pv); 01769 assert(pv.get() == q); 01770 assert(pv.use_count() == 1); 01771 assert(pv.unique()); 01772 assert(X::instances == 1); 01773 assert(Y::instances == 1); 01774 01775 pv.reset(static_cast<Y*>(0)); 01776 assert(pv? false: true); 01777 assert(!pv); 01778 assert(pv.get() == 0); 01779 assert(pv.use_count() == 1); 01780 assert(pv.unique()); 01781 assert(X::instances == 0); 01782 assert(Y::instances == 0); 01783 } 01784 } 01785 01786 void 01787 * deleted = 0; 01788 01789 void 01790 deleter2(void * p) 01791 { 01792 deleted = p; 01793 } 01794 01795 void 01796 deleter_reset() 01797 { 01798 { 01799 shared_ptr<int> pi; 01800 01801 pi.reset(static_cast<int*>(0), deleter2); 01802 assert(pi? false: true); 01803 assert(!pi); 01804 assert(pi.get() == 0); 01805 assert(pi.use_count() == 1); 01806 assert(pi.unique()); 01807 01808 deleted = π 01809 01810 int m = 0; 01811 pi.reset(&m, deleter2); 01812 assert(deleted == 0); 01813 assert(pi? true: false); 01814 assert(!!pi); 01815 assert(pi.get() == &m); 01816 assert(pi.use_count() == 1); 01817 assert(pi.unique()); 01818 01819 pi.reset(static_cast<int*>(0), deleter2); 01820 assert(deleted == &m); 01821 assert(pi? false: true); 01822 assert(!pi); 01823 assert(pi.get() == 0); 01824 assert(pi.use_count() == 1); 01825 assert(pi.unique()); 01826 01827 pi.reset(); 01828 assert(deleted == 0); 01829 } 01830 01831 { 01832 shared_ptr<X> px; 01833 01834 px.reset(static_cast<X*>(0), deleter2); 01835 assert(px? false: true); 01836 assert(!px); 01837 assert(px.get() == 0); 01838 assert(px.use_count() == 1); 01839 assert(px.unique()); 01840 01841 deleted = &px; 01842 01843 X x; 01844 px.reset(&x, deleter2); 01845 assert(deleted == 0); 01846 assert(px? true: false); 01847 assert(!!px); 01848 assert(px.get() == &x); 01849 assert(px.use_count() == 1); 01850 assert(px.unique()); 01851 01852 px.reset(static_cast<X*>(0), deleter2); 01853 assert(deleted == &x); 01854 assert(px? false: true); 01855 assert(!px); 01856 assert(px.get() == 0); 01857 assert(px.use_count() == 1); 01858 assert(px.unique()); 01859 01860 Y y; 01861 px.reset(&y, deleter2); 01862 assert(deleted == 0); 01863 assert(px? true: false); 01864 assert(!!px); 01865 assert(px.get() == &y); 01866 assert(px.use_count() == 1); 01867 assert(px.unique()); 01868 01869 px.reset(static_cast<Y*>(0), deleter2); 01870 assert(deleted == &y); 01871 assert(px? false: true); 01872 assert(!px); 01873 assert(px.get() == 0); 01874 assert(px.use_count() == 1); 01875 assert(px.unique()); 01876 01877 px.reset(); 01878 assert(deleted == 0); 01879 } 01880 01881 { 01882 shared_ptr<void> pv; 01883 01884 pv.reset(static_cast<X*>(0), deleter2); 01885 assert(pv? false: true); 01886 assert(!pv); 01887 assert(pv.get() == 0); 01888 assert(pv.use_count() == 1); 01889 assert(pv.unique()); 01890 01891 deleted = &pv; 01892 01893 X x; 01894 pv.reset(&x, deleter2); 01895 assert(deleted == 0); 01896 assert(pv? true: false); 01897 assert(!!pv); 01898 assert(pv.get() == &x); 01899 assert(pv.use_count() == 1); 01900 assert(pv.unique()); 01901 01902 pv.reset(static_cast<X*>(0), deleter2); 01903 assert(deleted == &x); 01904 assert(pv? false: true); 01905 assert(!pv); 01906 assert(pv.get() == 0); 01907 assert(pv.use_count() == 1); 01908 assert(pv.unique()); 01909 01910 Y y; 01911 pv.reset(&y, deleter2); 01912 assert(deleted == 0); 01913 assert(pv? true: false); 01914 assert(!!pv); 01915 assert(pv.get() == &y); 01916 assert(pv.use_count() == 1); 01917 assert(pv.unique()); 01918 01919 pv.reset(static_cast<Y*>(0), deleter2); 01920 assert(deleted == &y); 01921 assert(pv? false: true); 01922 assert(!pv); 01923 assert(pv.get() == 0); 01924 assert(pv.use_count() == 1); 01925 assert(pv.unique()); 01926 01927 pv.reset(); 01928 assert(deleted == 0); 01929 } 01930 01931 { 01932 shared_ptr<incomplete> px; 01933 01934 px.reset(p0, deleter2); 01935 assert(px? false: true); 01936 assert(!px); 01937 assert(px.get() == 0); 01938 assert(px.use_count() == 1); 01939 assert(px.unique()); 01940 01941 deleted = &px; 01942 px.reset(p0, deleter2); 01943 assert(deleted == 0); 01944 } 01945 } 01946 01947 void 01948 test() 01949 { 01950 plain_reset(); 01951 pointer_reset(); 01952 deleter_reset(); 01953 } 01954 01955 } // namespace n_reset 01956 01957 namespace n_access 01958 { 01959 01960 struct X 01961 { 01962 }; 01963 01964 void 01965 test() 01966 { 01967 { 01968 shared_ptr<X> px; 01969 assert(px.get() == 0); 01970 assert(px? false: true); 01971 assert(!px); 01972 01973 assert(get_pointer(px) == px.get()); 01974 } 01975 01976 { 01977 shared_ptr<X> px(static_cast<X*>(0)); 01978 assert(px.get() == 0); 01979 assert(px? false: true); 01980 assert(!px); 01981 01982 assert(get_pointer(px) == px.get()); 01983 } 01984 01985 #if 0 01986 { 01987 shared_ptr<X> px(static_cast<X*>(0), checked_deleter<X>()); 01988 assert(px.get() == 0); 01989 assert(px? false: true); 01990 assert(!px); 01991 01992 assert(get_pointer(px) == px.get()); 01993 } 01994 #endif // 0 01995 01996 { 01997 X * p = new X; 01998 shared_ptr<X> px(p); 01999 assert(px.get() == p); 02000 assert(px? true: false); 02001 assert(!!px); 02002 assert(&*px == px.get()); 02003 assert(px.operator ->() == px.get()); 02004 02005 assert(get_pointer(px) == px.get()); 02006 } 02007 02008 #if 0 02009 { 02010 X * p = new X; 02011 shared_ptr<X> px(p, checked_deleter<X>()); 02012 assert(px.get() == p); 02013 assert(px? true: false); 02014 assert(!!px); 02015 assert(&*px == px.get()); 02016 assert(px.operator ->() == px.get()); 02017 02018 assert(get_pointer(px) == px.get()); 02019 } 02020 #endif // 0 02021 } 02022 02023 } // namespace n_access 02024 02025 namespace n_use_count 02026 { 02027 02028 struct X 02029 { 02030 }; 02031 02032 void 02033 test() 02034 { 02035 { 02036 shared_ptr<X> px(static_cast<X*>(0)); 02037 assert(px.use_count() == 1); 02038 assert(px.unique()); 02039 02040 shared_ptr<X> px2(px); 02041 assert(px2.use_count() == 2); 02042 assert(!px2.unique()); 02043 assert(px.use_count() == 2); 02044 assert(!px.unique()); 02045 } 02046 02047 { 02048 shared_ptr<X> px(new X); 02049 assert(px.use_count() == 1); 02050 assert(px.unique()); 02051 02052 shared_ptr<X> px2(px); 02053 assert(px2.use_count() == 2); 02054 assert(!px2.unique()); 02055 assert(px.use_count() == 2); 02056 assert(!px.unique()); 02057 } 02058 02059 #if 0 02060 { 02061 shared_ptr<X> px(new X, checked_deleter<X>()); 02062 assert(px.use_count() == 1); 02063 assert(px.unique()); 02064 02065 shared_ptr<X> px2(px); 02066 assert(px2.use_count() == 2); 02067 assert(!px2.unique()); 02068 assert(px.use_count() == 2); 02069 assert(!px.unique()); 02070 } 02071 #endif // 0 02072 } 02073 02074 } // namespace n_use_count 02075 02076 namespace n_swap 02077 { 02078 02079 struct X 02080 { 02081 }; 02082 02083 void 02084 test() 02085 { 02086 { 02087 shared_ptr<X> px; 02088 shared_ptr<X> px2; 02089 02090 px.swap(px2); 02091 02092 assert(px.get() == 0); 02093 assert(px2.get() == 0); 02094 02095 using std::swap; 02096 swap(px, px2); 02097 02098 assert(px.get() == 0); 02099 assert(px2.get() == 0); 02100 } 02101 02102 { 02103 X * p = new X; 02104 shared_ptr<X> px; 02105 shared_ptr<X> px2(p); 02106 shared_ptr<X> px3(px2); 02107 02108 px.swap(px2); 02109 02110 assert(px.get() == p); 02111 assert(px.use_count() == 2); 02112 assert(px2.get() == 0); 02113 assert(px3.get() == p); 02114 assert(px3.use_count() == 2); 02115 02116 using std::swap; 02117 swap(px, px2); 02118 02119 assert(px.get() == 0); 02120 assert(px2.get() == p); 02121 assert(px2.use_count() == 2); 02122 assert(px3.get() == p); 02123 assert(px3.use_count() == 2); 02124 } 02125 02126 { 02127 X * p1 = new X; 02128 X * p2 = new X; 02129 shared_ptr<X> px(p1); 02130 shared_ptr<X> px2(p2); 02131 shared_ptr<X> px3(px2); 02132 02133 px.swap(px2); 02134 02135 assert(px.get() == p2); 02136 assert(px.use_count() == 2); 02137 assert(px2.get() == p1); 02138 assert(px2.use_count() == 1); 02139 assert(px3.get() == p2); 02140 assert(px3.use_count() == 2); 02141 02142 using std::swap; 02143 swap(px, px2); 02144 02145 assert(px.get() == p1); 02146 assert(px.use_count() == 1); 02147 assert(px2.get() == p2); 02148 assert(px2.use_count() == 2); 02149 assert(px3.get() == p2); 02150 assert(px3.use_count() == 2); 02151 } 02152 } 02153 02154 } // namespace n_swap 02155 02156 namespace n_comparison 02157 { 02158 02159 struct X 02160 { 02161 int dummy; 02162 }; 02163 02164 struct Y 02165 { 02166 int dummy2; 02167 }; 02168 02169 struct Z 02170 : public X 02171 , public virtual Y 02172 { 02173 }; 02174 02175 void 02176 test() 02177 { 02178 { 02179 shared_ptr<X> px; 02180 assert(px == px); 02181 assert(!(px != px)); 02182 assert(!(px < px)); 02183 02184 shared_ptr<X> px2; 02185 02186 assert(px.get() == px2.get()); 02187 assert(px == px2); 02188 assert(!(px != px2)); 02189 assert(!(px < px2 && px2 < px)); 02190 } 02191 02192 { 02193 shared_ptr<X> px; 02194 shared_ptr<X> px2(px); 02195 02196 assert(px2 == px2); 02197 assert(!(px2 != px2)); 02198 assert(!(px2 < px2)); 02199 02200 assert(px.get() == px2.get()); 02201 assert(px == px2); 02202 assert(!(px != px2)); 02203 assert(!(px < px2 && px2 < px)); 02204 } 02205 02206 { 02207 shared_ptr<X> px; 02208 shared_ptr<X> px2(new X); 02209 02210 assert(px2 == px2); 02211 assert(!(px2 != px2)); 02212 assert(!(px2 < px2)); 02213 02214 assert(px.get() != px2.get()); 02215 assert(px != px2); 02216 assert(!(px == px2)); 02217 assert(px < px2 || px2 < px); 02218 assert(!(px < px2 && px2 < px)); 02219 } 02220 02221 { 02222 shared_ptr<X> px(new X); 02223 shared_ptr<X> px2(new X); 02224 02225 assert(px.get() != px2.get()); 02226 assert(px != px2); 02227 assert(!(px == px2)); 02228 assert(px < px2 || px2 < px); 02229 assert(!(px < px2 && px2 < px)); 02230 } 02231 02232 { 02233 shared_ptr<X> px(new X); 02234 shared_ptr<X> px2(px); 02235 02236 assert(px2 == px2); 02237 assert(!(px2 != px2)); 02238 assert(!(px2 < px2)); 02239 02240 assert(px.get() == px2.get()); 02241 assert(px == px2); 02242 assert(!(px != px2)); 02243 assert(!(px < px2 || px2 < px)); 02244 } 02245 02246 { 02247 shared_ptr<X> px(new X); 02248 shared_ptr<Y> py(new Y); 02249 shared_ptr<Z> pz(new Z); 02250 02251 assert(px.get() != pz.get()); 02252 assert(px != pz); 02253 assert(!(px == pz)); 02254 02255 assert(py.get() != pz.get()); 02256 assert(py != pz); 02257 assert(!(py == pz)); 02258 02259 assert(px < py || py < px); 02260 assert(px < pz || pz < px); 02261 assert(py < pz || pz < py); 02262 02263 assert(!(px < py && py < px)); 02264 assert(!(px < pz && pz < px)); 02265 assert(!(py < pz && pz < py)); 02266 02267 shared_ptr<void> pvx(px); 02268 02269 assert(pvx == pvx); 02270 assert(!(pvx != pvx)); 02271 assert(!(pvx < pvx)); 02272 02273 shared_ptr<void> pvy(py); 02274 shared_ptr<void> pvz(pz); 02275 02276 assert(pvx < pvy || pvy < pvx); 02277 assert(pvx < pvz || pvz < pvx); 02278 assert(pvy < pvz || pvz < pvy); 02279 02280 assert(!(pvx < pvy && pvy < pvx)); 02281 assert(!(pvx < pvz && pvz < pvx)); 02282 assert(!(pvy < pvz && pvz < pvy)); 02283 } 02284 02285 { 02286 shared_ptr<Z> pz(new Z); 02287 shared_ptr<X> px(pz); 02288 02289 assert(px == px); 02290 assert(!(px != px)); 02291 assert(!(px < px)); 02292 02293 shared_ptr<Y> py(pz); 02294 02295 assert(px.get() == pz.get()); 02296 assert(px == pz); 02297 assert(!(px != pz)); 02298 02299 assert(py.get() == pz.get()); 02300 assert(py == pz); 02301 assert(!(py != pz)); 02302 02303 assert(!(px < py || py < px)); 02304 assert(!(px < pz || pz < px)); 02305 assert(!(py < pz || pz < py)); 02306 02307 shared_ptr<void> pvx(px); 02308 shared_ptr<void> pvy(py); 02309 shared_ptr<void> pvz(pz); 02310 02311 // pvx and pvy aren't equal... 02312 assert(pvx.get() != pvy.get()); 02313 assert(pvx != pvy); 02314 assert(!(pvx == pvy)); 02315 02316 // ... but they share ownership ... 02317 assert(!(pvx < pvy || pvy < pvx)); 02318 02319 // ... with pvz 02320 assert(!(pvx < pvz || pvz < pvx)); 02321 assert(!(pvy < pvz || pvz < pvy)); 02322 } 02323 } 02324 02325 } // namespace n_comparison 02326 02327 namespace n_static_cast 02328 { 02329 02330 struct X 02331 { 02332 }; 02333 02334 struct Y 02335 : public X 02336 { }; 02337 02338 void 02339 test() 02340 { 02341 { 02342 shared_ptr<void> pv; 02343 02344 shared_ptr<int> pi = static_pointer_cast<int>(pv); 02345 assert(pi.get() == 0); 02346 02347 shared_ptr<X> px = static_pointer_cast<X>(pv); 02348 assert(px.get() == 0); 02349 } 02350 02351 { 02352 shared_ptr<int> pi(new int); 02353 shared_ptr<void> pv(pi); 02354 02355 shared_ptr<int> pi2 = static_pointer_cast<int>(pv); 02356 assert(pi.get() == pi2.get()); 02357 assert(!(pi < pi2 || pi2 < pi)); 02358 assert(pi.use_count() == 3); 02359 assert(pv.use_count() == 3); 02360 assert(pi2.use_count() == 3); 02361 } 02362 02363 { 02364 shared_ptr<X> px(new X); 02365 shared_ptr<void> pv(px); 02366 02367 shared_ptr<X> px2 = static_pointer_cast<X>(pv); 02368 assert(px.get() == px2.get()); 02369 assert(!(px < px2 || px2 < px)); 02370 assert(px.use_count() == 3); 02371 assert(pv.use_count() == 3); 02372 assert(px2.use_count() == 3); 02373 } 02374 02375 { 02376 shared_ptr<X> px(new Y); 02377 02378 shared_ptr<Y> py = static_pointer_cast<Y>(px); 02379 assert(px.get() == py.get()); 02380 assert(px.use_count() == 2); 02381 assert(py.use_count() == 2); 02382 02383 shared_ptr<X> px2(py); 02384 assert(!(px < px2 || px2 < px)); 02385 } 02386 } 02387 02388 } // namespace n_static_cast 02389 02390 namespace n_const_cast 02391 { 02392 02393 struct X; 02394 02395 void 02396 test() 02397 { 02398 { 02399 shared_ptr<void const volatile> px; 02400 02401 shared_ptr<void> px2 = const_pointer_cast<void>(px); 02402 assert(px2.get() == 0); 02403 } 02404 02405 { 02406 shared_ptr<int const volatile> px; 02407 02408 shared_ptr<int> px2 = const_pointer_cast<int>(px); 02409 assert(px2.get() == 0); 02410 } 02411 02412 { 02413 shared_ptr<X const volatile> px; 02414 02415 shared_ptr<X> px2 = const_pointer_cast<X>(px); 02416 assert(px2.get() == 0); 02417 } 02418 02419 { 02420 shared_ptr<void const volatile> px(new int); 02421 02422 shared_ptr<void> px2 = const_pointer_cast<void>(px); 02423 assert(px.get() == px2.get()); 02424 assert(!(px < px2 || px2 < px)); 02425 assert(px.use_count() == 2); 02426 assert(px2.use_count() == 2); 02427 } 02428 02429 { 02430 shared_ptr<int const volatile> px(new int); 02431 02432 shared_ptr<int> px2 = const_pointer_cast<int>(px); 02433 assert(px.get() == px2.get()); 02434 assert(!(px < px2 || px2 < px)); 02435 assert(px.use_count() == 2); 02436 assert(px2.use_count() == 2); 02437 } 02438 } 02439 02440 } // namespace n_const_cast 02441 02442 namespace n_dynamic_cast 02443 { 02444 02445 struct V 02446 { 02447 virtual ~V() {} 02448 }; 02449 02450 struct W 02451 : public V 02452 { }; 02453 02454 void 02455 test() 02456 { 02457 { 02458 shared_ptr<V> pv; 02459 shared_ptr<W> pw = dynamic_pointer_cast<W>(pv); 02460 assert(pw.get() == 0); 02461 } 02462 02463 { 02464 shared_ptr<V> pv(static_cast<V*>(0)); 02465 02466 shared_ptr<W> pw = dynamic_pointer_cast<W>(pv); 02467 assert(pw.get() == 0); 02468 02469 shared_ptr<V> pv2(pw); 02470 assert(pv < pv2 || pv2 < pv); 02471 } 02472 02473 { 02474 shared_ptr<V> pv(static_cast<W*>(0)); 02475 02476 shared_ptr<W> pw = dynamic_pointer_cast<W>(pv); 02477 assert(pw.get() == 0); 02478 02479 shared_ptr<V> pv2(pw); 02480 assert(pv < pv2 || pv2 < pv); 02481 } 02482 02483 { 02484 shared_ptr<V> pv(new V); 02485 02486 shared_ptr<W> pw = dynamic_pointer_cast<W>(pv); 02487 assert(pw.get() == 0); 02488 02489 shared_ptr<V> pv2(pw); 02490 assert(pv < pv2 || pv2 < pv); 02491 } 02492 02493 { 02494 shared_ptr<V> pv(new W); 02495 02496 shared_ptr<W> pw = dynamic_pointer_cast<W>(pv); 02497 assert(pw.get() == pv.get()); 02498 assert(pv.use_count() == 2); 02499 assert(pw.use_count() == 2); 02500 02501 shared_ptr<V> pv2(pw); 02502 assert(!(pv < pv2 || pv2 < pv)); 02503 } 02504 } 02505 02506 } // namespace n_dynamic_cast 02507 02508 namespace n_map 02509 { 02510 02511 struct X 02512 { 02513 }; 02514 02515 void 02516 test() 02517 { 02518 std::vector< shared_ptr<int> > vi; 02519 02520 { 02521 shared_ptr<int> pi1(new int); 02522 shared_ptr<int> pi2(new int); 02523 shared_ptr<int> pi3(new int); 02524 02525 vi.push_back(pi1); 02526 vi.push_back(pi1); 02527 vi.push_back(pi1); 02528 vi.push_back(pi2); 02529 vi.push_back(pi1); 02530 vi.push_back(pi2); 02531 vi.push_back(pi1); 02532 vi.push_back(pi3); 02533 vi.push_back(pi3); 02534 vi.push_back(pi2); 02535 vi.push_back(pi1); 02536 } 02537 02538 std::vector< shared_ptr<X> > vx; 02539 02540 { 02541 shared_ptr<X> px1(new X); 02542 shared_ptr<X> px2(new X); 02543 shared_ptr<X> px3(new X); 02544 02545 vx.push_back(px2); 02546 vx.push_back(px2); 02547 vx.push_back(px1); 02548 vx.push_back(px2); 02549 vx.push_back(px1); 02550 vx.push_back(px1); 02551 vx.push_back(px1); 02552 vx.push_back(px2); 02553 vx.push_back(px1); 02554 vx.push_back(px3); 02555 vx.push_back(px2); 02556 } 02557 02558 std::map< shared_ptr<void>, long > m; 02559 02560 { 02561 for(std::vector< shared_ptr<int> >::iterator i = vi.begin(); i != vi.end(); ++i) 02562 { 02563 ++m[*i]; 02564 } 02565 } 02566 02567 { 02568 for(std::vector< shared_ptr<X> >::iterator i = vx.begin(); i != vx.end(); ++i) 02569 { 02570 ++m[*i]; 02571 } 02572 } 02573 02574 { 02575 for(std::map< shared_ptr<void>, long >::iterator i = m.begin(); i != m.end(); ++i) 02576 { 02577 assert(i->first.use_count() == i->second + 1); 02578 } 02579 } 02580 } 02581 02582 } // namespace n_map 02583 02584 namespace n_transitive 02585 { 02586 02587 struct X 02588 { 02589 X(): next() {} 02590 shared_ptr<X> next; 02591 }; 02592 02593 void 02594 test() 02595 { 02596 shared_ptr<X> p(new X); 02597 p->next = shared_ptr<X>(new X); 02598 assert(!p->next->next); 02599 p = p->next; 02600 assert(!p->next); 02601 } 02602 02603 } // namespace n_transitive 02604 02605 #if 0 02606 namespace n_report_1 02607 { 02608 02609 class foo 02610 { 02611 public: 02612 02613 foo(): m_self(this) 02614 { } 02615 02616 void suicide() 02617 { m_self.reset(); } 02618 02619 private: 02620 shared_ptr<foo> m_self; 02621 }; 02622 02623 void 02624 test() 02625 { 02626 foo * foo_ptr = new foo; 02627 foo_ptr->suicide(); 02628 } 02629 02630 } // namespace n_report_1 02631 #endif // 0 02632 02633 // Test case by Per Kristensen 02634 namespace n_report_2 02635 { 02636 02637 class foo 02638 { 02639 public: 02640 02641 void setWeak(shared_ptr<foo> s) 02642 { 02643 w = s; 02644 } 02645 02646 private: 02647 02648 weak_ptr<foo> w; 02649 }; 02650 02651 class deleter 02652 { 02653 public: 02654 02655 deleter(): lock(0) 02656 { 02657 } 02658 02659 ~deleter() 02660 { 02661 assert(lock == 0); 02662 } 02663 02664 void operator() (foo * p) 02665 { 02666 ++lock; 02667 delete p; 02668 --lock; 02669 } 02670 02671 private: 02672 02673 int lock; 02674 }; 02675 02676 void 02677 test() 02678 { 02679 shared_ptr<foo> s(new foo, deleter()); 02680 s->setWeak(s); 02681 s.reset(); 02682 } 02683 02684 } // namespace n_report_2 02685 02686 namespace n_spt_incomplete 02687 { 02688 02689 class file; 02690 02691 shared_ptr<file> fopen(char const * name, char const * mode); 02692 void 02693 fread(shared_ptr<file> f, void * data, long size); 02694 02695 int file_instances = 0; 02696 02697 void 02698 test() 02699 { 02700 assert(file_instances == 0); 02701 02702 { 02703 shared_ptr<file> pf = fopen("name", "mode"); 02704 assert(file_instances == 1); 02705 fread(pf, 0, 17041); 02706 } 02707 02708 assert(file_instances == 0); 02709 } 02710 02711 } // namespace n_spt_incomplete 02712 02713 namespace n_spt_pimpl 02714 { 02715 02716 class file 02717 { 02718 private: 02719 class impl; 02720 shared_ptr<impl> pimpl_; 02721 02722 public: 02723 02724 file(char const * name, char const * mode); 02725 02726 // compiler generated members are fine and useful 02727 02728 void read(void * data, long size); 02729 02730 long total_size() const; 02731 }; 02732 02733 int file_instances = 0; 02734 02735 void 02736 test() 02737 { 02738 assert(file_instances == 0); 02739 02740 { 02741 file f("name", "mode"); 02742 assert(file_instances == 1); 02743 f.read(0, 152); 02744 02745 file f2(f); 02746 assert(file_instances == 1); 02747 f2.read(0, 894); 02748 02749 assert(f.total_size() == 152+894); 02750 02751 { 02752 file f3("name2", "mode2"); 02753 assert(file_instances == 2); 02754 } 02755 02756 assert(file_instances == 1); 02757 } 02758 02759 assert(file_instances == 0); 02760 } 02761 02762 } // namespace n_spt_pimpl 02763 02764 namespace n_spt_abstract 02765 { 02766 02767 class X 02768 { 02769 public: 02770 02771 virtual void f(int) = 0; 02772 virtual int g() = 0; 02773 02774 protected: 02775 02776 virtual ~X() {} 02777 }; 02778 02779 shared_ptr<X> createX(); 02780 02781 int X_instances = 0; 02782 02783 void 02784 test() 02785 { 02786 assert(X_instances == 0); 02787 02788 { 02789 shared_ptr<X> px = createX(); 02790 02791 assert(X_instances == 1); 02792 02793 px->f(18); 02794 px->f(152); 02795 02796 assert(px->g() == 170); 02797 } 02798 02799 assert(X_instances == 0); 02800 } 02801 02802 } // namespace n_spt_abstract 02803 02804 namespace n_spt_preventing_delete 02805 { 02806 02807 int X_instances = 0; 02808 02809 class X 02810 { 02811 private: 02812 X() 02813 { 02814 ++X_instances; 02815 } 02816 02817 ~X() 02818 { 02819 --X_instances; 02820 } 02821 02822 class deleter; 02823 friend class deleter; 02824 02825 class deleter 02826 { 02827 public: 02828 02829 void operator()(X * p) { delete p; } 02830 }; 02831 02832 public: 02833 02834 static shared_ptr<X> create() 02835 { 02836 shared_ptr<X> px(new X, X::deleter()); 02837 return px; 02838 } 02839 }; 02840 02841 void 02842 test() 02843 { 02844 assert(X_instances == 0); 02845 02846 { 02847 shared_ptr<X> px = X::create(); 02848 assert(X_instances == 1); 02849 } 02850 02851 assert(X_instances == 0); 02852 } 02853 02854 } // namespace n_spt_preventing_delete 02855 02856 namespace n_spt_array 02857 { 02858 02859 int X_instances = 0; 02860 02861 struct X 02862 { 02863 X() 02864 { 02865 ++X_instances; 02866 } 02867 02868 ~X() 02869 { 02870 --X_instances; 02871 } 02872 }; 02873 02874 void 02875 test() 02876 { 02877 assert(X_instances == 0); 02878 02879 #if 0 02880 { 02881 shared_ptr<X> px(new X[4], checked_array_deleter<X>()); 02882 assert(X_instances == 4); 02883 } 02884 #endif // 0 02885 02886 assert(X_instances == 0); 02887 } 02888 02889 } // namespace n_spt_array 02890 02891 namespace n_spt_static 02892 { 02893 02894 class X 02895 { 02896 public: 02897 02898 X() 02899 { 02900 } 02901 02902 private: 02903 void operator delete(void *) 02904 { 02905 throw "n_spt_static::X::operator delete() called."; 02906 } 02907 }; 02908 02909 struct null_deleter 02910 { 02911 void operator()(void const *) const 02912 { 02913 } 02914 }; 02915 02916 static X x; 02917 02918 void 02919 test() 02920 { 02921 shared_ptr<X> px(&x, null_deleter()); 02922 } 02923 02924 } // namespace n_spt_static 02925 02926 namespace n_spt_intrusive 02927 { 02928 02929 int X_instances = 0; 02930 02931 struct X 02932 { 02933 long count; 02934 02935 X(): count(0) 02936 { 02937 ++X_instances; 02938 } 02939 02940 ~X() 02941 { 02942 --X_instances; 02943 } 02944 }; 02945 02946 void 02947 intrusive_ptr_add_ref(X * p) 02948 { 02949 ++p->count; 02950 } 02951 02952 void 02953 intrusive_ptr_release(X * p) 02954 { 02955 if(--p->count == 0) delete p; 02956 } 02957 02958 template< class T > 02959 struct intrusive_deleter 02960 { 02961 void operator()(T * p) 02962 { 02963 if(p != 0) intrusive_ptr_release(p); 02964 } 02965 }; 02966 02967 shared_ptr<X> make_shared_from_intrusive(X * p) 02968 { 02969 if(p != 0) intrusive_ptr_add_ref(p); 02970 shared_ptr<X> px(p, intrusive_deleter<X>()); 02971 return px; 02972 } 02973 02974 void 02975 test() 02976 { 02977 assert(X_instances == 0); 02978 02979 { 02980 X * p = new X; 02981 assert(X_instances == 1); 02982 assert(p->count == 0); 02983 shared_ptr<X> px = make_shared_from_intrusive(p); 02984 assert(px.get() == p); 02985 assert(p->count == 1); 02986 shared_ptr<X> px2(px); 02987 assert(px2.get() == p); 02988 assert(p->count == 1); 02989 } 02990 02991 assert(X_instances == 0); 02992 } 02993 02994 } // namespace n_spt_intrusive 02995 02996 namespace n_spt_another_sp 02997 { 02998 02999 template< class T > 03000 class another_ptr 03001 : private shared_ptr<T> 03002 { 03003 private: 03004 typedef shared_ptr<T> base_type; 03005 03006 public: 03007 03008 explicit another_ptr(T * p = 0): base_type(p) 03009 { 03010 } 03011 03012 void reset() 03013 { 03014 base_type::reset(); 03015 } 03016 03017 T * get() const 03018 { 03019 return base_type::get(); 03020 } 03021 }; 03022 03023 class event_handler 03024 { 03025 public: 03026 03027 virtual ~event_handler() {} 03028 virtual void begin() = 0; 03029 virtual void handle(int event) = 0; 03030 virtual void end() = 0; 03031 }; 03032 03033 int begin_called = 0; 03034 int handle_called = 0; 03035 int end_called = 0; 03036 03037 class event_handler_impl 03038 : public event_handler 03039 { 03040 public: 03041 03042 virtual void begin() 03043 { 03044 ++begin_called; 03045 } 03046 03047 virtual void handle(int event) 03048 { 03049 handle_called = event; 03050 } 03051 03052 virtual void end() 03053 { 03054 ++end_called; 03055 } 03056 }; 03057 03058 another_ptr<event_handler> get_event_handler() 03059 { 03060 another_ptr<event_handler> p(new event_handler_impl); 03061 return p; 03062 } 03063 03064 shared_ptr<event_handler> current_handler; 03065 03066 void 03067 install_event_handler(shared_ptr<event_handler> p) 03068 { 03069 p->begin(); 03070 current_handler = p; 03071 } 03072 03073 void 03074 handle_event(int event) 03075 { 03076 current_handler->handle(event); 03077 } 03078 03079 void 03080 remove_event_handler() 03081 { 03082 current_handler->end(); 03083 current_handler.reset(); 03084 } 03085 03086 template< class P > 03087 class smart_pointer_deleter 03088 { 03089 private: 03090 P p_; 03091 03092 public: 03093 03094 smart_pointer_deleter(P const & p): p_(p) 03095 { 03096 } 03097 03098 void operator()(void const *) 03099 { 03100 p_.reset(); 03101 } 03102 }; 03103 03104 void 03105 test() 03106 { 03107 another_ptr<event_handler> p = get_event_handler(); 03108 03109 shared_ptr<event_handler> q(p.get(), smart_pointer_deleter< another_ptr<event_handler> >(p)); 03110 03111 p.reset(); 03112 03113 assert(begin_called == 0); 03114 03115 install_event_handler(q); 03116 03117 assert(begin_called == 1); 03118 03119 assert(handle_called == 0); 03120 03121 handle_event(17041); 03122 03123 assert(handle_called == 17041); 03124 03125 assert(end_called == 0); 03126 03127 remove_event_handler(); 03128 03129 assert(end_called == 1); 03130 } 03131 03132 } // namespace n_spt_another_sp 03133 03134 #if 0 03135 namespace n_spt_shared_from_this 03136 { 03137 03138 class X 03139 { 03140 public: 03141 03142 virtual void f() = 0; 03143 03144 protected: 03145 03146 ~X() {} 03147 }; 03148 03149 class Y 03150 { 03151 public: 03152 03153 virtual shared_ptr<X> getX() = 0; 03154 03155 protected: 03156 03157 ~Y() {} 03158 }; 03159 03160 class impl 03161 : public X, public Y 03162 { 03163 private: 03164 weak_ptr<impl> weak_this; 03165 03166 impl(impl const &); 03167 impl & operator=(impl const &); 03168 03169 impl() {} 03170 03171 public: 03172 03173 static shared_ptr<impl> create() 03174 { 03175 shared_ptr<impl> pi(new impl); 03176 pi->weak_this = pi; 03177 return pi; 03178 } 03179 03180 virtual void f() {} 03181 03182 virtual shared_ptr<X> getX() 03183 { 03184 shared_ptr<X> px = weak_this.lock(); 03185 return px; 03186 } 03187 }; 03188 03189 void 03190 test() 03191 { 03192 shared_ptr<Y> py = impl::create(); 03193 assert(py.get() != 0); 03194 assert(py.use_count() == 1); 03195 03196 shared_ptr<X> px = py->getX(); 03197 assert(px.get() != 0); 03198 assert(py.use_count() == 2); 03199 03200 shared_ptr<Y> py2 = dynamic_pointer_cast<Y>(px); 03201 assert(py.get() == py2.get()); 03202 assert(!(py < py2 || py2 < py)); 03203 assert(py.use_count() == 3); 03204 } 03205 03206 } // namespace n_spt_shared_from_this 03207 #endif // 0 03208 03209 namespace n_spt_wrap 03210 { 03211 03212 void 03213 test() 03214 { 03215 } 03216 03217 } // namespace n_spt_wrap 03218 03219 int main() 03220 { 03221 n_element_type::test(); 03222 n_constructors::test(); 03223 n_assignment::test(); 03224 n_reset::test(); 03225 n_access::test(); 03226 n_use_count::test(); 03227 n_swap::test(); 03228 n_comparison::test(); 03229 n_static_cast::test(); 03230 n_const_cast::test(); 03231 n_dynamic_cast::test(); 03232 03233 n_map::test(); 03234 03235 n_transitive::test(); 03236 #if 0 03237 n_report_1::test(); 03238 #endif // 0 03239 n_report_2::test(); 03240 03241 n_spt_incomplete::test(); 03242 n_spt_pimpl::test(); 03243 n_spt_abstract::test(); 03244 n_spt_preventing_delete::test(); 03245 n_spt_array::test(); 03246 n_spt_static::test(); 03247 n_spt_intrusive::test(); 03248 n_spt_another_sp::test(); 03249 //n_spt_shared_from_this::test(); 03250 n_spt_wrap::test(); 03251 03252 return 0; 03253 } 03254 03255 namespace n_spt_incomplete 03256 { 03257 03258 class file 03259 { 03260 public: 03261 03262 file(): fread_called(false) 03263 { 03264 ++file_instances; 03265 } 03266 03267 ~file() 03268 { 03269 assert(fread_called); 03270 --file_instances; 03271 } 03272 03273 bool fread_called; 03274 }; 03275 03276 shared_ptr<file> fopen(char const *, char const *) 03277 { 03278 shared_ptr<file> pf(new file); 03279 return pf; 03280 } 03281 03282 void 03283 fread(shared_ptr<file> pf, void *, long) 03284 { 03285 pf->fread_called = true; 03286 } 03287 03288 } // namespace n_spt_incomplete 03289 03290 namespace n_spt_pimpl 03291 { 03292 03293 class file::impl 03294 { 03295 private: 03296 impl(impl const &); 03297 impl & operator=(impl const &); 03298 03299 long total_size_; 03300 03301 public: 03302 03303 impl(char const *, char const *): total_size_(0) 03304 { 03305 ++file_instances; 03306 } 03307 03308 ~impl() 03309 { 03310 --file_instances; 03311 } 03312 03313 void read(void *, long size) 03314 { 03315 total_size_ += size; 03316 } 03317 03318 long total_size() const 03319 { 03320 return total_size_; 03321 } 03322 }; 03323 03324 file::file(char const * name, char const * mode): pimpl_(new impl(name, mode)) 03325 { 03326 } 03327 03328 void 03329 file::read(void * data, long size) 03330 { 03331 pimpl_->read(data, size); 03332 } 03333 03334 long file::total_size() const 03335 { 03336 return pimpl_->total_size(); 03337 } 03338 03339 } // namespace n_spt_pimpl 03340 03341 namespace n_spt_abstract 03342 { 03343 03344 class X_impl 03345 : public X 03346 { 03347 private: 03348 X_impl(X_impl const &); 03349 X_impl & operator=(X_impl const &); 03350 03351 int n_; 03352 03353 public: 03354 03355 X_impl(): n_(0) 03356 { 03357 ++X_instances; 03358 } 03359 03360 virtual ~X_impl() 03361 { 03362 --X_instances; 03363 } 03364 03365 virtual void f(int n) 03366 { 03367 n_ += n; 03368 } 03369 03370 virtual int g() 03371 { 03372 return n_; 03373 } 03374 }; 03375 03376 shared_ptr<X> createX() 03377 { 03378 shared_ptr<X> px(new X_impl); 03379 return px; 03380 } 03381 03382 } // namespace n_spt_abstract