PageRenderTime 74ms CodeModel.GetById 2ms app.highlight 67ms RepoModel.GetById 2ms app.codeStats 0ms

/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}