Want more features on Pastebin? Sign Up, it's FREE!
Guest

refcount testsuite

By: a guest on Feb 18th, 2012  |  syntax: D  |  size: 7.78 KB  |  views: 112  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import std.stdio;
  2.  
  3. // keep track of all living objects
  4. bool[int*] s_living;
  5.  
  6. // canonical reference count dummy implementation
  7. struct Count {
  8.         int* count;
  9.         int magic = 0x2f7d9a65;
  10.        
  11.         this(bool){
  12.                 count = new int;
  13.                 *count = 1;
  14.                 assert(count !in s_living);
  15.                 s_living[count] = true;
  16.         }
  17.         this(this){
  18.                 if( count ){
  19.                         assert(magic == 0x2f7d9a65);
  20.                         assert(*count > 0);
  21.                         (*count)++;
  22.                 }
  23.         }
  24.         ~this(){
  25.                 assert(magic == 0x2f7d9a65);
  26.                 if( count ){
  27.                         assert(*count > 0);
  28.                         if( --(*count) == 0){
  29.                                 assert(count in s_living);
  30.                                 s_living.remove(count);
  31.                                 count = null;
  32.                         }
  33.                 }
  34.                 // reset just to catch uninitialized-errors better
  35.                 count = null;
  36.                 magic = 0;
  37.         }
  38. }
  39.  
  40. void test_con_ass()
  41. {
  42.         Count c;
  43.         { c = Count(true); }
  44.         assert(c.count && *c.count == 1);
  45.         { c = Count(); }
  46.         assert(c.count == null);
  47. }
  48.  
  49. void test_con_sae_ass()
  50. {
  51.         Count c[1];
  52.         { c[0] = Count(true); }
  53.         assert(*c[0].count == 1);
  54.         { c[0] = Count(); }
  55.         assert(c[0].count == null);
  56. }
  57.  
  58. void test_con_ae_ass1()
  59. {
  60.         Count c[] = new Count[1];
  61.         { c[0] = Count(true); }
  62.         assert(c[0].count && *c[0].count == 1);
  63.         { c[0] = Count(); }
  64.         assert(c[0].count == null);
  65. }
  66.  
  67. void test_con_ae_ass2()
  68. {
  69.         Count c[];
  70.         { c ~= Count(true); }
  71.         assert(c[0].count && *c[0].count == 1);
  72.         { c[0] = Count(); }
  73.         assert(c[0].count == null);
  74.         { c ~= Count(true); }
  75.         assert(c[0].count && *c[0].count == 1);
  76.         Count tmp = c[0];
  77.         assert(c[0].count && *c[0].count == 2);
  78.         { c.length = 0; }
  79.         assert(c[0].count && *c[0].count == 1);
  80.         tmp = Count();
  81.         assert(c[0].count == null);
  82. }
  83.  
  84. void test_con_aa_ass1() // DMD 6178?
  85. {
  86.         Count[int] c;
  87.         { auto cs = Count(true); c[0] = cs; }
  88.         assert(c[0].count && *c[0].count == 1);
  89.         { Count cs; c[0] = cs; }
  90.         assert(c[0].count == null);
  91. }
  92.  
  93. void test_con_aa_ass2() // DMD 6178?
  94. {
  95.         Count[int] c;
  96.         { c[0] = Count(true); }
  97.         assert(c[0].count && *c[0].count == 1);
  98.         { c[0] = Count(); }
  99.         assert(c[0].count == null);
  100. }
  101.  
  102. void test_con_sm_ass()
  103. {
  104.         struct S { Count c; }
  105.         S s;
  106.         { s.c = Count(true); }
  107.         assert(s.c.count && *s.c.count == 1);
  108.         { s.c = Count(); }
  109.         assert(s.c.count == null);
  110. }
  111.  
  112. void test_con_cm_ass()
  113. {
  114.         class S { Count c; }
  115.         S s = new S;
  116.         { s.c = Count(true); }
  117.         assert(s.c.count && *s.c.count == 1);
  118.         { s.c = Count(); }
  119.         assert(s.c.count == null);
  120. }
  121.  
  122. void test_con_delp()
  123. {
  124.         Count c;
  125.         void f(Count c_){ c = c_; }
  126.         { f(Count(true)); }
  127.         assert(c.count && *c.count == 1);
  128.         { f(Count()); }
  129.         assert(c.count == null);
  130. }
  131.  
  132. void test_con_refp()
  133. {
  134.         Count c;
  135.         static void f(ref Count cd, Count cs){ cd = cs; }
  136.         { f(c, Count(true)); }
  137.         assert(c.count && *c.count == 1);
  138.         { f(c, Count()); }
  139.         assert(c.count == null);
  140. }
  141.  
  142. void test_con_refp2()
  143. {
  144.         Count c;
  145.         static void f(ref Count cd, ref Count cs){ cd = cs; }
  146.         { auto cs = Count(true); f(c, cs); }
  147.         assert(c.count && *c.count == 1);
  148.         { Count cs; f(c, cs); }
  149.         assert(c.count == null);
  150. }
  151.  
  152. void test_con_ptrp()
  153. {
  154.         Count c;
  155.         static void f(Count* cd, Count cs){ *cd = cs; }
  156.         { f(&c, Count(true)); }
  157.         assert(c.count && *c.count == 1);
  158.         { f(&c, Count()); }
  159.         assert(c.count == null);
  160. }
  161.  
  162. void test_con_ptrp2()
  163. {
  164.         Count c;
  165.         static void f(Count* cd, Count* cs){ *cd = *cs; }
  166.         { auto cs = Count(true); f(&c, &cs); }
  167.         assert(c.count && *c.count == 1);
  168.         { Count cs; f(&c, &cs); }
  169.         assert(c.count == null);
  170. }
  171.  
  172. void test_con_outp()
  173. {
  174.         Count c;
  175.         static void f(out Count cd, Count cs){ cd = cs; }
  176.         { f(c, Count(true)); }
  177.         assert(c.count && *c.count == 1);
  178.         { f(c, Count()); }
  179.         assert(c.count == null);
  180. }
  181.  
  182. void test_con_ret()
  183. {
  184.         Count c;
  185.         static Count a(){ return Count(true); }
  186.         static Count b(){ return Count(); }
  187.         { c = a(); }
  188.         assert(c.count && *c.count == 1);
  189.         { c = b(); }
  190.         assert(c.count == null);
  191. }
  192.  
  193. void test_var_ret()
  194. {
  195.         Count c;
  196.         static Count a(bool x = true){
  197.                 static Count cs;
  198.                 if( x && cs.count == null ) cs = Count(true);
  199.                 else if( !x && cs.count != null ) cs = Count();
  200.                 return cs;
  201.         }
  202.         static Count b(){ return a(); }
  203.         { c = a(); }
  204.         assert(c.count && *c.count == 2);
  205.         { c = Count(); }
  206.         assert(c.count && *c.count == 1);
  207.         { c = b(); }
  208.         assert(c.count && *c.count == 2);
  209.         { c = Count(); }
  210.         assert(c.count && *c.count == 1);
  211.         a(false); // frees the static reference
  212. }
  213.  
  214. void test_sae_ret() // DMD
  215. {
  216.         Count c;
  217.         static Count a(bool x = true){
  218.                 static Count[1] cs;
  219.                 if( x && cs[0].count == null ) cs[0] = Count(true);
  220.                 else if( !x && cs[0].count != null ) cs[0] = Count();
  221.                 return cs[0];
  222.         }
  223.         { c = a(); }
  224.         assert(c.count && *c.count == 2);
  225.         { c = Count(); }
  226.         assert(c.count && *c.count == 1);
  227.         a(false); // frees the static reference
  228. }
  229.  
  230. void test_ae_ret()
  231. {
  232.         Count c;
  233.         static Count a(bool x = true){
  234.                 static Count[] cs;
  235.                 if( x && cs.length == 0 ) cs ~= Count(true);
  236.                 else if( !x && cs.length > 0 ) cs.length = 0;
  237.                 return cs[0];
  238.         }
  239.         { c = a(); }
  240.         assert(c.count && *c.count == 2);
  241.         { c = Count(); }
  242.         assert(c.count && *c.count == 1);
  243.         a(false); // frees the static reference
  244. }
  245.  
  246. void test_aae_ret()
  247. {
  248.         Count c;
  249.         static Count a(bool x = true){
  250.                 static Count[int] cs;
  251.                 if( x && 0 !in cs ) cs[0] = Count(true);
  252.                 else if( !x && 0 in cs ) cs.remove(0);
  253.                 return cs[0];
  254.         }
  255.         { c = a(); }
  256.         assert(c.count && *c.count == 2);
  257.         { c = Count(); }
  258.         assert(c.count && *c.count == 1);
  259.         a(false); // frees the static reference
  260. }
  261.  
  262. void test_sm_ret()
  263. {
  264.         Count c;
  265.         struct S { Count c; }
  266.         static Count a(bool x = true){
  267.                 static S cs;
  268.                 if( x && cs.c.count == null ) cs.c = Count(true);
  269.                 else if( !x && cs.c.count != null ) cs.c = Count();
  270.                 return cs.c;
  271.         }
  272.         { c = a(); }
  273.         assert(c.count && *c.count == 2);
  274.         { c = Count(); }
  275.         assert(c.count && *c.count == 1);
  276.         a(false); // frees the static reference
  277. }
  278.  
  279. void test_tern_ret() // DMD 7516
  280. {
  281.         Count c;
  282.         static Count a(bool x, bool y = true){
  283.                 static Count cs;
  284.                 if( y && cs.count == null ) cs = Count(true);
  285.                 else if( !y && cs.count != null ) cs = Count();
  286.                 return x ? cs : Count(0);
  287.         }
  288.         static Count b(bool x){ return x ? a(x) : Count(); }
  289.         { c = a(true); }
  290.         assert(c.count && *c.count == 2);
  291.         { c = a(false); }
  292.         assert(c.count && *c.count == 1);
  293.         { c = b(true); }
  294.         assert(c.count && *c.count == 2);
  295.         { c = b(false); }
  296.         assert(c.count && *c.count == 1);
  297.         a(false, false); // frees the static reference
  298. }
  299.  
  300. void test_str_ass()
  301. {
  302.         struct S { Count c; }
  303.         S s, t;
  304.         { s.c = Count(true); }
  305.         assert(s.c.count && *s.c.count == 1);
  306.         { t = s; }
  307.         assert(s.c.count && *s.c.count == 2);
  308.         assert(t.c.count && *t.c.count == 2);
  309.         { t.c = Count(); }
  310.         assert(s.c.count && *s.c.count == 1);
  311.         { s = t; }
  312.         assert(s.c.count == null);
  313.         assert(t.c.count == null);
  314. }
  315.  
  316. void test_str_sa_ass()
  317. {
  318.         struct S { Count[2] c; }
  319.         S s, t;
  320.         { s.c[0] = Count(true); }
  321.         assert(s.c[0].count && *s.c[0].count == 1);
  322.         { t = s; }
  323.         assert(s.c[0].count && *s.c[0].count == 2);
  324.         assert(t.c[0].count && *t.c[0].count == 2);
  325.         { t.c[0] = Count(); }
  326.         assert(s.c[0].count && *s.c[0].count == 1);
  327.         { s = t; }
  328.         assert(s.c[0].count == null);
  329.         assert(t.c[0].count == null);
  330. }
  331.  
  332. @property void test(alias F)()
  333. {
  334.         import std.stdio;
  335.         writef("Test %s: ", F.stringof);
  336.         version(BAILOUT){
  337.                 F();
  338.                 assert(s_living.length == 0);
  339.         } else {
  340.                 try {
  341.                         F();
  342.                         if( s_living.length > 0 ){
  343.                                 writeln("FAIL (leak)");
  344.                         } else writeln("OK");
  345.                         s_living = null;
  346.                 } catch(Throwable th){
  347.                         writeln("FAIL");
  348.                 }
  349.         }
  350. }
  351.  
  352. int main()
  353. {
  354.         test!test_con_ass;
  355.         test!test_con_sae_ass;
  356.         test!test_con_ae_ass1;
  357.         test!test_con_ae_ass2;
  358.         test!test_con_aa_ass1;
  359.         test!test_con_aa_ass2;
  360.         test!test_con_sm_ass;
  361.         test!test_con_cm_ass;
  362.         test!test_con_delp;
  363.         test!test_con_refp;
  364.         test!test_con_refp2;
  365.         test!test_con_ptrp;
  366.         test!test_con_ptrp2;
  367.         test!test_con_outp;
  368.         test!test_con_ret;
  369.         test!test_var_ret;
  370.         test!test_sae_ret;
  371.         test!test_aae_ret;
  372.         test!test_sm_ret;
  373.         test!test_tern_ret;
  374.         test!test_str_ass;
  375.         test!test_str_sa_ass;
  376.         return 1;
  377. }
clone this paste RAW Paste Data