/trunk/Examples/test-suite/d/li_boost_shared_ptr_runme.2.d
D | 602 lines | 471 code | 74 blank | 57 comment | 26 complexity | 1a0b36594b3a01d01454a515242b951b MD5 | raw file
1module li_boost_shared_ptr_runme; 2 3import core.memory; 4import core.thread; 5import std.conv; 6import std.exception; 7import std.stdio; 8import li_boost_shared_ptr.li_boost_shared_ptr; 9import li_boost_shared_ptr.Klass; 10import li_boost_shared_ptr.KlassDerived; 11import li_boost_shared_ptr.Klass3rdDerived; 12import li_boost_shared_ptr.MemberVariables; 13import li_boost_shared_ptr.PairIntDouble; 14 15// Debugging flag 16enum TRACE = false; 17 18void main() { 19 if (TRACE) 20 writeln("---> STARTED <---"); 21 22 debug_shared = TRACE; 23 24 // Change loop count to run for a long time to monitor memory 25 enum LOOP_COUNT = 1; // 50000; 26 for (int i = 0; i < LOOP_COUNT; ++i) { 27 runTest(); 28 GC.collect(); 29 } 30 31 if (TRACE) 32 writeln("---> NEARLY FINISHED <---"); 33 34 // Try to get the GC to collect everything not referenced anymore. 35 int countdown = 100; 36 while (--countdown) { 37 GC.collect(); 38 if (Klass.getTotal_count() == 1) 39 break; 40 Thread.sleep(100); 41 } 42 43 // A single remaining instance expected: the global variable (GlobalValue). 44 if (Klass.getTotal_count() != 1) 45 throw new Exception("Klass.total_count=" ~ to!string(Klass.getTotal_count())); 46 47 // A single remaining instance expected: the global variable (GlobalSmartValue). 48 int wrapper_count = shared_ptr_wrapper_count(); 49 if (wrapper_count != NOT_COUNTING) 50 if (wrapper_count != 1) 51 throw new Exception("shared_ptr wrapper count=" ~ to!string(wrapper_count)); 52 53 if (TRACE) 54 writeln("---> FINISHED <---"); 55} 56 57void runTest() { 58 // simple shared_ptr usage - created in C++ 59 { 60 auto k = new Klass("me oh my"); 61 string val = k.getValue(); 62 verifyValue("me oh my", val); 63 verifyCount(1, k); 64 } 65 66 // simple shared_ptr usage - not created in C++ 67 { 68 auto k = factorycreate(); 69 string val = k.getValue(); 70 verifyValue("factorycreate", val); 71 verifyCount(1, k); 72 } 73 74 // pass by shared_ptr 75 { 76 auto k = new Klass("me oh my"); 77 auto kret = smartpointertest(k); 78 string val = kret.getValue(); 79 verifyValue("me oh my smartpointertest", val); 80 verifyCount(2, k); 81 verifyCount(2, kret); 82 } 83 84 // pass by shared_ptr pointer 85 { 86 auto k = new Klass("me oh my"); 87 auto kret = smartpointerpointertest(k); 88 string val = kret.getValue(); 89 verifyValue("me oh my smartpointerpointertest", val); 90 verifyCount(2, k); 91 verifyCount(2, kret); 92 } 93 94 // pass by shared_ptr reference 95 { 96 auto k = new Klass("me oh my"); 97 auto kret = smartpointerreftest(k); 98 string val = kret.getValue(); 99 verifyValue("me oh my smartpointerreftest", val); 100 verifyCount(2, k); 101 verifyCount(2, kret); 102 } 103 104 // pass by shared_ptr pointer reference 105 { 106 auto k = new Klass("me oh my"); 107 auto kret = smartpointerpointerreftest(k); 108 string val = kret.getValue(); 109 verifyValue("me oh my smartpointerpointerreftest", val); 110 verifyCount(2, k); 111 verifyCount(2, kret); 112 } 113 114 // const pass by shared_ptr 115 { 116 auto k = new Klass("me oh my"); 117 auto kret = constsmartpointertest(k); 118 string val = kret.getValue(); 119 verifyValue("me oh my", val); 120 verifyCount(2, k); 121 verifyCount(2, kret); 122 } 123 124 // const pass by shared_ptr pointer 125 { 126 auto k = new Klass("me oh my"); 127 auto kret = constsmartpointerpointertest(k); 128 string val = kret.getValue(); 129 verifyValue("me oh my", val); 130 verifyCount(2, k); 131 verifyCount(2, kret); 132 } 133 134 // const pass by shared_ptr reference 135 { 136 auto k = new Klass("me oh my"); 137 auto kret = constsmartpointerreftest(k); 138 string val = kret.getValue(); 139 verifyValue("me oh my", val); 140 verifyCount(2, k); 141 verifyCount(2, kret); 142 } 143 144 // pass by value 145 { 146 auto k = new Klass("me oh my"); 147 auto kret = valuetest(k); 148 string val = kret.getValue(); 149 verifyValue("me oh my valuetest", val); 150 verifyCount(1, k); 151 verifyCount(1, kret); 152 } 153 154 // pass by pointer 155 { 156 auto k = new Klass("me oh my"); 157 auto kret = pointertest(k); 158 string val = kret.getValue(); 159 verifyValue("me oh my pointertest", val); 160 verifyCount(1, k); 161 verifyCount(1, kret); 162 } 163 164 // pass by reference 165 { 166 auto k = new Klass("me oh my"); 167 auto kret = reftest(k); 168 string val = kret.getValue(); 169 verifyValue("me oh my reftest", val); 170 verifyCount(1, k); 171 verifyCount(1, kret); 172 } 173 174 // pass by pointer reference 175 { 176 auto k = new Klass("me oh my"); 177 auto kret = pointerreftest(k); 178 string val = kret.getValue(); 179 verifyValue("me oh my pointerreftest", val); 180 verifyCount(1, k); 181 verifyCount(1, kret); 182 } 183 184 // null tests 185 { 186 Klass k = null; 187 188 // TODO: add in const versions too 189 enforce(smartpointertest(k) is null, "return was not null"); 190 enforce(smartpointerpointertest(k) is null, "return was not null"); 191 enforce(smartpointerreftest(k) is null, "return was not null"); 192 enforce(smartpointerpointerreftest(k) is null, "return was not null"); 193 enforce(nullsmartpointerpointertest(null) == "null pointer", 194 "not null smartpointer pointer"); 195 196 enforceThrows( (){ valuetest(k); }, "Failed to catch null pointer"); 197 enforce(pointertest(k) is null, "return was not null"); 198 enforceThrows( (){ reftest(k); }, "Failed to catch null pointer"); 199 } 200 201 // $owner 202 { 203 auto k = pointerownertest(); 204 string val = k.getValue(); 205 verifyValue("pointerownertest", val); 206 verifyCount(1, k); 207 } 208 { 209 auto k = smartpointerpointerownertest(); 210 string val = k.getValue(); 211 verifyValue("smartpointerpointerownertest", val); 212 verifyCount(1, k); 213 } 214 215 ////////////////////////////////// Derived classes //////////////////////////////////////// 216 // derived pass by shared_ptr 217 { 218 auto k = new KlassDerived("me oh my"); 219 auto kret = derivedsmartptrtest(k); 220 string val = kret.getValue(); 221 verifyValue("me oh my derivedsmartptrtest-Derived", val); 222 verifyCount(4, k); // includes two extra references for upcasts in the proxy classes 223 verifyCount(4, kret); 224 } 225 // derived pass by shared_ptr pointer 226 { 227 auto k = new KlassDerived("me oh my"); 228 auto kret = derivedsmartptrpointertest(k); 229 string val = kret.getValue(); 230 verifyValue("me oh my derivedsmartptrpointertest-Derived", val); 231 verifyCount(4, k); // includes two extra references for upcasts in the proxy classes 232 verifyCount(4, kret); 233 } 234 // derived pass by shared_ptr ref 235 { 236 auto k = new KlassDerived("me oh my"); 237 auto kret = derivedsmartptrreftest(k); 238 string val = kret.getValue(); 239 verifyValue("me oh my derivedsmartptrreftest-Derived", val); 240 verifyCount(4, k); // includes two extra references for upcasts in the proxy classes 241 verifyCount(4, kret); 242 } 243 // derived pass by shared_ptr pointer ref 244 { 245 auto k = new KlassDerived("me oh my"); 246 auto kret = derivedsmartptrpointerreftest(k); 247 string val = kret.getValue(); 248 verifyValue("me oh my derivedsmartptrpointerreftest-Derived", val); 249 verifyCount(4, k); // includes two extra references for upcasts in the proxy classes 250 verifyCount(4, kret); 251 } 252 // derived pass by pointer 253 { 254 auto k = new KlassDerived("me oh my"); 255 auto kret = derivedpointertest(k); 256 string val = kret.getValue(); 257 verifyValue("me oh my derivedpointertest-Derived", val); 258 verifyCount(2, k); // includes an extra reference for the upcast in the proxy class 259 verifyCount(2, kret); 260 } 261 // derived pass by ref 262 { 263 auto k = new KlassDerived("me oh my"); 264 auto kret = derivedreftest(k); 265 string val = kret.getValue(); 266 verifyValue("me oh my derivedreftest-Derived", val); 267 verifyCount(2, k); // includes an extra reference for the upcast in the proxy class 268 verifyCount(2, kret); 269 } 270 271 ////////////////////////////////// Derived and base class mixed //////////////////////////////////////// 272 // pass by shared_ptr (mixed) 273 { 274 auto k = new KlassDerived("me oh my"); 275 auto kret = smartpointertest(k); 276 string val = kret.getValue(); 277 verifyValue("me oh my smartpointertest-Derived", val); 278 verifyCount(3, k); // an extra reference for the upcast in the proxy class 279 verifyCount(3, kret); 280 } 281 282 // pass by shared_ptr pointer (mixed) 283 { 284 auto k = new KlassDerived("me oh my"); 285 auto kret = smartpointerpointertest(k); 286 string val = kret.getValue(); 287 verifyValue("me oh my smartpointerpointertest-Derived", val); 288 verifyCount(3, k); // an extra reference for the upcast in the proxy class 289 verifyCount(3, kret); 290 } 291 292 // pass by shared_ptr reference (mixed) 293 { 294 auto k = new KlassDerived("me oh my"); 295 auto kret = smartpointerreftest(k); 296 string val = kret.getValue(); 297 verifyValue("me oh my smartpointerreftest-Derived", val); 298 verifyCount(3, k); // an extra reference for the upcast in the proxy class 299 verifyCount(3, kret); 300 } 301 302 // pass by shared_ptr pointer reference (mixed) 303 { 304 auto k = new KlassDerived("me oh my"); 305 auto kret = smartpointerpointerreftest(k); 306 string val = kret.getValue(); 307 verifyValue("me oh my smartpointerpointerreftest-Derived", val); 308 verifyCount(3, k); // an extra reference for the upcast in the proxy class 309 verifyCount(3, kret); 310 } 311 312 // pass by value (mixed) 313 { 314 auto k = new KlassDerived("me oh my"); 315 auto kret = valuetest(k); 316 string val = kret.getValue(); 317 verifyValue("me oh my valuetest", val); // note slicing 318 verifyCount(2, k); // an extra reference for the upcast in the proxy class 319 verifyCount(1, kret); 320 } 321 322 // pass by pointer (mixed) 323 { 324 auto k = new KlassDerived("me oh my"); 325 auto kret = pointertest(k); 326 string val = kret.getValue(); 327 verifyValue("me oh my pointertest-Derived", val); 328 verifyCount(2, k); // an extra reference for the upcast in the proxy class 329 verifyCount(1, kret); 330 } 331 332 // pass by ref (mixed) 333 { 334 auto k = new KlassDerived("me oh my"); 335 auto kret = reftest(k); 336 string val = kret.getValue(); 337 verifyValue("me oh my reftest-Derived", val); 338 verifyCount(2, k); // an extra reference for the upcast in the proxy class 339 verifyCount(1, kret); 340 } 341 342 // 3rd derived class 343 { 344 auto k = new Klass3rdDerived("me oh my"); 345 string val = k.getValue(); 346 verifyValue("me oh my-3rdDerived", val); 347 verifyCount(3, k); // 3 classes in inheritance chain == 3 swigCPtr values 348 val = test3rdupcast(k); 349 verifyValue("me oh my-3rdDerived", val); 350 verifyCount(3, k); 351 } 352 353 ////////////////////////////////// Member variables //////////////////////////////////////// 354 // smart pointer by value 355 { 356 auto m = new MemberVariables(); 357 auto k = new Klass("smart member value"); 358 m.SmartMemberValue = k; 359 string val = k.getValue(); 360 verifyValue("smart member value", val); 361 verifyCount(2, k); 362 363 auto kmember = m.SmartMemberValue; 364 val = kmember.getValue(); 365 verifyValue("smart member value", val); 366 verifyCount(3, kmember); 367 verifyCount(3, k); 368 369 delete m; 370 371 verifyCount(2, kmember); 372 verifyCount(2, k); 373 } 374 // smart pointer by pointer 375 { 376 auto m = new MemberVariables(); 377 auto k = new Klass("smart member pointer"); 378 m.SmartMemberPointer = k; 379 string val = k.getValue(); 380 verifyValue("smart member pointer", val); 381 verifyCount(1, k); 382 383 auto kmember = m.SmartMemberPointer; 384 val = kmember.getValue(); 385 verifyValue("smart member pointer", val); 386 verifyCount(2, kmember); 387 verifyCount(2, k); 388 389 delete m; 390 391 verifyCount(2, kmember); 392 verifyCount(2, k); 393 } 394 // smart pointer by reference 395 { 396 auto m = new MemberVariables(); 397 auto k = new Klass("smart member reference"); 398 m.SmartMemberReference = k; 399 string val = k.getValue(); 400 verifyValue("smart member reference", val); 401 verifyCount(2, k); 402 403 auto kmember = m.SmartMemberReference; 404 val = kmember.getValue(); 405 verifyValue("smart member reference", val); 406 verifyCount(3, kmember); 407 verifyCount(3, k); 408 409 // The C++ reference refers to SmartMemberValue... 410 auto kmemberVal = m.SmartMemberValue; 411 val = kmember.getValue(); 412 verifyValue("smart member reference", val); 413 verifyCount(4, kmemberVal); 414 verifyCount(4, kmember); 415 verifyCount(4, k); 416 417 delete m; 418 419 verifyCount(3, kmember); 420 verifyCount(3, k); 421 } 422 // plain by value 423 { 424 auto m = new MemberVariables(); 425 auto k = new Klass("plain member value"); 426 m.MemberValue = k; 427 string val = k.getValue(); 428 verifyValue("plain member value", val); 429 verifyCount(1, k); 430 431 auto kmember = m.MemberValue; 432 val = kmember.getValue(); 433 verifyValue("plain member value", val); 434 verifyCount(1, kmember); 435 verifyCount(1, k); 436 437 delete m; 438 439 verifyCount(1, kmember); 440 verifyCount(1, k); 441 } 442 // plain by pointer 443 { 444 auto m = new MemberVariables(); 445 auto k = new Klass("plain member pointer"); 446 m.MemberPointer = k; 447 string val = k.getValue(); 448 verifyValue("plain member pointer", val); 449 verifyCount(1, k); 450 451 auto kmember = m.MemberPointer; 452 val = kmember.getValue(); 453 verifyValue("plain member pointer", val); 454 verifyCount(1, kmember); 455 verifyCount(1, k); 456 457 delete m; 458 459 verifyCount(1, kmember); 460 verifyCount(1, k); 461 } 462 // plain by reference 463 { 464 auto m = new MemberVariables(); 465 auto k = new Klass("plain member reference"); 466 m.MemberReference = k; 467 string val = k.getValue(); 468 verifyValue("plain member reference", val); 469 verifyCount(1, k); 470 471 auto kmember = m.MemberReference; 472 val = kmember.getValue(); 473 verifyValue("plain member reference", val); 474 verifyCount(1, kmember); 475 verifyCount(1, k); 476 477 delete m; 478 479 verifyCount(1, kmember); 480 verifyCount(1, k); 481 } 482 483 // null member variables 484 { 485 auto m = new MemberVariables(); 486 487 // shared_ptr by value 488 auto k = m.SmartMemberValue; 489 if (k !is null) 490 throw new Exception("expected null"); 491 m.SmartMemberValue = null; 492 k = m.SmartMemberValue; 493 if (k !is null) 494 throw new Exception("expected null"); 495 verifyCount(0, k); 496 497 // plain by value 498 enforceThrows( (){ m.MemberValue = null; }, "Failed to catch null pointer"); 499 } 500 501 ////////////////////////////////// Global variables //////////////////////////////////////// 502 // smart pointer 503 { 504 auto kglobal = GlobalSmartValue; 505 enforce(kglobal is null, "expected null"); 506 507 auto k = new Klass("smart global value"); 508 GlobalSmartValue = k; 509 verifyCount(2, k); 510 511 kglobal = GlobalSmartValue; 512 string val = kglobal.getValue(); 513 verifyValue("smart global value", val); 514 verifyCount(3, kglobal); 515 verifyCount(3, k); 516 verifyValue("smart global value", GlobalSmartValue.getValue()); 517 GlobalSmartValue = null; 518 } 519 // plain value 520 { 521 Klass kglobal; 522 523 auto k = new Klass("global value"); 524 GlobalValue = k; 525 verifyCount(1, k); 526 527 kglobal = GlobalValue; 528 string val = kglobal.getValue(); 529 verifyValue("global value", val); 530 verifyCount(1, kglobal); 531 verifyCount(1, k); 532 verifyValue("global value", GlobalValue.getValue()); 533 534 enforceThrows((){ GlobalValue = null; }, "Failed to catch null pointer"); 535 } 536 // plain pointer 537 { 538 auto kglobal = GlobalPointer; 539 enforce(kglobal is null, "expected null"); 540 541 auto k = new Klass("global pointer"); 542 GlobalPointer = k; 543 verifyCount(1, k); 544 545 kglobal = GlobalPointer; 546 string val = kglobal.getValue(); 547 verifyValue("global pointer", val); 548 verifyCount(1, kglobal); 549 verifyCount(1, k); 550 GlobalPointer = null; 551 } 552 // plain reference 553 { 554 Klass kglobal; 555 556 auto k = new Klass("global reference"); 557 GlobalReference = k; 558 verifyCount(1, k); 559 560 kglobal = GlobalReference; 561 string val = kglobal.getValue(); 562 verifyValue("global reference", val); 563 verifyCount(1, kglobal); 564 verifyCount(1, k); 565 566 enforceThrows((){ GlobalReference = null; }, "Failed to catch null pointer"); 567 } 568 569 ////////////////////////////////// Templates //////////////////////////////////////// 570 { 571 auto pid = new PairIntDouble(10, 20.2); 572 enforce(pid.baseVal1 == 20 && pid.baseVal2== 40.4, "Base values wrong"); 573 enforce(pid.val1 == 10 && pid.val2 == 20.2, "Derived Values wrong"); 574 } 575} 576 577private void verifyValue(string expected, string got) { 578 if (expected != got) 579 throw new Exception("verify value failed. Expected: " ~ expected ~ " Got: " ~ got); 580} 581 582private void verifyCount(int expected, Klass k) { 583 // We deliberately call the use_count(Klass) overload also for objects which 584 // are instances of a subclass of Klass (due to static dispatch); things still 585 // have to work. 586 auto got = use_count(k); 587 if (expected != got) 588 throw new Exception("verify use_count failed. Expected: " ~ to!string(expected) ~ " Got: " ~ to!string(got)); 589} 590 591private void enforceThrows(void delegate() dg, string errorMessage) { 592 bool hasThrown; 593 try { 594 dg(); 595 } catch (Exception) { 596 hasThrown = true; 597 } finally { 598 if (!hasThrown) { 599 throw new Exception(errorMessage); 600 } 601 } 602}